13

サーバーにファイルをアップロードするときに、Web ブラウザーは http ヘッダーでファイル サイズを送信しますか? その場合、アップロードプロセス全体が完了するのを待たずに、ヘッダーを読み取るだけでファイルを拒否することは可能ですか?

4

3 に答える 3

13

http://www.faqs.org/rfcs/rfc1867.html

HTTP クライアントは、提案されたファイル データが大きすぎて適切に処理できないかどうかをビジー状態のサーバーが検出できるように、ファイル入力全体に対して content-length を指定することをお勧めします。

ただし、コンテンツの長さは必須ではないため、信頼することはできません。また、攻撃者は間違ったコンテンツ長を偽造する可能性があります。

ファイルの内容を読み取ることが唯一の信頼できる方法です。そうは言っても、コンテンツの長さが存在し、大きすぎる場合は、接続を閉じるのが合理的です。

また、コンテンツはマルチパートとして送信されるため、最新のフレームワークのほとんどは最初にデコードします。つまり、フレームワークが完了するまでファイル バイト ストリームを取得できないということです。これは、「ファイル全体がアップロードされるまで」という意味になる可能性があります。

于 2008-11-11T11:54:46.957 に答える
2

編集: やりすぎる前に、apache の構成に依存するこの他の回答を確認することをお勧めします: Using jQuery, Restricting File Size Before Uploading。以下の説明は、さらにカスタム フィードバックが本当に必要な場合にのみ役立ちます。

はい、ファイル全体のアップロードを許可する前に、事前にいくつかの情報を取得できます。

enctype="multipart/form-data"属性を持つフォームからのヘッダーの例を次に示します。

POST / HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.7,fr-be;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------886261531333586100294758961
Content-Length: 135361

-----------------------------886261531333586100294758961
Content-Disposition: form-data; name=""; filename="IMG_1132.jpg"
Content-Type: image/jpeg

(data starts here and ends with -----------------------------886261531333586100294758961 )

ヘッダーに Content-Length があり、さらにファイル パーツのヘッダーに Content-Type があります (各ファイルには、マルチパート エンコーディングの目的である独自のヘッダーがあります)。ファイル タイプを推測して関連する Content-Type を設定するのはブラウザの責任であることに注意してください。それを保証することはできませんが、早期の拒否についてはかなり信頼できるはずです (ただし、ファイルが完全に利用可能になったら、ファイル全体を確認することをお勧めします)。

さて、落とし穴があります。サイズではなく content-type で、そのような画像ファイルをフィルタリングしていました。しかし、できるだけ早くリクエストを停止したい場合は、同じ問題が発生します。フォームのコンテンツとアップロードされたファイルを含むリクエスト全体が送信された場合にのみ、ブラウザは応答を取得します

提供されたコンテンツが不要でアップロードを停止する場合は、ソケットを残酷に閉じるしかありません。ユーザーには、紛らわしい「接続がピアによってリセットされました」というメッセージが表示されるだけです。それはひどいですが、それは設計によるものです。

したがって、バックグラウンドで非同期チェックを行う場合にのみ、このメソッドを使用する必要があります (ファイル フィールドをチェックするタイマーを使用)。だから私はそのハックを持っていました:

  • jqueryを使用して、ファイルフィールドが変更されたかどうかを教えてくれます
  • 新しいファイルが選択されたら、同じフォームの他のすべてのファイル フィールドを無効にして、そのファイルのみを取得します。
  • ファイルを非同期で送信します (jQuery で実行できます。隠しフレームを使用します)。
  • サーバー側で、ヘッダー ( content-length 、 content-type など) を確認し、必要なものが得られたらすぐに接続を切断します。
  • そのファイルが正常かどうかを示すセッション変数を設定します。
  • クライアント側では、ファイルがフレームにアップロードされるため、接続が閉じられている場合でも、フィードバックは一切得られません。あなたの唯一の選択肢はタイマーです。
  • クライアント側では、タイマーがサーバーをポーリングして、アップロードされたファイルのステータスを取得します。サーバー側では、そのセッション変数を設定して、ブラウザに送り返します。
  • クライアントのステータス コードは です。エラーメッセージ、緑のチェックマーク/赤のXなど、フォームにレンダリングします。ファイル フィールドをリセットするか、フォームを無効にするかは、あなた次第です。他のファイル フィールドを再度有効にすることを忘れないでください。

かなり面倒ですよね?あなたの誰かがより良い代替手段を持っているなら、私はすべて耳にします。

于 2008-11-11T12:22:55.993 に答える
1
  1. よくわかりませんが、ユーザーが偽造する可能性があるため、ヘッダーで送信されたものを本当に信頼するべきではありません。

  2. サーバーの仕組みによって異なります。たとえば PHP では、ファイルのアップロードが完了するまでスクリプトは実行されないため、これは不可能です。

于 2008-11-11T11:49:25.920 に答える