Transfer-Encoding:gzipとContent-Encoding:gzip


98

それをするかどうかということになると、現在の状況はどうですか

Transfer-Encoding: gzip

または

Content-Encoding: gzip

たとえば、帯域幅が制限されているクライアントに、圧縮された応答を受け入れる意志があること通知することを許可し、サーバーが最終的に圧縮するかどうかを決定する場合

後者は、たとえば、Apacheのmod_deflateとIISが圧縮を処理する場合に行うことです。圧縮するコンテンツのサイズに応じて、追加の処理が行われますTransfer-Encoding: chunked

またVary: Accept-Encoding、既に問題のヒントとなっているも含まれます。Content-Encodingエンティティの一部であるように見えるため、エンティティの変更に応じてContent-Encoding金額を変更します。つまり、Accept-Encodingヘッダーが異なるということは、たとえば、キャッシュがそれ以外の場合は同一のエンティティのキ​​ャッシュバージョンを使用できないことを意味します。

私が見逃した明確な答えはありますか(そして、それはいくつかのApacheニュースグループの長いスレッドのメッセージの中に埋め込まれていません)?

私の現在の印象は:

  • Transfer-Encodingは、実際には、既存のサーバーとクライアントの実装によってContent-Encodingで主に行われることを実行する正しい方法です
  • Content-Encodingは、その意味上の影響のため、いくつかの問題を抱えています(サーバーがETag応答を透過的に圧縮する場合、サーバーは何をすべきですか?)
  • その理由は、ニワトリではありません。ブラウザがサポートしていないためサーバーがサポートしていないため、ブラウザはそれをサポートしていません。

私は正しい方法を想定していますので、だろうTransfer-Encoding: gzip(Iさらにチャンク体、それがあれば、またはなります Transfer-Encoding: gzip, chunked)。タッチする理由VaryETag、それはトランスポートレベルのことだとして、その場合には、他のヘッダをか。

今のところ、の「ホップバイホップ」性についてはあまり気にしません。Transfer-Encodingプロキシは圧縮解除されて非圧縮でクライアントに転送される可能性があるため、他の人が何よりもまず心配しているようです。ただし、元のリクエストに適切なAccept-Encodingヘッダーが含まれている場合、プロキシはそのまま(圧縮されて)転送する可能性があります。これは、私が知っているすべてのブラウザの場合、ヘッダーが指定されているためです。

ところで、この問題は少なくとも10年前のものです。例:https : //bugzilla.mozilla.org/show_bug.cgi?id=68517を参照して ください

これについての明確化は高く評価されます。標準に準拠していると見なされるものと、実用的であると見なされるものの両方に関して。たとえば、透過的な「Content-Encoding」のみをサポートするHTTPクライアントライブラリは、実用性に反するものです。



ちょうどこれに遭遇しました。PHP 5.3のCurlはを認識しませんがTransfer-Encoding:gzip、コマンドラインcurlは認識します。安全のために、チャンクとgzipを組み合わせる場合を除いて、両方を送信します。
Seva Alekseyev 2016

1
@SevaAlekseyev両方を送信するのは非常に間違っています-クライアントは2回解凍しようとする可能性があります
Joshua Wise

これも私を永遠に悩ませてきました(私が尋ねた質問)... @JoLissが引用した質問への回答の1つによると、要求/応答ボディを圧縮するための完全に論理的で、意味的に一貫性があり、標準に準拠した方法があります…そして基本的にクライアント/サーバーはそれを使用またはサポートしていません。🤦🏻‍
Dan Lenski

回答:


35

RFC 2616の著者の1人であるロイT.フィールディングの引用:

一貫性のない方法でコンテンツエンコーディングをオンザフライで変更する(「決して」でも「常に」でもない)と、そのコンテンツ(たとえば、PUTまたは条件付きGET)に関するその後の要求が正しく処理されなくなります。オンザフライのコンテンツエンコーディングは愚かな考えであり、リソースを変更せずにオンザフライエンコーディングを行う適切な方法として、なぜHTTPにTransfer-Encodingを追加したのか。

ソース:https : //issues.apache.org/bugzilla/show_bug.cgi?id=39727#c31

つまり、オンザフライの Content-Encodingを行わず、代わりにTransfer-Encodingを使用してください!

編集:つまり、Content-Encodingのみを理解するクライアントにgzip圧縮されたコンテンツを提供する場合を除きます。残念ながら、それらはほとんどのようです。ただし、仕様のレルム離れると、 Fieldingによって言及された問題や他の問題(たとえば、キャッシュプロキシが関係する場合)に遭遇する可能性があることに注意してください。


3
したがって、私が正しく理解した場合、次のようになります。1. Content-encodingは、抽象的にサーバー上のコンテンツエンコーディングを指します。つまり、コンテンツはサーバーによって指定されたエンコーディングで一貫して提供されます。2. transfer-encodingは、サーバーがこのインスタンスで、つまりこの応答でユーザーエージェントに配信するために使用することを決定したエンコードを指します。私があなたの答えを間違って解釈していないことを確認してください。
ドットスラッシュハック

