对于我正在开发的应用程序,用户提交带有多部分表单数据(内容类型:multipart/form-data)的压缩 HTTP POST 请求(内容编码:GZIP)。我使用 mod_deflate 作为输入过滤器来解压缩,并通过 mod_wsgi 在 Django 中处理 Web 请求。
总的来说,一切都很好。但对于某些请求(确定性),从请求到响应几乎有一分钟的延迟。调查显示 django 中的处理立即完成,但服务器的响应停滞。如果请求未经过 GZIP 压缩,则一切正常。
请注意,为了处理 mod_wsgi 中的故障,我将 content-length 设置为未压缩的消息大小。
有人遇到过这个问题吗?有没有办法在 apache 处理响应时轻松调试它?
最佳答案
您认为 mod_wsgi 中存在什么故障?
事情的简单事实是 WSGI 1.0 不支持改变请求内容的内容长度的变异输入过滤器。因此,从技术上讲,在使用 WSGI 1.0 时,您不能在 Apache 中使用 mod_deflate 来获取请求内容。您将内容长度设置为实际大小以外的值很可能会堵塞 mod_deflate 的操作。
如果您希望能够处理压缩请求内容,您需要超越 WSGI 1.0 规范并使用非标准代码。
我建议您阅读:
http://blog.dscpl.com.au/2009/10/details-on-wsgi-10-amendmentsclarificat.html
这解释了这个问题以及有关它的建议。
我强烈建议您将此问题提交给官方 mod_wsgi mailing list讨论如何编写代码。然而,如果您使用的是 Python 框架之一,您的操作可能会受到限制,因为它们将实现 WSGI 1.0,而您则无法执行此操作。
更新1
从mod_wsgi列表的讨论来看,原始的WSGI应用程序应该包装在以下WSGI中间件中。这仅适用于实际上提供空字符串作为输入结束标记的 WSGI 适配器,这是 WSGI 1.0 不需要的。这可能只适用于小型上传,因为所有内容都被读入内存。如果需要大量压缩上传,则应将累积的数据写出到文件中。
class Wrapper(object):
def __init__(self, application):
self.__application = application
def __call__(self, environ, start_response):
if environ.get('HTTP_CONTENT_ENCODING', '') == 'gzip':
buffer = cStringIO.StringIO()
input = environ['wsgi.input']
blksize = 8192
length = 0
data = input.read(blksize)
buffer.write(data)
length += len(data)
while data:
data = input.read(blksize)
buffer.write(data)
length += len(data)
buffer = cStringIO.StringIO(buffer.getvalue())
environ['wsgi.input'] = buffer
environ['CONTENT_LENGTH'] = length
return self.__application(environ, start_response)
application = Wrapper(original_wsgi_application_callable)
关于django - Apache 在响应 gzip 压缩请求时出现滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1559416/