Working with PHP script files: unreliable downloads?

This post started out as a question from ServerFault ( https://serverfault.com/questions/131156/user-receiving-partial-downloads ), but I figured our PHP script was the culprit. So I am releasing an updated question on what I think is the actual issue.

I am using a php script to check permissions and then serves to upload a file to load my website. Most of the time this works, but recently one user has been having problems with large downloads. It gets ~ 80% downloads for files> 100MB. Also, all downloads from this script do not report file sizes. Also, tests have shown that the same user CAN reliably download each of the failed files if given a direct link (at which point the file size is reported).

Here is the relevant piece of code that we use to serve the file:

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

      

Please note that $ contenttype, $ filename, $ title and $ ext are configured correctly before we move on here. They have been tested three times. None of these are a problem. Additionally, $ len provides the correct file size.

While researching this issue, I came across this post: Content-Length header is always null

It seems that I am facing the same problem. When I use the script, I get the encoded encoding in the file and the content size is not set. I am guessing something is wrong with large downloads that caused it to get a zero length chunk to the end of the file.

Here the headers look like a direct request:

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

      

And this is how they look for the request my script answered:

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

      

So the question is ... what can I do to get it loaded correctly from the script? Again, for 99% of users, it works as it is (although I now find it annoying that no file sizes are reported and therefore no estimate of the time to download).

+2


source to share


3 answers


This is your GZIP compression. When you specify the length of the content, but include compression, it all whimpers. This happened to me several times: try turning it off in your script.

Typically, you include it:

ob_start("ob_gzhandler");

      



... so just comment this line out. If it's not in your code, it might be in your php.ini or apache.conf / conf.d file somewhere.

Hope this helps!

+2


source


Content-Encoding: gzip

      

Hmm. Presumably PHP zlib.output_compression does this. (Not like Apache mod_deflate.)



Try disabling it and see if that forces you to force encoded encoding. You don't want to compress the download of a WMV type file that is already heavily compressed.

However, the coded coding only explains the lack of a size report. The download should still work. Is it possible that you have been hit by a timeout (like PHP set_time_limit or Apache Timeout )?

+2


source


If it's a script, have you tried using a substitute function for the readfile () function that reads and outputs a bit at a time? The reason for this might be that the memory limit has been reached somewhere and it is failing.

From 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);
} 

      

Also, try flushing the output as often as you can.

0


source







All Articles