2011-06-27 9 views
12

4つのユースケースに対して送信する最も良いHTTPヘッダーを理解しようとしています。私は、ユーザーエージェント/プロトコルバージョンの盗聴に依存しないヘッダーを思いつきたいと思っていますが、それ以外のものがあればそれを受け入れます。私が好きなようにすべてのヘッダを選択することができるように、すべてのURLは完全カスタムのハンドラを通してフェッチされます。これは中間プロキシとユーザエージェントに関するすべてです。可能であれば、これはHTTP/1.0とHTTP/1.1の両方のクライアントと互換性があります。複数のソリューションが存在する場合、最良のものが配線を介して送信されるときに最短のものになります。HTTPヘッダー:キャッシュと履歴のメカニズムを制御する

静的パブリックコンテンツ

すべての「静的パブリックコンテンツは、」HTTPが本当にすべてに約あるというものである:URLが同じであれば、内容は同じです。私はこれを簡単に行うことができます:例えば、ユーザプロファイルアイコンをhttp://domain.com/profiles/xyz/icon/1234abcdに入れます。ここで、 "1234abcd"はアイコンのファイル内容のSHA-1です。今後iconに変更すると、新しいURLを作成し、新しいアイコンを使用する既存のすべての参照元を変更します。これが永遠にキャッシュされ、共有される可能性があることを宣言するための最良のヘッダは何ですか?私は現在、行に沿って何かを考えています:

Date: <current time> 
Expires: <current time + one year> 

ユーザエージェントとプロキシによるキャッシュを許可するには十分ですか? Last-ModifiedまたはPragmaが必要ですか?

静的非パブリックコンテンツ

すべての「静的非パブリックコンテンツは、」静的ですが、誰もが利用できない場合がありますものです。実際には、このコンテンツは選択されたログインユーザだけが利用できます(セッションはセッションのUUIDを保持するセッションCookieで保持されます)。 URLが同じ場合、コンテンツは同じです。しかし、その応答は公開されていません。ユースケースは、ソーシャルネットワークサービスで選択された友人に共有される画像である可能性があります。私は現在、線に沿って何かを考えている:

Date: <current time> 
Expires: <current time> 
Cache-Control: private, max-age=<huge number>, s-maxage=0 

は、ユーザエージェントによってキャッシュを許可するとしてプロキシを無効にするには、この十分ですか? Pragmaが必要ですか?

揮発公開コンテンツ

すべて「揮発性のパブリックコンテンツは、」揮発性と誰もが利用できるものです。ログインしていないときは、http://slashdot.org/のフロントページのようなものです。意図していないURLのコンテンツをすばやく更新できるようにすることです。 私はユーザエージェント履歴のメカニズムを壊したくないことに注意してください(つまり、揮発性ページから何かをクリックしてから、戻るボタンを押すと、サーバから揮発性ページを取得してはいけません。サーバからリソースを取得する必要があります)。私は現在、行に沿って何か考えています:

キャッシングを防止するのに十分ですが、履歴メカニズム(戻るボタン)を許可するには十分ですか?もし私がCache-Control: no-store, must-revalidateを送ると、私は再ロードを強制することができますが、これは私が望むものではないことがわかります。 Last-ModifiedまたはPragmaが必要ですか?

これは公開されていますが、揮発性であるため中間プロキシがこれをキャッシュできるようにするのはおそらく意味がありません。

揮発性非パブリックコンテンツ

すべて「揮発性非パブリックコンテンツは、」揮発性、みんな(プライベート)に利用できないものです。あなたがログインしているときには、http://slashdot.org/のフロントページのようなものがあります。その意図は、変化していないURLでコンテンツをすばやく更新できるようにすることです。 私はユーザエージェント履歴のメカニズムを壊したくないことに注意してください(つまり、揮発性ページから何かをクリックしてから、戻るボタンを押すと、サーバから揮発性ページを取得してはいけません。サーバからリソースを取得する必要があります)。私は現在、行に沿って何かを考えています:

Date: <current time> 
Expires: <current time> 
Cache-Control: private, max-age=0, s-maxage=0 

