【问题标题】:How to make Apache mod_deflate and Transfer-encoding : Chunked work together?如何使 Apache mod_deflate 和 Transfer-encoding : Chunked 一起工作?
【发布时间】:2012-01-27 20:34:48
【问题描述】:

我正在尝试在我们的网站上使用 bigpipe 概念。这意味着尝试以块的形式发送响应,而不是将其作为一个整体发送,以便用户感觉该页面很快。我通过在java中的响应对象上使用flushBuffer方法成功地做到了这一点。但是现在当我尝试使用 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开启deflate时的响应头

连接:保持活动状态
内容编码:gzip
内容长度:7916
内容类型:文本/html;字符集=UTF-8
日期:格林威治标准时间 2012 年 1 月 27 日星期五 20:11:11
保活:超时=300,最大值=3997
服务器:阿帕奇
变化:接受编码

在apache中关闭deflate时的响应头

连接:保持活动状态
内容类型:文本/html;字符集=UTF-8
日期:格林威治标准时间 2012 年 1 月 27 日星期五 20:21:14
保活:超时=300,最大值=3997
服务器:Apache/2.2.3 (CentOS)
Transfer-Encoding:chunked

正如您在上面的 2 个标头中看到的那样,只有在关闭压缩的情况下,分块才有效。我在网上搜索这方面的内容,人们建议降低 DeflateBufferSize 值。正如您在我的 apache 配置中看到的那样,我将值减小到 100 字节,但这仍然没有解决问题。 DeflateBufferSize 设置为 100 字节意味着响应在 apache 中被缓冲,直到接收到 100 字节,然后将其压缩。

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

mod_gzip_dechunk 是的

有人知道与 apache 2.x 捆绑在一起的 mod_deflate 中有这样的指令吗?

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

【问题讨论】:

    标签: apache mod-deflate chunked


    【解决方案1】:

    其实我找到了解决办法。我以前每次都创建一个新的 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();
        }
    }
    

    【讨论】:

    • 等等——你在你的应用程序中同时使用了 mod_deflate 和压缩吗?
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2018-09-12
      • 2021-08-18
      • 1970-01-01
      • 1970-01-01
      • 2012-01-11
      • 1970-01-01
      • 1970-01-01
      • 2019-05-15
      相关资源
      最近更新 更多