2008年01月15日
Flash | URLLoader
AS3であるWebサービスを使用するライブラリを作ろうとしていたところ、いくつか引っかかったポイントがあった。
まず標準APIのURLLoader。そのWebサービスはWSSE認証が必要だったために、HTTPのリクエストヘッダに任意の値をセットできる必要があった。幸いURLLoaderに渡すURLRequestクラスのAPIドキュメントを見ると、requestHeadersプロパティが用意されている。
WSSEヘッダの値の生成は、corelibのWSSEUsernameTokenクラスを使えばOKなので、これでWSSEの認証部分はOKだなと思ったら、ここに第一の罠が。
URLLoaderでリクエストヘッダを付けたリクエストを送っても、そのヘッダが付いていない。検索してみると「URLRequestHeader#requestHeadersが反映されない」というFxUGの投稿が見つかった。同じ症状。
結論から書くと、FxUGで書かれているようなcrossdomain.xmlが云々という問題ではなく、GETリクエストでは任意のリクエストヘッダが付与されないということが分かった。同じリクエストのmethodをPOSTにして適当にPOSTデータを付けてURLLOaderから送信してみるとWSSEヘッダはちゃんと付いていた。おそらくFlash Playerの問題。仕様なのかバグなのかは分からないけど。
じゃあ、GETリクエストで任意のリクエストヘッダが付けられるURLLoaderをSocket使って自作するしかないのかと思っていたところ、次の記事を見つけた。
HTTP Authentication for HTTP/GET requests using ActionScript 3上と同じことが書いてあります。で、この人はHTTPURLLoaderクラスというURLLoaderではできない機能を持つものを作って公開してくれてます。基本的なインターフェースはURLLoaderと同じなので、クラス名をHTTPURLLoaderに差し替えるだけで使える。I was not able to set the header of a HTTP/GET request. Macromedia Flash Player allows you set the header only for POST requests.
このお陰でGETリクエストでもWSSEヘッダを付けられるようになりました。
WSSE認証ができたら、次はPOSTメソッドでXMLデータを送受信する機能の実装。POSTリクエストなら標準のURLLoaderで問題ないなと思ったら、ここにもまた罠が。
何が悪いのか分からなかったのだけど、何度やってもレスポンスのXMLが受け取れない。COMPLETEイベントを受け取る前に、「Error #2032: ストリームエラー」で中断されてしまう。Proxyソフトで正しいXMLレスポンスが返ってきているところまでは確認できているのだが。
URLLoaderは使わずにHTTPURLLoaderクラスを使うかと思って、試してみたところHTTPURLLoaderクラスはPOSTメソッドに対応していなかった。あちらを立てればこちらが立たず。なかなかうまくはいきません。
HTTPURLLoaderに手を入れてPOSTに対応させるかとごちゃごちゃいじってたんだけど思い通りにいかず、最終的に行き着いたのがas3httpclientのSocketURLLoader。HTTPURLLoaderと同じ人が作ってます。もっと早くに気付いていれば。。
このSocketURLLoaderクラスを使うと、POST結果のXMLレスポンスもちゃんと受け取れるようになって、万事解決。前にも書いたHTTPステータスも受け取れるみたい。すばらしい。