だいぶマニアックな情報ですが備忘メモとして書いておきます。
socket.io 1.0系の話です。0.9系は分かりません。
おそらく、普通のブラウザでsocket.io-clientを使う場合はクッキーは共通なので困らないと思いますが、node.jsからsocket.io-clientを使う場合はどうやるのでしょうか。
ところで、node.jsからsocket.io-clientを使いたい理由は、テストコードのためです。socket.io-clientはよくできていて、ブラウザでもnode.jsでも動くようです。
なぜ、クッキーを設定したいかというと、セッション維持のためです。サーバ側でなんらかの方法で認証して、セッションIDをクッキーに格納するというのはよくある方法だと思いますが、それをテストコードで動作確認したいわけです。
さて、本題です。socket.io-clientはengine.io-clientに依存していて、engine.io-clientはxmlhttpreuestやws (WebSocket)のライブラリに依存しています。socket.io-clientからそれらのライブラリにクッキーの情報を明示的に渡す手段は見つかりません。そもそも、テストコードを書くときくらいしか使わないのでしょう。
いろいろ調べた結果、engine.io-clientのv0.7.0からagentをオプションで渡せるようになっていました。socket.io-clientからengine.io-clientへはそっくりそのままオプションが引き継がれます。
agentというのは、httpのソケットを管理する仕組みなのですが、ちょっとそこを用途外利用することにしました。つまり、リクエストを登録しにきたところをフックして、クッキーのヘッダを追加してしまうのです。
コードはこんな感じです。
var http = require('http');
var socket_io_client = require('socket.io-client');
var cookie = 'aaa=123';
var myAgent = new http.Agent();
myAgent._addRequest = myAgent.addRequest;
myAgent.addRequest = function(req, host, port, localAddress) {
var old = req._headers.cookie;
req._headers.cookie = cookie + (old ? '; ' + old : '');
req._headerNames['cookie'] = 'Cookie';
return myAgent._addRequest(req, host, port, localAddress);
};
var client = socket_io_client('http://localhost:12345/', {
agent: myAgent
});
クッキードメインのチェックは省略されています。テストコード以外では使えないでしょう。また、将来的に仕様が変わったら使えなくなる可能性もあります。
コメント