对于我们的网络服务,我编写了一些逻辑来防止multipart/form-data
POST 大于 4mb。
它归结为以下内容(我已经剥离了所有 WebOb 的使用,只是将其简化为普通的 WSGI 代码):
import paste.httpserver
form = """\
<html>
<body>
<form method="post" enctype="multipart/form-data" action="/">
<input type="file" name="photopicker" />
<input type="submit" />
</form>
</body>
</html>
"""
limit = 4 * 1024 * 1024
def upload_app(environ, start_response):
if environ['REQUEST_METHOD'] == 'POST':
if int(environ.get('CONTENT_LENGTH', '0')) > limit:
start_response('400 Ouch', [('content-type', 'text/plain')])
return ["Upload is too big!"]
# elided: consume the file appropriately
start_response('200 OK', [('content-type', 'text/html')])
return [form]
paste.httpserver.serve(upload_app, port=7007)
显示的逻辑在单元测试时工作正常。但当我尝试将大于 4mb 的实际文件发送到此端点时,我在客户端收到如下错误:
-
Error 101 (net::ERR_CONNECTION_RESET): Unknown error.
来自谷歌浏览器
-
The connection to the server was reset while the page was loading.
来自火狐
使用Python内置时也会出现同样的错误wsgiref
HTTP 服务器。
事实:一旦我添加environ['wsgi.input'].read()
就在使用 HTTP 400 进行响应之前,连接重置问题消失了。当然,这不是一个好的解决办法。它只是显示当您完全消耗输入时会发生什么。
我读过HTTP:权威指南 http://oreilly.com/catalog/9781565925090并发现了一些有趣的指南,说明在实现 HTTP 服务器和客户端时仔细管理 TCP 连接的重要性。它继续讨论如何,而不是close
-ing 套接字,最好这样做shutdown
,以便客户端有机会做出反应并停止向服务器发送更多数据。
也许我遗漏了一些阻止此类连接重置的关键实现细节。有人有见解吗?
See 要旨。 http://gist.github.com/281530