如何制作Apache mod_deflate和Transfer-encoding:Chunked一起工作?

时间:2012-01-27 20:34:48

标签: apache mod-deflate chunked

我正在尝试在我们的网站上使用bigpipe概念。这意味着尝试以块的形式发送响应,而不是将其作为一个整体发送,以便用户感觉页面很快。我通过在java中的响应对象上使用flushBuffer方法成功地做到了这一点。但是现在当我尝试用apache mod_deflate模块压缩内容时,分块就丢失了。

以下是用于压缩内容的apache配置

**

开始mod_deflate config

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 config **

这是在apache

中打开deflate时的响应标头

连接:保持活动
内容编码:gzip
内容长度:7916
内容类型:text / html的;字符集= UTF-8
日期:2012年1月27日星期五20:11:11 GMT
保持活跃:超时= 300,最大= 3997
服务器:Apache
变化:接受编码

在apache中关闭deflate时的响应标头

连接:保持活动
内容类型:text / html的;字符集= UTF-8
日期:2012年1月27日星期五20:21:14 GMT
保持活跃:超时= 300,最大= 3997
服务器:Apache / 2.2.3(CentOS)
转移编码:分块

正如您在上面看到的那样,只有在压缩关闭的情况下,两个标题才会有效。我在网上搜索这个,人们建议减少 DeflateBufferSize 值。我将值减少到100字节,你可以在我的apache配置中看到,但仍然无法解决问题。将DeflateBufferSize设置为100字节意味着响应在apache中缓冲,直到收到100个字节,然后压缩它。

我正在查看与旧apache 1.3捆绑在一起的mod_gzip模块,该模块有一个以下指令,允许对chunked内容进行gzip压缩。

mod_gzip_dechunk是

有没有人知道与apache 2.x捆绑的mod_deflate中的这样的指令?

或者有谁知道如何压缩分块内容?

2 个答案:

答案 0 :(得分:2)

实际上我找到了解决方案。我曾经每次创建一个GZipOutputStream的新对象来刷新不同的块。相反,您应该只创建一个GZipOutputStream对象,然后使用该对象压缩响应的所有块。我还在GZipOutputStream周围放了一个包装器。这是我从谷歌搜索到的包装。

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 :(得分:1)

我的理解是你需要“整个”文件才能压缩它。您可以将其发送到块将其压缩发送出去。 mod_gzip_dechunk选项似乎不再存在 - 请参阅mod_deflate documentation