Chrome to Phone

そもそもChrome to Phoneが使いたくてブラウザを移行したのだが、実際に使って見ると非常に便利で重宝している。特に、私の仕事場のようにネットワーク運用ポリシが厳しくGETは出来てもPOST一切禁止の場合、現在選択しているテキストを登録したプッシュ先のAndroid機のクリップボードにコピーできたりするのは超絶便利である。(他に現在Chromeで開いているページのURLを通知することもできる)

便利な機能を使い倒したら、次はどのように実現しているかが知りたくなるのが職業病だが、同機能を実行した際のWWWのログをFiddlerで採取してみた。

CONNECT chrometophone.appspot.com:443 HTTP/1.1
Host: chrometophone.appspot.com
Proxy-Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.41 Safari/534.7

The data sent represents an SSLv3-compatible ClientHello handshake. For your convenience, the data is extracted below.
:

HTTP CONNECTを使用している。恐らくはChrome Extension APIによる接続(connect)の結果だろう。URLを見れば解るが、これはGoogle App Engine上のサービスだ。

ヘッダを見れば解るが、ボディはSSLで暗号化されている(省略している)。CONNECT は、SSL 等のプロトコルで暗号化されたものをトンネルさせるために使うメソッドであり、プロクシがトンネルを確立すると、その後のリクエストに関しては一切関知しない。通信は完全にクローズドである。

いろいろ妄想するのは楽しいが、本拡張はきちんとソースコードが公開されているgoogle codeのプロジェクトなので、四の五の言わずにそちらを見たほうが早い。

いきなり核心。chrometophoneサービス、appengine側のソースコードを読んでみよう。

C2DMessaging push = C2DMessaging.get(getServletContext());

〜
boolean res = push.sendNoRetry(deviceInfo.getDeviceRegistrationID(),
        collapseKey,
        "url", url,
        "title", title,
        "sel", sel,
        "debug", deviceInfo.getDebug() ? "1" : null);

やはり(というか当たり前だが)C2DM(Cloud to Device Messaging)を使っているのだということが解る。

このパッケージのソースコードツリーは以上のJavaクラスから構成されており、これを見ればchrometophoneのサーバ側の処理が解る。

1. 認証 (AuthServlet)
2. デバイス情報の登録 (DeviceInfo, RegisterServlet)
3. データの送信 (SendServlet)
4. デバイスの登録解除 (UnregisterServlet)

C2DM以外、これらのたった5つのサーバサイドコードで構成されているのは全く持って驚きだ。