Сброс TCP-соединения происходит, когда приложение WSGI отвечает перед использованием среды ['wsgi.input'] - PullRequest
3 голосов
/ 20 января 2010

Для нашего веб-сервиса я написал некоторую логику, чтобы предотвратить multipart/form-data POSTs, скажем, больше, чем, например, 4 МБ.

.простой ванильный код 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)

Показанная логика работает правильно при тестировании модуля.Но как только я попытался отправить фактические файлы размером более 4 МБ в эту конечную точку, я получил такие ошибки на стороне клиента:

  • Error 101 (net::ERR_CONNECTION_RESET): Unknown error. из Google Chrome
  • The connection to the server was reset while the page was loading.из Firefox

Та же ошибка возникает при использовании встроенного в Python HTTP-сервера wsgiref.

Факт: после добавления environ['wsgi.input'].read() непосредственно перед ответом HTTP 400 сброс соединенияпроблема ушлаКонечно, это не очень хорошее решение.Он просто показывает, что происходит, когда вы полностью потребляете ввод.

Я просмотрел HTTP: Полное руководство и нашел некоторые интересные рекомендации о том, как важно тщательно управлять TCP-соединениями при реализации HTTP-серверов.и клиенты.Далее говорилось о том, что вместо close -ing сокета было предпочтительнее выполнить shutdown, чтобы у клиента была возможность отреагировать и прекратить отправку дополнительных данных на сервер.

Возможно, я пропустилнекоторые важные детали реализации, которые предотвращают такие сбросы соединения.Кто-нибудь понимает?

См. Суть.

1 Ответ

0 голосов
/ 20 января 2010

Это происходит потому, что вы отбрасываете входной поток, не читая его, и это заставляет его закрыться.Браузер поставил в очередь большую часть файла, который должен быть отправлен, и затем он получает ошибку записи, потому что сервер принудительно закрывает соединение.input.

Я бы порекомендовал немного Javascript для проверки размера файла перед его отправкой.Тогда единственные люди, которые получают ошибку, это те, кто игнорирует проверку на стороне клиента, потому что у них нет Javascript или потому что они целенаправленно пытаются быть вредоносными.

...