これはキャッシングを防止するのに十分ですが、履歴メカニズム(戻るボタン)を許可するには十分ですか? Pragmaが必要ですか?


まだ私の提案のヘッダーでのテスト必要なもの:

  • は、プライベートコンテンツがHTTP/1.0プロキシから漏洩されないことを確認してください。
  • プロキシでキャッシュが正しく機能することを確認します。
  • ユーザエージェントでキャッシュが正しく動作することを確認してください。
  • ユーザエージェント履歴メカニズムがユーザエージェントで動作することを確認します(すべてのケース)。
  • 揮発性ページへのリンクをたどると、サーバーから新しいコンテンツが取得されることを確認します。
  • HTTPの代わりにHTTPSを使用する場合は、すべての結果を確認してください。
+0

私は以前の似たような質問については、http://stackoverflow.com/questions/2970938/ideal-http-cache-control-headers-for-different-types-of-resourcesに気付いています。 3つの重要なパズルの欠点:バックボタンの動作、ユーザーエージェントの互換性、HTTP/1.0プロキシのサポート。 –

+0

また、よく引用される他のソースhttp://www.mnot.net/cache_docs/も、バックボタンとHTTP/1.0プロキシのサポートで、実際のユーザーエージェントの動作に対処していません。 –

+0

ここにCache-Controlに関する記事があります:http://palisade.plynt.com/issues/2008Jul/cache-control-attributes/ - 現実世界のバックボタンの動作、ユーザエージェントの互換性、HTTP/1.0プロキシのサポートもありません。 –

答えて

10

を試しています自身の質問:

静的パブリックコンテンツ

Date: <current time> 
Expires: <current time + one year> 

理由:これは、HTTP/1.0プロキシとRFC 2616のセクション14と互換性があります。http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21 正しいキャッシングにはLast-Modifiedヘッダーは必要ありません(適合するユーザーエージェントはExpiresヘッダーに従うため)が、エンドユーザーが消費するために含めることができます。 Last-Modifiedヘッダーを含めると、ユーザーがReload/Refreshボタンを押した場合のサーバーデータ転送も減少する可能性があります。 Last-Modifiedヘッダーが追加された場合、それは発明されたものの代わりに実際のデータを反映するはずです。サーバのデータ転送を減らしたい場合(Reload/Refreshボタンを押した場合)、実際のLast-Modifiedヘッダを含めることができない場合は、ETagヘッダーを追加して条件付きGET(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26)を許可することができます。すでにLast-Modifiedを追加している場合は、ETagを追加するだけで無駄です。 Last-Modifiedは、HTTP/1.0クライアントとプロキシでもサポートされているため、明らかに優れています。動的ページの場合のETagの適切な値は、ページ/リソースの内容のSHA-1です。 Last-ModifiedまたはETagを使用しても、サーバのインターネット接続のパイプ/データ転送速度のみで、サーバの負荷が軽減されることに注意してください。

静的非パブリックコンテンツ

Date: <current time> 
Expires: <current time> 
Cache-Control: private, max-age=31536000, s-maxage=0 
Vary: Cookie 

理由:DateExpiresヘッダはHTTP/1.0の互換性のためであり、応答がプライベートであることを指定する賢明な方法はありませんので、これらのヘッダは、その通信応答はキャッシュされません。 Cache-Controlヘッダーは、この応答がプライベートキャッシュによってキャッシュされる可能性があるが、共有キャッシュはレスポンスをキャッシュしない可能性があることを示しています。 s-maxage=0が追加されました。privateは、Cache-Controlhttp://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3 - どのプロキシが壊れているかわかりません)をサポートするすべてのプロキシでサポートされていない可能性があります。 max-ageは、60*60*24*365(1年間)の値に設定されています.HTTP/1.1仕様ではこのパラメータの上限が定義されていないため、これは実装に依存していると思います。 Expiresヘッダーは今後1年間に限定されるべきである(SHOULD)ので、ここでは同じロジックを使用しても問題ありません。 Vary: Cookieヘッダーは、訪問者がコンテンツを見ることができるかどうかを確認するために使用されるセッションがCookieで転送されるため必要です。返される応答はCookieの値に依存するため、Cookieヘッダーが変更された場合、キャッシュはキャッシュされた応答を使用できません。

