Jaki jest obecny stan rzeczy, jeśli chodzi o podjęcie decyzji
Transfer-Encoding: gzip
lub a
Content-Encoding: gzip
kiedy chcę pozwolić klientom z np. ograniczoną przepustowością na zasygnalizowanie swojej chęci przyjęcia skompresowanej odpowiedzi a serwer ma ostateczną decyzję, czy kompresować czy nie .
To ostatnie jest tym, co robią np. Mod_deflate Apache i IIS, jeśli pozwolisz mu zająć się kompresją. W zależności od rozmiaru zawartości do skompresowania, zrobi to dodatkowe Transfer-Encoding: chunked
.
Będzie również zawierać Vary: Accept-Encoding
podpowiedź, która już wskazuje na problem. Content-Encoding
wydaje się być częścią jednostki, więc zmianaContent-Encoding
kwot w celu zmiany jednostki, tj. inny Accept-Encoding
nagłówek oznacza, że np. pamięć podręczna nie może używać swojej buforowanej wersji identycznej jednostki.
Czy jest jakaś konkretna odpowiedź na to pytanie, którą przegapiłem (i nie jest ona ukryta w wiadomości w długim wątku w jakiejś grupie dyskusyjnej apache)?
Moje obecne wrażenie to:
- Transfer-Encoding byłby w rzeczywistości właściwym sposobem na zrobienie tego, co jest najczęściej robione z Content-Encoding przez istniejące implikacje serwera i klienta
- Content-Encoding, ze względu na swoje implikacje semantyczne, niesie ze sobą kilka problemów (co powinien zrobić serwer,
ETag
gdy w przejrzysty sposób kompresuje odpowiedź?) - Powód jest taki, że chicken'n'egg: przeglądarki tego nie obsługują, ponieważ serwery nie obsługują, ponieważ przeglądarki nie obsługują
Zakładam więc, że właściwą drogą będzie Transfer-Encoding: gzip
(lub, jeśli dodatkowo rozbiję ciało, stanie się Transfer-Encoding: gzip, chunked
). I nie ma powodu, by dotykać Vary
lubETag
żadnego innego nagłówka w tym przypadku, ponieważ jest to rzecz na poziomie transportu.
Na razie nie obchodzi mnie zbytnio „przeskok po skoku” Transfer-Encoding
, coś, czym inni wydają się być zainteresowani przede wszystkim, ponieważ serwery proxy mogą zdekompresować i przekazać klientowi bez kompresji. Jednak serwery proxy mogą równie dobrze przekazywać je w stanie, w jakim są (skompresowane), jeśli oryginalne żądanie ma odpowiedni Accept-Encoding
nagłówek, który w przypadku wszystkich przeglądarek, które znam, jest dany.
Przy okazji, ten problem ma co najmniej dekadę, patrz np . Https://bugzilla.mozilla.org/show_bug.cgi?id=68517 .
Wszelkie wyjaśnienia w tej sprawie 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 klienta HTTP obsługujące tylko przezroczyste „kodowanie zawartości” byłyby argumentem przeciwko praktyczności.
źródło
Transfer-Encoding:gzip
, chociaż curl z linii poleceń tak. Aby być po bezpiecznej stronie, wyślij oba, chyba że łączysz fragmenty i gzip.Odpowiedzi:
Cytując Roya T. Fieldinga , jednego z autorów RFC 2616:
Źródło: https://issues.apache.org/bugzilla/show_bug.cgi?id=39727#c31
Innymi słowy: nie rób kodowania zawartości w locie , zamiast tego użyj Transfer-Encoding!
Edycja: to znaczy, chyba że chcesz udostępniać zawartość spakowaną gzip klientom, którzy rozumieją tylko kodowanie zawartości . Co niestety wydaje się być większością z nich. Ale pamiętaj, że opuścisz dziedzinę specyfikacji i możesz napotkać problemy takie jak ten, o którym wspomniał Fielding, a także inne, np. Gdy w grę wchodzą serwery proxy buforujące.
źródło
TE: gzip
. Następnie twój serwer powinien przejść na trasę Transfer-Encoding. Jeśli klient tylko mówiAccept-Encoding: gzip
, musisz to zrobić poContent-Encoding
drodze. Jeśli klient nie określi żadnego w swoim żądaniu, serwer nie może w ogóle gzipować.Prawidłowe wykorzystanie, zgodnie z definicją zawartą w dokumencie RFC 2616 i faktycznie realizowane w środowisku naturalnym, jest dla klienta, aby wysłać
Accept-Encoding
nagłówka żądania (klient może określić wiele kodowań). Serwer może wtedy i tylko wtedy zakodować odpowiedź zgodnie z obsługiwanymi przez klienta kodowaniami (jeśli dane pliku nie są już zapisane w tym kodowaniu), wskazać wContent-Encoding
nagłówku odpowiedzi, które kodowanie jest używane. Klient może następnie odczytać dane z gniazda na podstawieTransfer-Encoding
(tj.chunked
), A następnie zdekodować je na podstawieContent-Encoding
(tj:gzip
.Tak więc w twoim przypadku klient wyśle
Accept-Encoding: gzip
nagłówek żądania, a następnie serwer może zdecydować o skompresowaniu (jeśli nie jeszcze) i wysłaniuContent-Encoding: gzip
i opcjonalnieTransfer-Encoding: chunked
nagłówka odpowiedzi.I tak, plik
Transfer-Encoding
nagłówek może być używany w żądaniach, ale tylko w przypadku protokołu HTTP 1.1, który wymaga, aby implementacje klienta i serwera obsługiwałychunked
kodowanie w obu kierunkach.ETag
jednoznacznie identyfikuje dane zasobów na serwerze, a nie dane faktycznie przesyłane. Jeśli dany zasób adresu URL zmienia swojąETag
wartość, oznacza to, że zmieniły się dane po stronie serwera dla tego zasobu.źródło
Content-Encoding
wymagania różneETag
To właśnie dotyczy błędu mod_deflate, o którym mówię w mojej odpowiedzi. Zastanawiam się, dlaczego te szczegóły na poziomie aplikacji są w standardzie HTTP.Transfer-Encoding
Jednak podczas korzystania z ustawienia poziomu transportu nie ma potrzeby zmiany plikuETag
. Poza tym, że nikt nie zaimplementował Transfer-Enc.Content-Encoding
vsTransfer-Encoding
. Tak, gzip powinien być właściwością transferu zasobu, jeśli odbywa się w locie. Z drugiej strony, jeśli zasób jest przechowywany w postaci skompresowanej na serwerze, powinien być zamiast tego właściwością zawartości zasobu, jeśli jest wysyłany w stanie, w jakim jest. Ale to, co powinno być, a co faktycznie jest, nie zawsze jest tym samym.