大規模ファイルアップロード時のブラウザ対応状況私的まとめ
送信先は、apache 2.2.3 / mod_uploader 3.1.0。 クライアント環境は WinXP x64 SP2。
各ファイル送信時、ブラウザがどんなヘッダーをPOSTしてるのか調査しました。主に Content-Length の調査。正しいファイルサイズ(正確には、正しいリクエストボディサイズ)が送信できているかを確認。
ブラウザ | 2GB超 | 4GB超 |
---|---|---|
IE6 (32bit) | ×Content-Length がマイナスになる | ×Content-Length が小さくなる。実際のファイルサイズの下位32bitっぽい値になる |
IE6 (64bit) | ×Content-Length がマイナスになる | ×Content-Length が小さくなる。実際のファイルサイズの下位32bitっぽい値になる |
Firefox 14.0.1 | ×Content-Length がマイナスになる | ×Content-Length が極端に小さくなる(?) |
Opera 12.0 | ○アップロード可能。Content-Length正常値 | ×ファイルの中身が空(0Byte)の multipart/form-data のデータが送信される様子 |
Chrome 20.0 | ○アップロード可能。Content-Length正常値 | ○アップロード可能。Content-Length正常値 |
2GB超/4GB超の大規模ファイルをアップロードしたい際は Chrome が安定かも。 Opera も 2GB超えを扱えますが、送信ボタン押した際に30秒ぐらい固まります。
なお、以下(私が把握出来ている)注意点
- サーバー側も正しく Content-Length を解釈できないとアカンでー。 apache 2.2 から 4GB だか 2GB だか以上のファイルを扱えるようになったらしいので、apache 2.0 とかだと無理かも。(ココの「大ファイルサポート」に該当? 64bit なら apache 2.0 でもOKなんかな…詳細は不明。)
- スクリプト言語系でアップロード処理する場合、すごいパフォーマンスが悪化するかも。php とか → 一旦メモリに 2GB のファイルをおいてから処理開始ー って処理だと、相当メモリ積んでないと鯖が swap しまくりに。
- 鯖アプリが 32bit プロセスだとメモリ確保に失敗してヤバイ事になりそう。
- つまるところ、不特定多数を相手にする場合、DoS攻撃(というか自爆)が容易に出来ちゃう環境になるのでヤバイ。皆が一斉にアップロードしはじめると容易に落ちそう。
- ってか、GB単位を http で upload とかバカじゃねーの!
以下ブラウザが送信したヘッダー情報
IE6 (32bit) - 2.82GB 送信時
POST http://example.jp/uploader/upload//3000737340 HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */* Referer: http://example.jp/uploader/ Accept-Language: ja Content-Type: multipart/form-data; boundary=---------------------------7dc2020206ae UA-CPU: x86 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; WOW64; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E) Host: example.jp Content-Length: -126138086 Proxy-Connection: Keep-Alive Pragma: no-cache Cookie: __utma=228853188.850377578.1316378493.1316378493.1316378493.1
負の値
IE6 (32bit) - 4.3GB 送信時
POST http://example.jp/uploader/upload//2195712367 HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*s Referer: http://example.jp/uploader/ Accept-Language: ja Content-Type: multipart/form-data; boundary=---------------------------7dc222c10542 UA-CPU: x86 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; WOW64; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E) Host: example.jp Content-Length: 338387945 Connection: Keep-Alive Pragma: no-cache Cookie: __utma=228853188.850377578.1316378493.1316378493.1316378493.1
322.71MB になってる
IE6 (64bit) - 2.82GB 送信時
POST http://example.jp/uploader/upload//2370704091 HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, */* Referer: http://example.jp/uploader/ Accept-Language: ja Content-Type: multipart/form-data; boundary=---------------------------7dc37b6205ec UA-CPU: AMD64 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; Win64; x64; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E) Host: example.jp Content-Length: -126138086 Proxy-Connection: Keep-Alive Pragma: no-cache Cookie: __utma=228853188.850377578.1316378493.1316378493.1316378493.1
負の値
IE6 (64bit) - 4.3GB 送信時
POST http://example.jp/uploader/upload//4083968936 HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, */* Referer: http://example.jp/uploader/ Accept-Language: ja Content-Type: multipart/form-data; boundary=---------------------------7dc3b92920544 UA-CPU: AMD64 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; Win64; x64; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E) Host: example.jp Content-Length: 338387952 Connection: Keep-Alive Pragma: no-cache Cookie: __utma=228853188.850377578.1316378493.1316378493.1316378493.1
322.71MB になってる
Firefox 14.0.1 - 2.82GB 送信時
POST http://example.jp/uploader/upload//3253414070 HTTP/1.1 Host: example.jp User-Agent: Mozilla/5.0 (Windows NT 5.2; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Proxy-Connection: keep-alive Referer: http://example.jp/uploader/ Cookie: __utma=228853188.280221657.1314556159.1331915237.1334759080.7; __utmz=228853188.1334759080.7.6.utmccn=(referral)|utmcsr=google.co.jp|utmcct=/imgres|utmcmd=referral Content-Type: multipart/form-data; boundary=---------------------------26418279386900 Content-Length: -1261380876
負の値
Firefox 14.0.1 - 4.3GB 送信時
POST http://example.jp/uploader/upload//2029255848 HTTP/1.1 Host: example.jp User-Agent: Mozilla/5.0 (Windows NT 5.2; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Connection: keep-alive Referer: http://example.jp/uploader/ Cookie: __utma=228853188.280221657.1314556159.1331915237.1334759080.7; __utmz=228853188.1334759080.7.6.utmccn=(referral)|utmcsr=google.co.jp|utmcct=/imgres|utmcmd=referral Content-Type: multipart/form-data; boundary=---------------------------762748024099 Content-Length: 702 -----------------------------762748024099 Content-Disposition: form-data; name="file"; filename="kanaria.rar" Content-Type: application/x-rar-compressed Rar!??s?? ????????t??`??????????+?|4?@03? ???????????en_windows_7_ultimate_with_sp1_x64_dvd_u_677332.iso??*?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
リクエストボディ付。 "?" はファイルのバイナリで化けてます。 …でまぁ、このボディだけだと 695byte だったりはします^^; なんかの文字のコピペに失敗したのかも…? …とはいえ、他にパラメータ4つぐらいあるハズなんだけどなぁ… 後にパケットが続いたとしても、残り7byteで表現できないしなぁ…
→ やっぱり挙動が怪しい気がする(ぉ
Opera 12.0 - 2.82GB 送信時
POST /uploader/upload//3493308023 HTTP/1.1 User-Agent: Opera/9.80 (Windows NT 5.2; WOW64; U; ja) Presto/2.10.289 Version/12.00 Host: example.jp Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 Accept-Language: ja-JP,ja;q=0.9,en;q=0.8 Accept-Encoding: gzip, deflate Referer: http://example.jp/uploader/ Connection: Keep-Alive Content-Length: 3033586364 Content-Type: multipart/form-data; boundary=----------kc1nYkz5CKzz7QbXlR4OqI
OK
Opera 12.0 - 4.3GB 送信時
POST /uploader/upload//3639104731 HTTP/1.1 User-Agent: Opera/9.80 (Windows NT 5.2; WOW64; U; ja) Presto/2.10.289 Version/12.00 Host: example.jp Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 Accept-Language: ja-JP,ja;q=0.9,en;q=0.8 Accept-Encoding: gzip, deflate Referer: http://example.jp/uploader/ Connection: Keep-Alive Content-Length: 654 Content-Type: multipart/form-data; boundary=----------0jwScDP2ld1qKmPGYDytPJ ------------0jwScDP2ld1qKmPGYDytPJ Content-Disposition: form-data; name="file"; filename="kanaria.rar" Content-Type: application/x-rar-compressed ------------0jwScDP2ld1qKmPGYDytPJ Content-Disposition: form-data; name="comment" iso ------------0jwScDP2ld1qKmPGYDytPJ Content-Disposition: form-data; name="download_pass" ------------0jwScDP2ld1qKmPGYDytPJ Content-Disposition: form-data; name="remove_pass" test ------------0jwScDP2ld1qKmPGYDytPJ Content-Disposition: form-data; name="code_pat" ------------0jwScDP2ld1qKmPGYDytPJ Content-Disposition: form-data; name="submit" ------------0jwScDP2ld1qKmPGYDytPJ--
リクエストボディ付。 ファイルの中身が空っぽです。
Chrome 20.0 - 2.82GB 送信時
POST /uploader/upload//3823057925 HTTP/1.1 Host: example.jp Connection: keep-alive Content-Length: 3033586398 Cache-Control: max-age=0 Origin: http://example.jp User-Agent: Mozilla/5.0 (Windows NT 5.2; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvAM37gHVlSQEpjjA Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Referer: http://example.jp/uploader/ Accept-Encoding: gzip,deflate,sdch Accept-Language: ja,en-US;q=0.8,en;q=0.6 Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.3
OK
Chrome 20.0 - 4.3GB 送信時
POST /uploader/upload//1038647563 HTTP/1.1 Host: example.jp Connection: keep-alive Content-Length: 4633355231 Cache-Control: max-age=0 Origin: http://example.jp User-Agent: Mozilla/5.0 (Windows NT 5.2; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryUbRDMovTgufJzVRM Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Referer: http://example.jp/uploader/ Accept-Encoding: gzip,deflate,sdch Accept-Language: ja,en-US;q=0.8,en;q=0.6 Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.3
OK
おまけ
http パケット解析に Fiddler2 を利用していたのですが、この子 2GB 以上のリクエストには対応していない様子。 ってか .NET が制約持ってる感じ?
↓こんなエラーダイアログが出ちゃいました
Fiddler has encountered an unexpected problem. If you believe this is a bug in Fiddler, please copy this message by hitting CTRL+C, and submit a bug report using the Help | Send Feedback menu. Sorry, the .NET Framework (and Fiddler) cannot handle streams larger than 2 Gigabytes. Type: System.Exception Source: Fiddler 場所 Fiddler.PipeReadBuffer.Write(Byte[] buffer, Int32 offset, Int32 count) 場所 Fiddler.ClientChatter.ReadRequest() 場所 Fiddler.Session._executeObtainRequest() 場所 Fiddler.Session.InnerExecute() 場所 Fiddler.Session.Execute(Object objThreadState)