对于我们的WebService,我编写了一些逻辑来防止
multipart/form-data
大于,比如说,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.
来自Google Chrome
-
The connection to the server was reset while the page was loading.
来自Firefox
使用python内置时也会出现相同的错误
wsgiref
HTTP服务器。
事实:一旦我添加
environ['wsgi.input'].read()
在用HTTP 400响应之前,连接重置问题就消失了。当然,这不是一个好办法。它只显示当您完全使用输入时会发生什么。
我仔细阅读
HTTP: The Definitive Guide
并且发现了一些有趣的指导方针,说明在实现HTTP服务器和客户机时如何小心管理TCP连接是很重要的。它是关于如何,而不是
close
-在插座上,最好这样做。
shutdown
使客户机有机会作出反应,停止向服务器发送更多数据。
也许我遗漏了一些防止这种连接重置的关键实现细节。洞察任何人?
见
the gist.