Apache mod_spdy の X-Associated-Content で Server Push
intro
SPDY の Server Push については以前にも書きましたのでそちらをご参照下さい。
SPDY と WebSocket の基礎と SPDY の Push - Block Rockin’ Codes
上記記事ではサンプルの実装に node-spdy を用いましたが、更なる検証のために他の実装を調べました。
主な SPDY 実装で、 Server Push を実装しているサーバは、把握してる範囲では以下のような状況です。
今回は Server Push の検証のために、 Apache mod_spdy でこの機能を有効にする方法を調べました。
Apache mod_spdy
名前の通り、 Apache HTTP Server を SPDY 対応させるためのモジュールです。
mod-spdy - Apache SPDY module - Google Project Hosting
mod_spdy 自体のインストールはこちらを参照下さい。
Apache mod_spdy のインストール - Qiita [キータ]
そして、 mod_spdy で Server Push を行う方法は、基本的には本家の wiki である下記に書かれているんですが、具体的な方法の情報が少なかったので書いておきます。
https://code.google.com/p/mod-spdy/wiki/OptimizingForSpdy#Using_SPDY_server_push
X-Associated-Content
Server Push するリソースは X-Associated-Content というヘッダで指定します。
ヘッダのフォーマットは以下のようなものです。
X-Associated-Content: "https://www.example.com/styles/foo.css", "/scripts/bar.js?q=4":2, "https://www.example.com/images/baz.png": 5, "https://www.example.com/generate_image.php?w=32&h=24"
mod_spdy は、この X-Associated-Content ヘッダを見つけると、そこに指定されたリソースをクライアントに push します。
フォーマットルールは以下です。
注意点は以下です。
- X-Associated-Content ヘッダは mod_spdy で処理されると削除される(クライアントには届かない)
- priority が指定されなかった場合は、現実的かつ最小の値が自動で付与される(実装依存)
- priority は値が小さい方が優先順位が高い
以上より、 mod_spdy が処理する前のどこかの処理で、レスポンスヘッダに X-Associated-Content ヘッダを付与してあげれば、mod_spdy が push を行ってくれます。
方法としては CGI などでプログラムで行うか、 mod_headers を用いることで実現できます。
mod_headers
Apache のモジュールだけで完結し、デフォルトで入ってることから mod_headers を用いる方法が一番手軽です。
mod_headers はそのなの通りヘッダを制御するモジュールで、設定ファイルのほとんど全ての場所で、のヘッダを操作できます。
では、 /spdy/test/push.html に、 /jquery.js と /bootstarp.css を push する設定を作成してみます。
<Directory /spdy/test> Options Indexes allow from all <Files push.html> Header append x-associated-content "\"/jquery.js\", \"/bootstrap.css\"" </Files> </Directory>
ダブルクオートのエスケープに気をつければそのまま書くだけです。
成功したら、 Chrome などで jquery.js と bootstrap.css が Cache から読み込まれていることを確認して下さい。
Rails
とにかく mod_spdy に渡る前に X-Associated-Content ヘッダが付与できれば良いので、プログラムを介す場合はそのプログラムから API 経由でレスポンスをいじれば同様のことができます。
Rails を Apache で走らせている場合は以下のような感じ。(参考)
class SPDYController < ApplicationController def server_push response.headers["X-Associated-Content"] = '"/assets/jquery.js", "/assets/bootstrap.css"' end end
CGI なども同様です。
outro
SPDY 単体でもそうですが、 Server Push も含めるとサイトの最適化に対する選択肢が増えます。
特に「ハイパフォーマンス Web サイト」に書かれているような手法のいくつかは、SPDY によって見直す余地が出てくる可能性があります。
現在その辺を少し検証しているので、まとめたらまた書きたいと思います。