Flashとフォワードプロキシ
寒すぎて風呂が常に恋しくなる@masudaKです。 FLASHで作られたサービスに長く携わっていることもあり、ちょっとハマったので、残しておきます。 やりたいことは、FLASHで作られたゲームをフォワードプロキシ経由で表示させること。
要は、こんな感じ。
自分のPC - フォワードプロキシ - リアルサーバ(apache, socket)
単にWebサーバにつなぎに行くだけなら難しくありません。
Squid立てて、以下の様な感じの記述をしておけば、最低限動くでしょう。
acl Safe_ports port 80 # http http_access deny !Safe_ports
あとはACLの設定すればいけるかと。
しなしながら、FLASH Playerを経由したRTMP通信をプロキシ経由にさせようとすると、以下の様な方法ではうまくいきません。
acl Safe_ports port 80 # http acl Safe_ports port 843 # crossdomain acl Safe_ports port 1935 # rtmp http_access deny !Safe_ports
これではダメなのです。では、どうダメなのか。
Config
まず、Safe_portsだけではだめ。
acl SSL_ports port 1935
のようにSSL_portsとしても扱ってあげる。要はSafe_portsとSSL_ports両方が必要になります。
通信
加えて、ブラウザでプロキシの設定をしても、SWFはプロキシを介してくれません。 これは仕様らしく、wiresharkとかでパケットみないと分からないかも。
要は直接サーバとソケット通信しようとしてしまうのです。 そのため、プロキシを介すように魔改造をしなければならない。
そこで見つけた以下の記事。 要はRFC準拠した形でソケット通信する部分のクラス(flash.net.Socket class)を書き換えればいけるでしょうと。
これが提案されているクラス。
んで、これを反映したswfを使って (デベロッパーの方ありがとうございます> <)、通信させると、プロキシは通ってくれる。
クロスドメイン
しかしながら、デベロッパーツールとかで見ると、以下の様なエラーが見られる。
Delegate::onError, [SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048"] RootModel::showError, 通信エラーが発生しました。
セキュリティエラーが発生してしまいました。なぜなのか。
どうもローカルに落としたSWFは、別ドメインとしてのプロキシサーバにアクセスしにいきます。 ただし、プロキシサーバはそれに答えられない。 そのため、crossdomainの部分でセキュリティ上エラーを吐いてしまいます。
なので、crossdomain.xmlを返せるようにします。
Apacheでさくっとやるなら、
# wget http://www.beamartyr.net/projects/mod_adobe_crossdomainpolicy.c # ./apxs -c -i mod_adobe_crossdomainpolicy.c // modules/mod_adobe_crossdomainpolicy.so ができあがるので、conf/extra/httpd-crossdomain.confを作る # vim conf/extra/httpd-crossdomain.conf // 以下を記入 LoadModule adobe_crossdomainpolicy_module modules/mod_adobe_crossdomainpolicy.so Listen 843 <VirtualHost 0.0.0.0:843> AdobePolicyFileServerEnabled On AdobePolicyFile [crossdomain.xmlの絶対パス書く] </VirtualHost> // crossdomain.xmlにはこんな感じで書いておく <cross-domain-policy><allow-access-from domain='*.test.com' to-ports='*'/></cross-domain-policy>
あとはapache再起動して、以下で確認。crossdomain.xmlの中身が返ってきたら、OK。
perl -e 'printf "<policy-file-request/>%c",0' | nc 127.0.0.1 843
ここまでできたらSqiud再起動して、FLASHがプロキシ経由できるか見てみましょう。
終わりに
なんか色々ハマるところが多かったので、苦戦しました。 ソケット通信部分のクラスを改造したりしなきゃなので、あまりスマートな解決とは言えないかもしれません。
他にもっといい方法があるかもしれませんが、とりあえず。 間違い等あれば@masudaKまでお願いします。