4

multipart/form-data私たちの Web サービスでは、たとえば 4 MB を超える POSTを防ぐためのロジックを書きました。

要約すると、次のようになります (すべての 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)

示されているロジックは、単体テスト時に正しく機能します。しかし、4 MB を超える実際のファイルをこのエンドポイントに送信しようとするとすぐに、クライアント側で次のようなエラーが発生しました。

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

wsgirefPython 組み込みHTTP サーバーを使用すると、同じエラーが発生します。

事実: environ['wsgi.input'].read()HTTP 400 で応答する直前に追加すると、接続のリセットの問題はなくなりました。もちろん、これは良い修正ではありません。入力を完全に消費するとどうなるかを示しているだけです。

私はHTTP: The Definitive Guideを熟読し、HTTP サーバーとクライアントを実装する際に TCP 接続を慎重に管理することが重要であるという興味深いガイドラインを見つけました。クライアントが反応してサーバーへのデータの送信を停止する機会が得られるように、closeソケットを -ingする代わりにを実行することをお勧めしました。shutdown

おそらく、このような接続のリセットを防ぐ重要な実装の詳細が欠けているのでしょう。インサイト誰か?

あらすじを参照してください。

4

1 に答える 1

2

これは、入力ストリームを読み取らずに破棄し、強制的に閉じているために発生しています。ブラウザーは、送信するファイルのかなりの部分を既にキューに入れているため、サーバーが強制的に接続を閉じるため、書き込みエラーが発生します。

すべての入力を読まなければ、私が知っているこれを回避する方法はありません。

ファイルを送信する前に、ファイルのサイズをテストする Javascript をお勧めします。次に、エラーが発生するのは、Javascript を持っていないか、意図的に悪意を持っているためにクライアント側のチェックを無視している人々だけです。

于 2010-01-20T08:11:07.493 に答える