代码之家  ›  专栏  ›  技术社区  ›  Pavel Repin

当wsgi应用程序在使用environn之前响应时会发生TCP连接重置['wsgi.input']

  •  3
  • Pavel Repin  · 技术社区  · 14 年前

    对于我们的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.

    1 回复  |  直到 14 年前
        1
  •  0
  •   Omnifarious    14 年前

    发生这种情况是因为您丢弃了输入流而没有读取它,这将强制关闭它。浏览器已经将要发送的文件的一部分排队,然后由于服务器强制关闭连接,它会收到一个写错误。

    如果不阅读所有的输入,我就不可能了解这一点。

    在发送文件之前,我建议使用一些javascript来测试文件的大小。然后,只有那些因为没有javascript或故意试图恶意而忽略客户端检查的人才会得到错误。

    推荐文章