Transfer-Encoding: gzip vs. Content-Encoding: gzip

Jaki jest obecny stan rzeczy, jeśli chodzi o to, czy zrobić

Transfer-Encoding: gzip

Lub

Content-Encoding: gzip

Kiedy chcę zezwolić klientom z np. ograniczoną przepustowością do zasygnalizować chęć zaakceptowania skompresowanej odpowiedzi, A Serwer ma ostatnie słowo, czy kompresować.

Ten ostatni jest tym, co robią np. mod_deflate Apache i IIS, jeśli pozwolisz, aby zajął się kompresją. W zależności od wielkości zawartość, która ma być skompresowana, wykona dodatkowe Transfer-Encoding: chunked.

Będzie również zawierać Vary: Accept-Encoding, który już podpowiada problem. Content-Encoding wydaje się być częścią encji, więc zmiana Content-Encoding oznacza zmianę encji, tzn. inny nagłówek Accept-Encoding oznacza, że np. cache nie może używać swojej buforowanej wersji identycznej encji.

Czy jest na to konkretna odpowiedź, którą przeoczyłem (i to nie jest zakopane w wiadomości w długim wątku w jakimś apache grupa dyskusyjna)?

Moje obecne wrażenie to:

    W rzeczywistości kodowanie transferowe byłoby właściwym sposobem na to, co najczęściej robi się z kodowaniem treści za pomocą istniejących implantów serwera i klienta.]}
  • kodowanie treści, ze względu na swoje semantyczne implikacje, niesie ze sobą kilka problemów (co serwer powinien zrobić z ETag, gdy transparentnie kompresuje odpowiedź?)
  • powodem jest chicken ' n ' Egg: przeglądarki nie obsługują tego, ponieważ serwery nie obsługują, ponieważ przeglądarki nie

Więc zakładam, że właściwą drogą będzie Transfer-Encoding: gzip (lub, jeśli dodatkowo pochłonie ciało, to stanie się Transfer-Encoding: gzip, chunked). I nie ma powodu dotykać Vary lub ETag lub jakiegokolwiek innego nagłówka w tym przypadku, ponieważ jest to rzecz na poziomie transportu.

Na razie nie dbam zbytnio o "hop-by-hop" - ness Transfer-Encoding, coś, o co inni wydają się martwić przede wszystkim, ponieważ proxy mogą dekompresować i przesyłać nieskompresowane do klienta. Jednak proxy może równie dobrze przesłać je tak, jak-jest (skompresowane), jeśli oryginalne żądanie ma właściwy nagłówek Accept-Encoding, który w przypadku wszystkich przeglądarek, które znam, jest dany.

Btw, ten problem ma co najmniej dekadę, patrz np. https://bugzilla.mozilla.org/show_bug.cgi?id=68517 .

Wszelkie wyjaśnienia na ten temat będą mile widziane. Zarówno pod względem tego, co jest uważane za zgodne z normami, jak i tego, co jest uważane za praktyczne. Na przykład biblioteki klientów HTTP obsługujące tylko przezroczyste "Kodowanie treści" byłoby argumentem przeciwko praktyczności.

Author: Eugene Beresovksy, 2012-07-25

2 answers

Cytat Roy T. Fielding , jeden z autorów RFC 2616:

Zmiana kodowania treści w locie w niespójny sposób (ani "nigdy", ani "zawsze") uniemożliwia późniejsze żądania jeśli chodzi o treść (np. PUT lub conditional GET) do obsługi prawidłowo. To jest, oczywiście, dlaczego występ w locie content-encoding to głupi pomysł i dlaczego dodałem Transfer-Encoding HTTP jako właściwy sposób na kodowanie w locie bez zmiana zasób.

Źródło: https://issues.apache.org/bugzilla/show_bug.cgi?id=39727#c31

Innymi słowy: nie rób on-the-fly Content-Encoding, zamiast tego użyj Transfer-Encoding!

Edit: czyli , chyba że chcesz podawać treść gzipped klientom, którzy rozumieją tylko kodowanie Treści . Które, niestety, wydaje się być większość z nich. Ale pamiętaj, że opuścisz sfery spec i możesz wpaść w problemy takie jak ten wspomniany przez Fieldinga, jak również inne, np. podczas buforowania proxy są zaangażowane.

 37
Author: Evgeniy Berezovsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-17 22:42:34

Poprawne użycie , zdefiniowane w RFC 2616 i faktycznie zaimplementowane w środowisku naturalnym, polega na wysłaniu przez Klienta nagłówka żądania Accept-Encoding (klient może określić wiele kodowań). Serwer może wtedy i tylko wtedy zakodować odpowiedź zgodnie z obsługiwanymi kodowaniami klienta (jeśli DANE pliku nie są jeszcze zapisane w tym kodowaniu), wskazać w nagłówku odpowiedzi Content-Encoding, które kodowanie jest używane. Klient może następnie odczytać dane z gniazda na podstawie Transfer-Encoding (ie, chunked), a następnie dekodować na podstawie Content-Encoding (ie: gzip).

Tak więc, w Twoim przypadku, klient wyśle Accept-Encoding: gzip nagłówek żądania, a następnie serwer może zdecydować się na kompresję (jeśli jeszcze nie) i wysłać Content-Encoding: gzip i opcjonalnie Transfer-Encoding: chunked nagłówek odpowiedzi.

I tak, nagłówek Transfer-Encoding może być używany w żądaniach, ale tylko dla HTTP 1.1, który wymaga, aby zarówno implementacje klienta, jak i serwera wspierały kodowanie chunked w obu kierunkach.

ETag jednoznacznie identyfikuje zasób dane na serwerze, a nie dane faktycznie przesyłane. Jeśli dany zasób URL zmienia swoją wartość ETag, oznacza to, że dane po stronie serwera dla tego zasobu uległy zmianie.

 29
Author: Remy Lebeau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-08 02:16:08