处理请求数据

关于Web开发最重要的规则是“不要信任用户”。这对于输入流上的传入请求数据尤其适用。对于WSGI,这实际上比您预期的要难一些。正因为如此,Werkzeug将请求流包装起来,让您从最突出的问题中解脱出来。

输入流上缺少EOF标记

输入流没有文件结束标记。如果您要调用 read() 方法的基础上。 wsgi.input 流,则会导致应用程序挂起在符合要求的服务器上。这实际上是故意的,无论多么痛苦。Werkzeug通过将输入流包装在特殊的 LimitedStream 。输入流在请求对象上公开为 stream 。这要么是空流(如果表单数据已解析),要么是包含输入流内容的限制流。

Werkzeug什么时候分析?

Werkzeug在以下情况下解析传入数据:

  • 您可以访问以下任一项 formfiles ,或 stream 请求方法是 POSTPUT

  • 如果你打电话 parse_form_data() .

这些电话不能互换。如果你调用 parse_form_data() 您不能使用请求对象,或者至少不能使用触发解析过程的属性。

如果你读到 wsgi.input 分析前的流。

一般规则: 不要使用wsgi输入流。尤其是在WSGI中间商中。使用解析函数或请求对象。不要将多个WSGI实用程序库混用在表单数据分析或输入流上工作的任何其他工具中。

它是如何解析的?

标准的werkzeug解析行为处理三种情况:

  • 输入内容类型为 multipart/form-data 。在这种情况下, stream 将为空,并且 form 将包含常规的 POST / PUT 数据, files 将包含上载的文件,格式为 FileStorage 对象。

  • 输入内容类型为 application/x-www-form-urlencoded 。然后是 stream 将为空,并且 form 将包含常规的 POST / PUT 数据和 files 都会是空的。

  • 输入内容类型既不是这两种类型, stream 指向一个 LimitedStream 以及用于进一步处理的输入数据。

关于 get_data 方法:调用此方法会将完整的请求数据加载到内存中。只有在以下情况下才能安全地执行此操作 max_content_length 已经设置好了。你也可以 或者 读取流 or 打电话 get_data()

限制请求数据

这个 Request 类提供了几个属性来控制从请求正文处理多少数据。这可以帮助减轻DoS攻击,这种攻击手工创建请求的方式使服务器使用过多的资源来处理它。这些限制中的每个都将引发 RequestEntityTooLarge 如果超过了这些限制。

  • max_content_length 在此字节数之后停止读取请求数据。最好在WSGI服务器或HTTP服务器中进行配置,而不是在WSGI应用程序中进行配置。

  • max_form_memory_size 如果任何表单部分大于此字节数,则停止读取请求数据。虽然可以将文件部分移动到磁盘,但常规表单域数据仅存储在内存中。

  • max_form_parts 如果以多部件形式数据发送的部件数量超过此数量,则停止读取请求数据。这对于停止大量非常小的零件,尤其是文件零件非常有用。默认值为1000。

使用Werkzeug设置这些限制只是一层保护。WSGI服务器和HTTPS服务器应该设置自己的大小和超时限制。操作系统或容器管理器应设置服务器进程的内存和处理时间限制。

如果在读取整个请求之前返回413内容太大错误,客户端可能会显示“Connection Reset”(连接重置)失败,而不是413错误。这是基于WSGI/HTTP服务器和客户端处理连接的方式,而不是WSGI应用程序(Werkzeug)所能控制的。

如何扩展解析?

现代网络应用程序传输的远不止多部分表单数据或URL编码数据。要扩展功能,子类 RequestRequest 并添加或扩展方法。