30
@KemHeyndels権利について。別の言い方をすると、仕様によると、Transfer-Encodingは純粋なトランスポート層の詳細です。つまり、中間プロキシはそのレベルでgzip圧縮などを自由に元に戻すことができますが、Content-Encodingはビジネス層のプロパティであり、プロキシはそうではありません他の影響(ETagなど)に加えて、変更が許可されています。ただし現実には、TEは通常圧縮に使用されず、多くのサーバー/クライアントはそのままではサポートしていませんが、CEは多かれ少なかれTEが意図した方法で使用されています:トランスポート層の詳細として。
ユージーン・ベレソフスキー

1
だから私たちは現実にロイ・T・フィールディングのアドバイスを無視する義務があるのですか?
ドットスラッシュハック

11
@KemHeyndels理想主義に出て、最初にすべてのオープンソースHTTPクライアント/サーバー実装にTEサポートを追加する必要があります。次に、クローズドソースのHTTP実装(とにかくMicrosoftだけだと思います)をしているすべての会社で採用され、そこにも機能を追加します。その後、現実と仕様は一致します。;)(そして、HTTP 2.0がリリースされ、問題は
取り除かれ

10
Transfer-Encodingをサポートしていることを示しても、Transfer-Encodingよりもgzipをサポートしていることが明確ではないため、何も購入しません。表示は逆に行われます。Transfer-Encodingを介してgzipを実行できるクライアントは、を設定することでサーバーに通知しますTE: gzip。次に、サーバーはTransfer-Encodingルートに移動します。クライアントがとだけ言う場合はAccept-Encoding: gzip、そのContent-Encodingようにする必要があります。クライアントがリクエストでどちらも指定しない場合、サーバーはまったくgzipしてはなりません。
Eugene Beresovsky 14

27

正しいクライアントに送信するために使用方法は、RFC 2616で定義され、実際に野生で実装されるAccept-Encodingリクエストヘッダを(クライアントが複数のエンコーディングを指定することができます)。次に、サーバーは、クライアントのサポートされているエンコーディング(ファイルデータがそのエンコーディングにまだ格納されていない場合)に従って応答をエンコードし、Content-Encodingどのエンコーディングが使用されているかを応答ヘッダーで示します。次に、クライアントは、に基づいて、ソケットのからデータを読み取ることができるTransfer-Encoding(すなわち、chunked)、その後に基づいて、それをデコードContent-Encoding(すなわち:gzip)。

そのため、あなたのケースでは、クライアントがAccept-Encoding: gzipリクエストヘッダーを送信し、サーバーが(まだでない場合)圧縮してContent-Encoding: gzip、オプションでTransfer-Encoding: chunkedレスポンスヘッダーを送信することを決定します。

そして、はい、Transfer-Encodingヘッダーはリクエストで使用できますが、HTTP 1.1の場合のみで、クライアントとサーバーの両方の実装chunkedが両方向のエンコーディングをサポートする必要があります。

ETag実際に送信されているデータではなく、サーバー上のリソースデータを一意に識別します。特定のURLリソースのETag値が変更された場合は、そのリソースのサーバー側データが変更されたことを意味します。


14
content-codingは、Request-URIによって識別されるエンティティの特性です。言い換えると、異なるContent-Encoding要求は異なる必要がありますETagこれは、私の回答で言及しているmod_deflateのバグのすべてです。なぜこのアプリケーションレベルの詳細が最初からHTTP標準にあるのかと不思議に思います。Transfer-Encodingただし、トランスポートレベル設定を使用する場合は、を変更する必要はありませんETag。Transfer-Encを実装した人がいない場合を除きます。
ユージーンベレソフスキー2013年

2
Content-Encodingは「オンザフライ」エンコーディング用ではありません。RFC 2616には、「Transfer-Encoding ...はcontent-codingとは異なり、transfer-codingはエンティティではなくメッセージのプロパティである」と記載されています。(tools.ietf.org/html/rfc2616#section-14.41)、および「コンテンツコーディングは、Request-URIによって識別されるエンティティの特性です。通常、エンティティボディはこのエンコーディングで保存されます」(tools.ietf.org/html/rfc2616#section-14.11)。だから私は反対票を投じる。
Robert

私が説明したのは、vs に関係なく実際に実際に実装されている」ものです。はい、オンザフライで行われる場合、gzip リソースの転送のプロパティである必要があります。一方、リソースがサーバーに圧縮されて保存されている場合、そのまま送信される場合は、リソースのコンテンツのプロパティである必要があります。しかし、本来あるべきもの実際にあるものは必ずしも同じでありません。Content-EncodingTransfer-Encoding
レミールボー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.