私は個人的に最後の部分を壊すかもしれません。 Vary: Cookieヘッダーを含めないことで、キャッシュを大幅に改善できます。たとえば、選択した認証済みのユーザーに対してのみ返されるhttp://domain.com/icon/12のプロファイルイメージがあります。セッションIDが5f2の訪問者Xがあり、そのユーザーに画像を許可します。訪問者Xがログアウトし、その後に再びログインします。今すぐXはセッションID 2e8をセッションクッキーに保存しています。 Vary: cookieがある場合、ユーザエージェントXはキャッシュされたイメージを使用できず、これをキャッシュに再ロードすることが強制されます。 Cookieによって内容が異なるため、最後に変更した条件付きGETは使用できません。この場合、ETagを使用するとテストできませんでした。この場合、サーバーの応答は同じになります(応答の内容から計算されたSHA-1 ETagに一致します)。 Internet Explorer(少なくともバージョン9まで)は、Vary: Cookie(ソース:http://blogs.msdn.com/b/ie/archive/2010/07/14/caching-improvements-in-internet-explorer-9.aspx)を含むリソースに対して常に条件付きGETを強制することに注意してください。これは、MSIEの内部キャッシュ実装が、最初に送信したCookieを記憶しておらず、現在のCookieが同じものかどうかを知ることができないためです。

ただし、実際に技術的に正しい動作に実際に必要な理由を示すために、Vary: Cookieヘッダーを削除することによって発生する問題の例を次に示します。上記の例を参照して、Xがログアウトした後、訪問者Yが同じユーザーエージェントでログインしているとします(ユーザーエージェントはXとYの間で再起動されている可能性があります)。 Yがhttp://domain.com/icon/12へのリンクを含むページを閲覧した場合、Xが以前に同じユーザーエージェントを使用していなかった場合、Yはアイコンを見ることができなくてもページ内に埋め込まれたアイコンを見るでしょう。私の場合は、おそらく追加されたVary: Cookieに関係なく、Yがユーザーエージェントのキャッシュを検査することによってアイコンに手動でアクセスできるため、これは十分に大きな問題ではありません。ただし、この問題により、Yが技術的にこのコンテンツにアクセスできないことに気付かない可能性があります(Yがコンテンツを共同編集する場合など)。内容が機密と見なされる場合、サーバーはCache-Control指示文によって引き起こされる問題にかかわらず、no-storeを送信する必要があります。

また、Last-Modifiedヘッダーを追加すると、ユーザーが再読み込み/更新ボタンを押すのに役立ちます(上記の説明を参照)。

揮発公開コンテンツ

Date: <current time> 
Expires: <current time> 
Cache-Control: public, max-age=0, s-maxage=0 
Last-Modified: <real-last-modification-time> 

理論的根拠:HTTP/1.0のクライアントと、この応答は、直ちに無効と見なされるべきであることをプロキシに知らせます。 Last-Modified時間は、リソースが再びアクセスされ、クライアントが条件付きGETをサポートするとき、コンテンツデータ送信をスキップできるように含まれています。 Last-Modifiedを使用できない場合は、ETagを代わりに使用することができます(上記の説明を参照)。 HTTP/1.0互換のクライアントで条件付きGETを行うには、Last-Modifiedを使用することが重要です。

内容が少しでも遅れている場合は、Expires,max-ageおよびs-maxage [sic]を適切に調整する必要があります。たとえば、symcbeanの回答が示唆するように、5秒を追加すると人気の高いサイトで多くの手助けをすることができます。条件付きGETとは異なり、有効期限を長くすると、(サーバの要求総数が少なくなるため)サーバの送信データトラフィックを減らすだけではなく、サーバの負荷を軽減できます。

揮発性非パブリックコンテンツ

