17 February, 2018

HTTP Varyヘッダについて

HTTP Varyヘッダとはクライアントとサーバ間(以下 オリジンサーバ)にCDN等のキャッシュサーバへキャッシュの扱い方を指定するためのフィールド。

背景と問題

同じURLへのアクセスでもリクエストに含まれるAccept-Languageヘッダによって言語ごとに異なるレスポンスをサーバが返す場合、 キャッシュサーバがURLのみで 「キャッシュを利用するか」/「オリジンサーバへ問い合わせをするか」を判断してしまうと、 Accept-Languageヘッダで指定された言語にオリジンサーバが対応しているにもかかわらず、 キャッシュサーバが間違ったレスポンスを返してしまう可能性がある。これを解決するのがVaryフィールド。

Varyフィールド

VaryフィールドはRFC7231で定義されている。 以下の図はVaryフィールドを使った異なる言語に対するレスポンスの振り分けの例。
クライアントから3回リクエストが送信されていますが、Varyフィールドで言語ごとのレスポンスをキャッシュサーバへキャッシュしている。

vary-flow-diagram

  • > 1回目のリクエスト
    キャッシュサーバにキャッシュがない状態ですのでキャッシュサーバからオリジンサーバへ問い合わせが発生する。その際、オリジンサーバはVary: Accept-Languageをレスポンスに付加することで、キャッシュサーバはURLだけでなく、URL + Accept-Language: jaをキーとしてレスポンスをキャッシュする。
Content-Language: ja
Vary: Accept-Language
  • > 2回目のリクエスト
    キャッシュサーバにAccept-Language: jaのリクエストが来ましたが、すでにキャッシュに登録されているためキャッシュのレスポンスをクライアントへ返する。オリジンサーバへのリクエストは発生しません

  • > 3回目のリクエスト Accept-Language: enのリクエストが来ましたが、キャッシュサーバにはenのキャッシュはないので、オリジンサーバへ問い合わせ、帰ってきたレスポンスをenでキャッシュして、クライアントへ返する。

まとめ

言語によるレスポンス振り分けにおけるキャッシュサーバのキャッシュ制御についての例を確認しました。VaryフィールドはAccept-Languageだけでなく、他のフィールド指定や複数のフィールドをカンマで区切って指定することもできる。

Vary: Accept-Encoding, Accept-Language

なお、Varyヘッダではオリジンサーバの対応する形式などをキャッシュサーバへ伝えることができないので、それをできるようにする仕様HTTP Variantsというものも提案されている。

参考

author r-tamura
r-tamura
Web関連多めのソフトウェアエンジニアです。