【问题标题】:Django with mod_wsgi and gzip带有 mod_wsgi 和 gzip 的 Django
【发布时间】:2014-03-24 07:30:06
【问题描述】:

我使用 Django 作为休息服务器。我想得到一个包含我应该解析的 JSON 的 POST。客户端是对请求进行 gzip 压缩的 Salesforce 服务器。

为了让请求膨胀,我在 VHost 中使用它: SetInputFilter DEFLATE

几乎一切看起来都很好,但是当我阅读 request.body 或 request.read(16000) 时 - 输入非常小 - 我总是看到响应断断续续(缺少 5 个字符)。

有什么建议从哪里开始调试?

【问题讨论】:

    标签: python django gzip mod-wsgi


    【解决方案1】:

    从技术上讲,WSGI 规范不支持将输入过滤器作为中间件进行变异的概念,甚至在底层 Web 服务器中也不支持。

    具体问题是修改输入过滤器会改变请求内容的数量,但不会改变 WSGI 环境字典中的 CONTENT_LENGTH 值。

    WSGI 规范说有效的 WSGI 应用程序只允许从请求内容中读取 CONTENT_LENGTH 个字节。因此,在压缩请求内容的情况下,最终请求大小最终会大于 CONTENT_LENGTH 指定的大小,Web 框架可能会在读取所有数据之前截断请求输入。

    您可以在以下位置找到有关此问题的一些详细信息:

    尽管规范中的更改被推动,但什么也没发生。

    要解决这个问题,你需要做的是实现一个 WSGI 中间件,你可以将它包裹在 Django 应用程序周围,如果它通过传递的标头检测到原始内容已被压缩,但是你在哪里知道 Apache 解压缩它,会读取所有请求内容,直到它到达流标记的末尾,忽略 CONTENT_LENGTH,甚至在将请求传递给 Django 之前。完成后,它可以更改 CONTENT_LENGTH 并将 wsgi.input 替换为替换流,然后返回已读取的内容。

    由于内容可能非常大且大小未知,因此将其全部读入内存不一定是个好主意。因此,您可能希望一次读取一个块并将其写入临时文件。然后 wsgi.input 将替换为临时文件上的打开文件句柄,并将 CONTENT_LENGTH 替换为文件的最终大小。

    如果您在 Google Groups 上的 mod_wsgi 档案中正确搜索,您应该会找到有关此内容的先前讨论,甚至可能还有一些示例代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      • 2012-04-30
      • 2018-05-31
      • 1970-01-01
      • 2014-06-29
      • 1970-01-01
      相关资源
      最近更新 更多