5
<VirtualHost *:80>
    ServerAdmin webmaster@dev.dom.com
    DocumentRoot "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs"
    ServerName dev.dom.com
    ServerAlias dev.dom.com
    ErrorLog "logs/dev.dom.com-error.log"
    CustomLog "logs/dev.dom.com-access.log" common
    PassEnv CLUSTER
    Header always set X-Cluster "%{CLUSTER}e"
</VirtualHost>

これが私の構成です。「X-Cluster」のヘッダーとして渡される、現在のクラスターを示す環境変数があります。これは 200 または 404 応答では問題なく返されますが、304 Not Modified 応答では、他の適切な Apache ヘッダーが返されても、ヘッダーが返されることはありません。

304 応答中にヘッダーを設定するにはどうすればよいですか?

4

2 に答える 2

8

現在の HTTP 仕様によると、304 Not Modified応答はエンティティ ヘッダーを返すことは想定されていません (いくつかの特定の例外を除く)。RFC 2616 のセクション 10.3.5からの引用:

条件付き GET が強力なキャッシュ バリデーターを使用した場合、応答には他のエンティティ ヘッダーを含めないでください (SHOULD NOT)。それ以外の場合 (つまり、条件付き GET で弱いバリデータが使用された場合)、応答に他のエンティティ ヘッダーを含めてはなりません (MUST NOT)。これにより、キャッシュされたエンティティ本体と更新されたヘッダーの間の不一致が防止されます。

残念ながら、すべての拡張ヘッダーはエンティティ ヘッダーとして分類されます

ただし、将来に目を向けると、RFC 2616 を置き換えることを意図した HTTPbis 仕様のドラフトでは、ルールが大幅に緩和されています。Conditional Requests 仕様のセクション 4.1からの引用:

304 応答の目的は、受信者が既に 1 つまたは複数のキャッシュされた表現を持っている場合に情報転送を最小限に抑えることであるため、送信者は、上記のメタデータがキャッシュの更新を導く目的で存在しない限り、上記のフィールド以外の表現メタデータを生成すべきではありません (SHOULD NOT)。

そのため、表現メタデータとして分類されないカスタム ヘッダーを設定している場合は、新しいルールの下で合法であると見なされると予想されます。

とはいえ、これらの仕様に何が書かれていようとも、Apache がサポートできるものに対処する必要があります。また、ソース コードで確認したところ、カスタム ヘッダーは 304 応答ではまだサポートされていません。

ヘッダーがフィルタリングされる場所は、ファイル /modules/http/http_filters.c のap_http_header_filter関数にあります。

より具体的には、このコード:

if (r->status == HTTP_NOT_MODIFIED) {
    apr_table_do((int (*)(void *, const char *, const char *)) form_header_field,
                 (void *) &h, r->headers_out,
                 "Connection",
                 "Keep-Alive",
                 "ETag",
                 "Content-Location",
                 "Expires",
                 "Cache-Control",
                 "Vary",
                 "Warning",
                 "WWW-Authenticate",
                 "Proxy-Authenticate",
                 "Set-Cookie",
                 "Set-Cookie2",
                 NULL);
}

"Not Modified" 応答 (304) を返す場合、上記のヘッダーのリストのみが通過します ( DateServerなどの自動生成されたいくつかのヘッダーを除く)。そして、私が見る限り、このコードにフックして動作を変更する簡単な方法はないようです。

肝心なのは、これは現時点で Apache ではまだ不可能だということです。他のヘッダーのサポートを要求するバグ レポートが少なくとも1 つありますが、それは CORS ヘッダー専用です。ただし、運が良ければ、一般的にカスタム ヘッダーのサポートに対してよりオープンになる可能性があります。

しかし、それが起こるまで、私が提案できる唯一の解決策は、サーバーに自分でパッチを当てることです. ソースから再構築する必要がない場合は、バイナリに直接パッチを適用することもできます。たとえば、1 つまたは 2 つの新しいヘッダーのみをサポートする必要がある場合は、使用する可能性が低い既存のヘッダーの一部を置き換えることができます (たとえば、いずれにしても廃止されたSet-Cookie2 )。

置き換えたいヘッダー名を Apache bin ディレクトリで検索するだけです (Windows ではlibhttpd.dllで見つける必要があります)。次に、バイナリ エディターを使用して、null で終わる文字列を新しいヘッダー名に置き換えます (もちろん、置き換えるヘッダーと同じ長さかそれよりも短い必要があります)。

他のオペレーティング システムについてはわかりませんが、これを Windows でテストしたところ、動作するようです。これは明らかに恐ろしいハックですが、どうしても必要な場合は、オプションと考えることができます。

于 2013-07-23T23:28:44.270 に答える
2

Apache は、http 仕様に準拠するために 304 応答の応答ヘッダーを変更することを明示的に禁止しています。このタイプの応答の名前は「変更されていません」です。Apache のフィルター アーキテクチャを使用したり、カスタム モジュールを作成したり、mod_perl を使用したりすることで、この動作を変更できますが、それはおそらく間違った方法です。

于 2011-11-18T18:40:23.123 に答える