まず、サーバに接続してリクエストを投げます。クライアントからのリクエストはこんな感じです。今回はecho.websocket.orgに対してリクエストを投げています。
GET / HTTP/1.1 Host: echo.websocket.org Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: c6b8hTg4EeGb2gQMztV1/g== Origin: http://echo.websocket.org Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13
websocketのサーバに接続するとき、Sec-WebSocket-KeyとHost, Origin以外のヘッダーはほぼ固定ですね。Sec-WebSocket-Keyだけがリクエストごと変更されます。まあ、同じでも問題ないんだけど。
Sec-WebSocket-Keyはuuidの16bitのバイト列をbase64エンコードしたもの、っていうことになっています。でも、サーバの実装は長さのチェックとかしていなさそうなので、何でもいいかも。
このリクエストに対してサーバは、
HTTP/1.1 101 Web Socket Protocol Handshake Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: Kxep+hNu9n51529fGidYu7a3wO0= Server: Kaazing Gateway Date: Fri, 06 Jan 2012 07:39:19 GMT
となります。echo.websocket.orgってKaazing Gateway使っているんですね。で、Sec-WebSocket-Acceptでちゃんとしたサーバかをチェックしていますが、以前にも書きましたが、これで何がセキュアになるのか、さっぱり分かりません。
Sec-WebSocket-Acceptは、Sec-WebSocket-Keyで送った文字列に258EAFA5-E914-47DA-95CA-C5AB0DC85B11をconcatして、shaでdigestしたもののbase64エンコードした値です。えっ?何言ってんだって?コードだと
s = sec_websocket_key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" digest = sha.sha(s).digest() print base64.encodestring(digest).lower()
と言うことです。これでサーバからのレスポンスのSec-WebSocket-Acceptと、クライアントで計算した値が同じであればハンドシェークは成功です。まあ、厳密いえばUpgradeヘッダーとかその辺の値のバリデーションも必要なんですが・・・。
でも、大昔よりは幾分シンプルになりましたね。
次回は実際のデータ転送について。
0 コメント:
コメントを投稿