Сжатие gzip ответа кодированной части? - PullRequest
31 голосов
/ 12 марта 2011

Я пытаюсь заставить мой веб-сервер правильно сжать HTTP-ответ, который представляет собой чан-кодировку.

Насколько я понимаю, ответ не-gzip выглядит так:

<the response headers>

, а затем для каждого чанка:

<chunk length in hex>\r\n<chunk>\r\n

и, наконец, чанк нулевой длины:

0\r\n\r\n

Я пытался заставить работать сжатие gzip, и я мог бы использовать некоторую справочную информациюиз того, что на самом деле должно быть возвращено.Эта документация подразумевает, что весь ответ должен быть разархивирован, а не разархивирован каждый кусок:

HTTP servers sometimes use compression (gzip) or deflate methods to optimize transmission.
Chunked transfer encoding can be used to delimit parts of the compressed object.
In this case the chunks are not individually compressed. Instead, the complete payload 
is compressed and the output of the compression process is chunk encoded.

Я пытался сжать весь ответ и вернуть ответ даже без разделения, и это не сработало.Я попытался установить заголовок Content-Encoding в "gzip".Может кто-нибудь объяснить, какие изменения необходимо внести в вышеприведенную схему для поддержки распаковки кусков?Спасибо.

Ответы [ 3 ]

32 голосов
/ 02 февраля 2012

В случае, если другие ответы не были достаточно ясны:

Сначала вы сжимаете тело с помощью zlib (это можно сделать в потоке, чтобы вам не понадобилось все это в памяти сразу, а в этом весь смысл разброса).

Затем вы отправляете это сжатое тело кусками (предположительно, предоставленными потоком gzip, с заголовком чанка, чтобы объявить, как долго это), с Content-Encoding: gzip и Transfer-Encoding: chunked headers (и нет Контент-длина заголовка).

Если вы используете gzip или zcat или какую-либо другую утилиту для сжатия, она, вероятно, не будет работать. Нужно быть злеб. Если вы создаете куски, а затем сжимаете их, это точно не сработает. Если вы считаете, что делаете это правильно, и это не работает, вы можете попытаться взять трассировку пакета и задать вопросы на основе этого и любых сообщений об ошибках, которые вы получаете.

22 голосов
/ 08 апреля 2011

Вы распаковываете содержимое, и только затем применяете кодировку chunked:

«Поскольку« chunked »является единственной кодировкой передачи, которую должны понимать получатели HTTP / 1.1, она играет решающую роль в разделениисообщения о постоянном соединении. Всякий раз, когда кодирование передачи применяется к телу полезной нагрузки в запросе, конечное примененное кодирование передачи ДОЛЖНО быть "разбито на куски". Если кодирование передачи применяется к телу полезной нагрузки ответа, то либоприменяемое кодирование передачи ДОЛЖНО быть "chunked", или сообщение ДОЛЖНО завершаться закрытием соединения. Когда используется "chunked" кодирование передачи, оно ДОЛЖНО быть последним кодированием передачи, применяемым для формирования тела сообщения. "chunked"«кодирование передачи НЕ ДОЛЖНО применяться более одного раза в теле сообщения».

( HTTPbis Часть 1, Раздел 6.2.1 )

1 голос
/ 08 апреля 2011

Вероятно, вы на самом деле не отправляете должным образом сжатый ответ.

Попробуйте установить window bits в 31 в zlib.И используйте deflateInit2().

...