【问题标题】:Apache sending Transfer-Encoding: chunked when deflate module is enabledApache发送Transfer-Encoding:启用deflate模块时分块
【发布时间】:2015-05-20 21:17:42
【问题描述】:

我有一个简单的 web.py 代码,如下所示,在 apache 中使用 mod_wsgi 部署。

import web

urls = (
    '/', 'index'
)

class index:
    def GET(self):
        content = 'hello'
        web.header('Content-length', len(content))
        return content

app = web.application(urls, globals())
application = app.wsgifunc()

这个网站运行良好,除了一个小问题。当 mod_deflate 开启时,响应被分块,即使响应体很小。

响应头

HTTP/1.1 200 OK
Date: Wed, 20 May 2015 20:14:12 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html

当 mod_deflate 关闭时,Content-Length 标头返回。

HTTP/1.1 200 OK
Date: Wed, 20 May 2015 20:30:09 GMT
Server: Apache/2.4.7 (Ubuntu)
Content-Length: 5
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8

我四处搜索,有人说减少 DeflateBufferSize 会有所帮助,但是这个响应的大小只有 5,远离它的默认值:8096,所以我认为它不会干扰这个问题。

有人说 apache 发送分块响应是因为它在开始向客户端发送响应之前不知道响应的大小,但是在我的代码中,我确实设置了 Content-Length。

我也尝试过Flask 和 Apache/2.2.15 (CentOS),结果相同。

启用 deflate 模块时如何设置内容长度?而且我不喜欢在 python 中压缩内容。

【问题讨论】:

    标签: python apache wsgi


    【解决方案1】:

    响应Content-Length 必须反映压缩完成后发送的数据的最终长度,而不是原始长度。因此 mod_deflate 必须删除原始的 Content-Length 标头并使用分块传输编码。在发送压缩数据之前,它可以知道能够发送Content-Length 的内容长度的唯一方法是将完整的压缩响应缓冲在内存中或文件中,然后计算长度。缓冲所有压缩内容是不切实际的,并且在一定程度上破坏了在响应流式传输时压缩数据的意义。

    如果您不希望为整个站点启用 mod_deflate,则只需在 Location 块内限定某些 URL 前缀即可启用它。

    【讨论】:

      猜你喜欢
      • 2019-01-13
      • 2010-12-12
      • 2012-10-06
      • 2015-09-04
      • 1970-01-01
      • 2011-02-05
      • 2018-07-20
      • 2014-11-02
      • 2010-10-27
      相关资源
      最近更新 更多