0

Below there is some code extracted from a file browser written in PHP.

Actually the file browsing works and all the rest too but, after a recent Google Chrome update, downloads wouldn't work only on that browser (I've not tested firefox anyway). I've searched elsewhere, but found nothing that could help. The Interesting thing, is that the download works fine in IE, and worked before the recent update on chrome.

Maybe there are some relevant changes in standards that I should know of?

Below the relevant portion of code.

global $_ERROR;
    global $_START_TIME;
    // If user click the download link
    if(isset($_GET['filename']))
    {
        // The directory of downloadable files
        // This directory should be unaccessible from web
        $file_dir="C:/Directory/".$this->location->getDir(false, true, false, 0);

        // Replace the slash and backslash character with empty string
        // The slash and backslash character can be dangerous
        $file_name=str_replace("/", "", $_GET['filename']);
        $file_name=str_replace("\\", "", $file_name);

        // If the requested file exists
        if(file_exists($file_dir.$file_name))
        {
            // Get the file size
            $file_size=filesize($file_dir.$file_name);
            // Open the file
            $fh=fopen($file_dir.$file_name, "r");

            // Download speed in KB/s
            $speed=2048;

            // Initialize the range of bytes to be transferred
            $start=0;
            $end=$file_size-1;

            // Check HTTP_RANGE variable
            if(isset($_SERVER['HTTP_RANGE']) && preg_match('/^bytes=(\d+)-(\d*)/', $_SERVER['HTTP_RANGE'], $arr))
            {
                // Starting byte
                $start=$arr[1];
                if($arr[2])
                {
                    // Ending byte
                    $end=$arr[2];
                }
            }   

            // Check if starting and ending byte is valid
            if($start>$end || $start>=$file_size)
            {
                header("HTTP/1.1 416 Requested Range Not Satisfiable");
                header("Content-Length: 0");
            }
            else
            {
                // For the first time download
                if($start==0 && $end==$file_size)
                {
                    // Send HTTP OK header
                    header("HTTP/1.1 200 OK");
                }
                else
                {
                    // For resume download
                    // Send Partial Content header
                    header("HTTP/1.1 206 Partial Content");
                    // Send Content-Range header
                    header("Content-Range: bytes ".$start."-".$end."/".$file_size);
                }

                // Bytes left
                $left=$end-$start+1;    

                // Send the other headers
                header("Content-Type: application/octet-stream ");
                header("Accept-Ranges: bytes");
                // Content length should be the bytes left
                header("Content-Length: ".$left);
                header("Content-Disposition: attachment; filename=".$file_name);

                // Read file from the given starting bytes
                fseek($fh, $start);
                // Loop while there are bytes left
                while($left>0)
                {
                    // Bytes to be transferred
                    // according to the defined speed
                    $bytes=$speed*1024;
                    // Read file per size
                    echo fread($fh, $bytes);
                    // Flush the content to client
                    flush();
                    // Substract bytes left with the tranferred bytes
                    $left-=$bytes;
                    // Delay for 1 second
                    sleep(1);
                }
            }
            fclose($fh);
        }
        else
        {
            // If the requested file is not exist
            // Display error message
            $_ERROR = "File not found!";
        }
    }
Sascha
  • 1
  • 2
  • what is the output of the browser ? possible duplicate - http://stackoverflow.com/questions/8485886/force-file-download-with-php-using-header – fehrlich Jul 10 '16 at 12:35
  • No output, as stated, that's something happening after an update to the current browser, in old chrome or platforms it correctly works. That's why I have really no idea in how to make it work again. – Sascha Jul 10 '16 at 12:49
  • you checked the other question ? Does this happen on every file type or only on some specific ones ? – fehrlich Jul 10 '16 at 12:54
  • That happens with any file, as long as I'm using Google chrome. That's really odd. Anyway, I think that this has something to do with this warning from chrome in debug mode: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/. – Sascha Jul 10 '16 at 12:54
  • i dont think thats an issue (but you might to want to include the ajax call). i never worked with `HTTP_RANGE` and `Accept-Ranges`. what is the source of the white page ? and check the received headers in chrome dev tools – fehrlich Jul 10 '16 at 13:15

1 Answers1

0

This relevant portion of code will fix my own answer, this was trivial, a simple error never noticed until recent updates of one browser:

Modify

 // For the first time download
            if($start==0 && $end==$file_size)
            {
                // Send HTTP OK header
                header("HTTP/1.1 200 OK");
            }

into

 // For the first time download
            if($start==0 && ($end+1)==$file_size)
            {
                // Send HTTP OK header
                header("HTTP/1.1 200 OK");
            }
Sascha
  • 1
  • 2