Werkzeug: 分块请求仍然不起作用

创建于 2017-07-16  ·  4评论  ·  资料来源: pallets/werkzeug

(更新,因为我意识到我一直在尝试解决这个问题,所以对原来的问题和让我放弃的问题感到困惑)

我正在向使用 Werkzeug(当前 git master)的应用程序发出分块请求。 get_input_stream 最终调用LimitedStream(wsgi.input, min(content_length, max_content_length)) 。 如果使用分块编码, min(content_length, max_content_length)将始终为 None。

为了取得进展,我尝试使用LimitedStream(stream, content_length or max_content_length) ,但最终我得到了ClientDisconnected异常,因为我们无法区分客户端断开连接和分块请求只是完成,因为wsgi.input.read()在这两种情况下都只返回一个长度为 0 的字符串。

最有用的评论

哪个 wsgi 目前支持input_terminated ? 在调试为什么数据为空,然后为什么流为空然后意识到这是由于分块流编码而燃烧一整天之后,我现在找不到任何支持这个的东西:/

所有4条评论

这不仅仅是min的简单错误。 解决这个问题后,问题是如果要读取的内容少于max_content_length ,则使用 Werkzeug 执行wsgi.input.read(max_content_length)永远阻塞。 或者使用 Gunicorn,它通过解析和缓冲整个消息来支持块,长度小于max_content_length ,因此LimitedStream认为客户端断开连接。

我在 Django 上对此进行了测试,以确保我们没有做一些奇怪的事情,它也看到了一个空流。

最简单的方法是提供一个设置environ['wsgi.input_terminated']的中间件,并告诉人们在使用支持分块传输的服务器时使用它。

哪个 wsgi 目前支持input_terminated ? 在调试为什么数据为空,然后为什么流为空然后意识到这是由于分块流编码而燃烧一整天之后,我现在找不到任何支持这个的东西:/

除了检查environ.get('wsgi.input_terminated') ,我们还应该检查environ.get('HTTP_TRANSFER_ENCODING') == 'chunked'并且在这种情况下还直接返回解包的流吗? 这解决了诸如简单的curl -H 'Transfer-Encoding: chunked' ...返回空流之类的问题。

根据RFC2616

4.4.2
如果存在 Transfer-Encoding 标头字段(第 14.41 节)并且
具有除“身份”以外的任何值,则传输长度为
通过使用“分块”传输编码(第 3.6 节)定义,
除非通过关闭连接来终止消息。

4.4.3
如果存在 Content-Length 头字段(第 14.13 节),则其
OCTET 中的十进制值表示实体长度和
传输长度。 不得发送 Content-Length 头字段
如果这两个长度不同(即,如果传输编码
头字段存在)。 如果收到的消息同时包含
Transfer-Encoding 头域和 Content-Length 头域,
后者必须被忽略。

...注意到Transfer-Encodingchunked要求忽略任何Content-Length标头,因此不应基于它进行流处理。 除非设置了wsgi.input_terminated否则当前就是这种情况。

是否真的有必要设置wsgi.input_terminated以便正常的分块编码(例如 10 字节 JSON 有效负载)工作?

此页面是否有帮助?
0 / 5 - 0 等级