Date: <current time> 
Expires: <current time> 
Cache-Control: private, max-age=0, s-maxage=0 
Last-Modified: <real-last-modification-time> 
Vary: Cookie 

理由:この応答は、直ちに無効と見なされるべきであること/ 1.0クライアントとプロキシをHTTPを教えてください。 Last-Modified時間は、リソースが再びアクセスされ、クライアントが条件付きGETをサポートするとき、コンテンツデータ送信をスキップできるように含まれています。 Last-Modifiedを使用できない場合は、ETagを代わりに使用することができます(上記の説明を参照)。 HTTP/1.0互換のクライアントで条件付きGETを行うには、Last-Modifiedを使用することが重要です。 Cache-Controlにはno-cache,must-revalidateまたはno-storeを含めてはならないことに注意してください。これらの指令のいずれかを使用すると、少なくとも1つのユーザーエージェントの戻るボタンが壊れるからです。ただし、サーバーが転送しているコンテンツに、恒久ストレージに保存すべきではない敏感な素材が含まれている場合は、戻るボタンの破損に関係なく、no-storeフラグを使用する必要があります。 警告:オペレーティングシステムのスワッピングが有効になっており、スワップが暗号化されていない場合、no-storeを使用しても、機密情報が暗号化されずにハードディスクに記録されるのを防ぐことはできません。 no-storeを使用すると、接続が暗号化されている(HTTPS/SSL)場合を除き、ほとんど意味がありません。

2

ほとんどOK、しかし、あなたは、HTTP/1.0プロキシがコンテンツをキャッシュすることができることを心に留めする必要がありますので、明示的な日付-modifiedヘッダーを設定するだけでなく、有効期限が切れるはずです

Cache-Control: private 

としてアップ務めヘッダ。

「静的な非公開コンテンツ」の場合は、「Varies:Cookie」ヘッダーを追加する必要があります。

あなたの「揮発性のパブリックコンテンツ」については、どれくらい速く変化していますか? TTLを+5秒に設定すると、サーバーから多くの負荷を軽減できます。

'非揮発性非揮発性コンテンツ'の場合は、no-cache、must-revalidateをCache-controlヘッダーに追加してください。

サーバーから発行されたプラグマヘッダーは、クライアントまたはプロキシには影響を与えません。

は私にお答えします(これはすべての条件付きのリクエスト/ 304レスポンスに無人口キャッシュでアクセス1よりもさらに遅いあなたがシステムで終わることができIME)あなたのキャッシュの有効期限が切れたときに何が起こるか

+0

私は、 'Cache-Control:private'はHTTP/1.0プロキシによって理解されていないことに気付いています。それが私が 'Date'と' Expires'を現在の時刻に置く理由です。これは、正しく理解していれば、すぐにHTTP/1.0プロキシからコンテンツを失効させるはずです。明示的な 'Date-Modified'ヘッダーが必要なのはなぜですか?それはいくつかのユーザエージェントによって要求されていますか? –

+0

私は 'no-cache、must-revalidate'を 'Volatile non-public content'に追加すると、少なくともFirefoxとInternet Explorerでは戻るボタンが壊れると思います。可能であれば、サーバーの状態を透過的に表示するのではなく、実際の履歴を表示するためにボタンを元の状態に戻すことです。詳細については、http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.13を参照してください。 –

+0

ヘッダーの構文は 'Vary:Cookie'だと思います。私はそれについて考えましたが、ユーザーエージェント(ブラウザ)もこのヘッダーを尊重してユーザーエージェントのキャッシュを破るためです。例: 'http://domain.com/icon/12'にプロファイルイメージがあり、これは選択された認証済みのユーザーに対してのみ返されます。セッションIDが「5f2」のビジターXがあり、そのユーザーにイメージを許可します。訪問者Xはログアウトしてから、後で再びログインします。 Xはセッションクッキーに格納されたセッションID '2e8'を持つようになりました。 'Vary:cookie'があれば、Xのユーザエージェントはキャッシュされたイメージを使うことができません。技術的には、「Vary:cookie」が正しいでしょう。 –

関連する問題