PHP download large file randomly breaks

Last two days, I was trying to make a PHP page to support large file downloading. It’s supposed to be fairly easy because PHP sample code is everywhere.

	
if (file_exists($file) && is_file($file)) 
{
    set_time_limit(0);
    //write HTTP header
    header('Cache-control: private');
    header('Content-Type: application/octet-stream');
    header('Content-Length: '.filesize($file));
    header('Content-Disposition: filename='.basename($file));
    $handle = fopen($file, 'rb');
    while (!feof($handle)) 
    {
        //limited to 256kb/s
        print(fread($handle, 256 * 1024));
        // flush the content to the browser
        flush();
        // sleep one second
        sleep(1);
        if(connection_status() != 0 || connection_aborted()) 
        {
            break;
        }
    }
    fclose($handle);
    exit;
}

However, a small issue causes a big trouble. For unknown reason, HTTP downloading interrupts and breaks randomly, and I couldn’t download the entire file. I checked the PHP code and changed the PHP.ini, but still couldn’t solve the problem. After hours and hours digging, I found this page, https://www.lacisoft.com/blog/2012/01/21/php-download-script-for-big-files/, which magically solves the issue and saves me heaps.

it is :  ob_end_clean();

Here is the final code:

	
if (file_exists($file) && is_file($file)) 
{
    set_time_limit(0);
    //write HTTP header
    header('Cache-control: private');
    header('Content-Type: application/octet-stream');
    header('Content-Length: '.filesize($file));
    header('Content-Disposition: filename='.basename($file));
    //!!!very important!!!
    ob_end_clean();
    $handle = fopen($file, 'rb');
    while (!feof($handle)) 
    {
        //limited to 256kb/s
        print(fread($handle, 256 * 1024));
        // flush the content to the browser
        flush();
        // sleep one second
        sleep(1);
        if(connection_status() != 0 || connection_aborted()) 
        {
            break;
        }
    }
    fclose($handle);
    exit;
}

I read the PHP manual about this function, and guess it could be PHP out buffering overflow or underflow causes the  break issue. If you are facing the similar issue, I hope this can help you as well.

Create your personalized web signature

Some website, eg http://www.danasoft.com/, provides customized signature that shows the ip address, the ISP, the OS and browser. You also can DIY your own with your style.

This article is for anyone who has basic network knowledge and is interested in DIY and it will guide you from start to finish so you get the full picture.

  1. Apply a free web hosting with PHP supported
  2. Download GeoIP.dat, geoip.inc and client.inc to your local drive
  3. Create and save ip.php as shown below
  4. Upload ip.php, GeoIP.dat, geoip.inc and client.inc to your new web space
  5. Open your browser and type “http://somespace.somespace/ip.php