Как заставить Apache mod_deflate и Transfer-encoding: Chunked работать вместе? - PullRequest
4 голосов
/ 28 января 2012

Я пытаюсь использовать концепцию bigpipe на нашем сайте.Это означает, что нужно пытаться отправить ответ кусками, а не отправлять его целиком, чтобы пользователь чувствовал, что страница работает быстро.Я успешен в этом, используя метод flushBuffer для объекта ответа в Java.Но теперь, когда я пытаюсь сжать содержимое с помощью модуля apache mod_deflate, фрагментация теряется.

Вот конфигурация из apache, используемая для сжатия содержимого

**

Начало конфигурации mod_deflate

DeflateBufferSize 100
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
DeflateFilterNote Input input_info
DeflateFilterNote Output output_info
DeflateFilterNote Ratio ratio_info
LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate
CustomLog /var/log/httpd/deflate_log deflate

Конец конфигурации mod_deflate **

Вот заголовок ответа, когда дефлят включен в apache

Соединение: Keep-Alive
Кодирование содержимого: gzip
Длина содержимого: 7916
Content-Type: text / html;charset = UTF-8
Дата: пт, 27 января 2012 20:11:11 GMT
Keep-Alive: время ожидания = 300, макс = 3997
Сервер: Apache
Варьируется: Accept-Encoding

Заголовок ответа при отключении дефлята в apache

Соединение: Keep-Alive
Тип содержимого: text / html;charset = UTF-8
Дата: пт, 27 января 2012 20:21:14 GMT
Keep-Alive: время ожидания = 300, макс = 3997
Сервер: Apache / 2.2.3 (CentOS)
Transfer-Encoding: chunked

Как вы можете видеть выше, 2 заголовка chunking работает, только если сжатие отключено.Я искал в Интернете об этом, и люди предлагали уменьшить значение DeflateBufferSize .Я уменьшил значение до 100 байт, как вы можете видеть в моей конфигурации apache, но это все еще не решило проблему.Значение DeflateBufferSize, равное 100 байтам, означает, что ответ буферизуется в apache до получения 100 байт, а затем он сжимается.

Я смотрел на модуль mod_gzip, который был связан со старым apache 1.3, и этот модуль имеетследующая директива, позволяющая архивировать содержимое по частям.

mod_gzip_dechunk Да

Кто-нибудь знает о такой директиве в mod_deflate в комплекте с apache 2.x?

Или кто-нибудь знает каксжать кусочный контент?

Ответы [ 2 ]

2 голосов
/ 25 августа 2012

На самом деле я нашел решение.Я использовал для создания нового объекта GZipOutputStream каждый раз, чтобы сбрасывать разные куски.Вместо этого вы должны создать только один объект GZipOutputStream, а затем использовать этот объект для сжатия всех фрагментов ответа.Также я помещаю обертку вокруг GZipOutputStream.Вот обертка, которую я получил от поиска в Google.

public class GZIPFlushableOutputStream extends GZIPOutputStream {

    public GZIPFlushableOutputStream(final OutputStream out) throws IOException {
        // Using Deflater with nowrap == true will ommit headers and trailers
        super(out);
    }

    private static final byte[] EMPTYBYTEARRAY = new byte[0];

    /**
     * Insure all remaining data will be output.
     */
    public void flush() throws IOException {
        /**
         * Now this is tricky: We force the Deflater to flush its data by
         * switching compression level. As yet, a perplexingly simple workaround
         * for
         * 
         * http://developer.java.sun.com/developer/bugParade/bugs/42557 43.html
         */
        def.setInput(EMPTYBYTEARRAY, 0, 0);

        def.setLevel(Deflater.NO_COMPRESSION);
        deflate();

        def.setLevel(Deflater.DEFAULT_COMPRESSION);
        deflate();

        out.flush();
    }
}
1 голос
/ 26 мая 2012

Насколько я понимаю, вам нужен "целый" файл, чтобы сжать его. Вы можете отправить его в виде кусков или и отправить его сжатым. Опция mod_gzip_dechunk больше не существует - см. документация mod_deflate .

...