2

この投稿は ServerFault ( https://serverfault.com/questions/131156/user-recoming-partial-downloads ) に関する質問として始まりましたが、私たちの php スクリプトが原因であると判断しました。そのため、実際の問題であると私が信じていることについて、ここで更新された質問を発行しています。

私はphpスクリプトを使用してアクセス許可を確認し、Webサイトのユーザーがダウンロードできるようにファイルを提供しています。ほとんどの場合、これは機能しますが、最近、1 人のユーザーがサイズの大きいダウンロードで問題を経験しています。彼は、サイズが 100MB を超えるファイルのダウンロードの最大 80% しか取得していません。また、このスクリプトからのすべてのダウンロードは、ファイルサイズを報告しません。さらに、テストの結果、直接リンクを指定すると (その時点でファイルサイズが報告されます)、同じユーザーが失敗した各ファイルを確実にダウンロードできることが明らかになりました。

ファイルを提供するために使用しているコードの関連スニペットは次のとおりです。

header("Content-type:$contenttype");
$len = filesize($filename);
header("Content-Length: $len");
header("Content-Disposition: attachment; filename=".$title.".".$ext);
readfile($filename);

ここに到達する前に、$contenttype、$filename、$title、および $ext がすべて正しく設定されていることに注意してください。これらはトリプルチェックされています。それらのどれも問題ではありません。また、$len は正しいファイルサイズを提供します。

この問題を調査しているときに、次の投稿に出くわしました: Content-Length ヘッダーは常にゼロです。

私は同じ問題に遭遇しているようです。スクリプトを使用すると、ファイルでチャンク エンコーディングが取得され、コンテンツの長さのサイズが設定されません。大規模なダウンロードで何かがうまくいかず、ファイルの終わりの前に長さゼロのチャンクを取得するようになったのではないかと推測しています。

直接リクエストのヘッダーは次のようになります。

http://www.grinderschool.com/videos/zfff5061b65ae00e8b21/KillsAids021.wmv

GET /videos/zfff5061b65ae00e8b21/KillsAids021.wmv HTTP/1.1
Host: www.grinderschool.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Referer: http://www.grinderschool.com/phpBB3/viewtopic.php?f=14&p=29468
Cookie: style_cookie=printonly; phpbb3_7c544_u=2; phpbb3_7c544_k=44b832912e5f887d; phpbb3_7c544_sid=e8852df42e08cc1b2250300c2897f78f; __utma=174624884.2719561324781918700.1251850714.1270986325.1270989003.575; __utmz=174624884.1264524375.411.12.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=low%20stakes%20poker%20videos; phpbb3_cmviy_k=; phpbb3_cmviy_u=2; phpbb3_cmviy_sid=d8df5c0943863004ca40ef9c392d371d; __utmb=174624884.4.10.1270989003; __utmc=174624884
Pragma: no-cache
Cache-Control: no-cache

HTTP/1.1 200 OK
Date: Sun, 11 Apr 2010 12:57:41 GMT
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8l DAV/2 mod_auth_passthrough/2.1 FrontPage/5.0.2.2635
Last-Modified: Sun, 04 Apr 2010 12:51:06 GMT
Etag: "eb42d6-7d9b843-48368aa6dc280"
Accept-Ranges: bytes
Content-Length: 131708995
Keep-Alive: timeout=10, max=30
Connection: Keep-Alive
Content-Type: video/x-ms-wmv

そして、これが私のスクリプトによって応答されたリクエストのように見えるものです:

http://www.grinderschool.com/download_video_test.php?t=KillsAids021&format=wmv

GET /download_video_test.php?t=KillsAids021&format=wmv HTTP/1.1
Host: www.grinderschool.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: style_cookie=printonly; phpbb3_7c544_u=2; phpbb3_7c544_k=44b832912e5f887d; phpbb3_7c544_sid=e8852df42e08cc1b2250300c2897f78f; __utma=174624884.2719561324781918700.1251850714.1270986325.1270989003.575; __utmz=174624884.1264524375.411.12.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=low%20stakes%20poker%20videos; phpbb3_cmviy_k=; phpbb3_cmviy_u=2; phpbb3_cmviy_sid=d8df5c0943863004ca40ef9c392d371d; __utmb=174624884.4.10.1270989003; __utmc=174624884

HTTP/1.1 200 OK
Date: Sun, 11 Apr 2010 12:58:02 GMT
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8l DAV/2 mod_auth_passthrough/2.1 FrontPage/5.0.2.2635
X-Powered-By: PHP/5.2.11
Content-Disposition: attachment; filename=KillsAids021.wmv
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=10, max=30
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: video/x-ms-wmv

問題は、スクリプトからのダウンロードを適切に機能させるにはどうすればよいかということです。繰り返しますが、99% のユーザーにとってはそのままで機能します (ただし、ファイルサイズが報告されず、ダウンロードにかかる時間の見積もりが計算されないことが今では面倒だと思います)。

4

3 に答える 3

2
Content-Encoding: gzip

うーん。おそらく、PHP のzlib.output_compressionがそれを行っています。(Apache の mod_deflate とは異なります。)

それをオフにして、それがチャンクエンコーディングを強制しているのかどうかを確認してください。既に高度に圧縮されている WMV のようなファイル形式のダウンロードを圧縮したくない場合。

ただし、チャンク エンコーディングは、サイズ レポートの欠如を説明するだけです。ダウンロードは引き続き機能するはずです。タイムアウト (PHP のset_time_limitや Apache Timeoutなど) が発生している可能性はありますか?

于 2010-04-11T14:03:17.133 に答える
2

それはあなたのGZIP圧縮です。コンテンツの長さを指定して圧縮をオンにすると、すべてが台無しになります。スクリプトでオフにしてみてください。

通常、次のようにして有効にします。

ob_start("ob_gzhandler");

...その行をコメントアウトするだけです。それがコードにない場合は、php.ini ファイルまたは apache.conf/conf.d のいずれかに設定がある可能性があります。

お役に立てれば!

于 2010-04-11T14:05:50.717 に答える
0

スクリプトの場合は、readfile() 関数の代わりに、少しずつ読み取りと出力を行う代替関数を使用してみましたか? この背後にある理由は、どこかでメモリ制限に達して失敗した可能性があります。

http://php.net/manual/en/function.readfile.phpから:

function readfile_chunked ($filename) {
  $chunksize = 1*(1024*1024); // how many bytes per chunk
  $buffer = '';
  $handle = fopen($filename, 'rb');
  if ($handle === false) {
    return false;
  }
  while (!feof($handle)) {
    $buffer = fread($handle, $chunksize);
    print $buffer;
  }
  return fclose($handle);
} 

また、できるだけ頻繁に出力をフラッシュするようにしてください。

于 2010-04-11T14:08:05.800 に答える