サーバーにファイルをアップロードするときに、Web ブラウザーは http ヘッダーでファイル サイズを送信しますか? その場合、アップロードプロセス全体が完了するのを待たずに、ヘッダーを読み取るだけでファイルを拒否することは可能ですか?
3 に答える
http://www.faqs.org/rfcs/rfc1867.html
HTTP クライアントは、提案されたファイル データが大きすぎて適切に処理できないかどうかをビジー状態のサーバーが検出できるように、ファイル入力全体に対して content-length を指定することをお勧めします。
ただし、コンテンツの長さは必須ではないため、信頼することはできません。また、攻撃者は間違ったコンテンツ長を偽造する可能性があります。
ファイルの内容を読み取ることが唯一の信頼できる方法です。そうは言っても、コンテンツの長さが存在し、大きすぎる場合は、接続を閉じるのが合理的です。
また、コンテンツはマルチパートとして送信されるため、最新のフレームワークのほとんどは最初にデコードします。つまり、フレームワークが完了するまでファイル バイト ストリームを取得できないということです。これは、「ファイル全体がアップロードされるまで」という意味になる可能性があります。
編集: やりすぎる前に、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など、フォームにレンダリングします。ファイル フィールドをリセットするか、フォームを無効にするかは、あなた次第です。他のファイル フィールドを再度有効にすることを忘れないでください。
かなり面倒ですよね?あなたの誰かがより良い代替手段を持っているなら、私はすべて耳にします。
よくわかりませんが、ユーザーが偽造する可能性があるため、ヘッダーで送信されたものを本当に信頼するべきではありません。
サーバーの仕組みによって異なります。たとえば PHP では、ファイルのアップロードが完了するまでスクリプトは実行されないため、これは不可能です。