Apache发送Transfer-Encoding:启用deflate模块时chunked

时间:2015-05-20 21:17:42

标签: python apache wsgi

我有一个简单的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

deflate is turn on

当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

deflate is turn off

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

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

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

启用deflate模块后如何设置内容长度?而且我不想在python中使用gzip内容。

1 个答案:

答案 0 :(得分:0)

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

如果您不希望为整个站点启用mod_deflate,则只能通过在Location块中对其进行范围设定来为某些URL前缀启用它。