TwistedのエンドポイントがTCP接続を実行します。プロキシをネゴシエートするよう設定されたWebSocketファクトリでも、中間者へ接続するにはそのエンドポイントが必要です。

標準のヘルパーを使っている既存のAutobahnアプリケーションの場合:

from autobahn.twisted.websocket import WebSocketClientFactory, connectWS
from twisted.internet import ssl

factory = WebSocketClientFactory(
    'wss://events.example/channel',
    proxy={'host': 'proxy.example', 'port': 8080},
)
factory.protocol = ApplicationProtocol
connector = connectWS(
    factory,
    contextFactory=ssl.optionsForClientTLS('events.example'),
    timeout=10,
)

ApplicationProtocolはアプリケーションの既存のWebSocketプロトコルクラスです。リアクターと接続の後始末はそのアプリケーションのライフサイクルに保ちます。公開された中間者を経由して許可される公開WSSサービスでは、HTTPプロキシ一覧がファクトリのプロキシホストとポートの候補を提供します。

プロキシ用に設定されたファクトリでは、connectWSがTCPをプロキシへ接続し、後段の安全な接続のために宛先のTLSコンテキストを保持します。通常のHTTPプロキシ接続を最初から宛先TLSで包むわけではありません。

独自のHostnameEndpointとClientServiceの構成でも同じ分担を保つ必要があります。まずプロキシへ接続し、次に設定済みファクトリに宛先をネゴシエートさせ、必要なTLSを確立させます。ファクトリがプロキシとの会話を期待しているのに、エンドポイントを直接events.exampleへ接続すると、これらの役割が混ざります。

WebSocketのURLは実際のサービス宛先のままです。そのホスト名はTLSの識別情報にもなります。プロキシのホスト名に置き換えても、意図した安全なサービスは構成されません。

関連記事