0

I have a script which is used to download large files in pdf and media format. I can't download it it gives http internal error sometimes it give 500 internal server error sometimes.

<?php


//The directory where the download files are kept - keep outside of the web document root
$strDownloadFolder = "uploads/";

//If you can download a file more than once
$boolAllowMultipleDownload = 0;

// 1. Create a database connection
//connect to the DB
$resDB = mysql_connect("localhost", "root", "");
mysql_select_db("downloader", $resDB);


if(!empty($_GET['key'])){
    //check the DB for the key
    $resCheck = mysql_query("SELECT * FROM downloads WHERE downloadkey = '".mysql_real_escape_string($_GET['key'])."' LIMIT 1");
    if($resCheck == FALSE) { echo "QUERY FAILED: " . mysql_error(); }
    $arrCheck = mysql_fetch_assoc($resCheck);
    if(!empty($arrCheck['file'])){
        //check that the download time hasnt expired
        if($arrCheck['expires']>=time()){
            if(!$arrCheck['downloads'] OR $boolAllowMultipleDownload){
                //everything is hunky dory - check the file exists and then let the user download it
                $strDownload = $strDownloadFolder.$arrCheck['file'];

                if(file_exists($strDownload)){

                    //get the file content
                    $strFile = file_get_contents($strDownload);

                    //set the headers to force a download
                    header("Content-type: application/force-download");
                    header("Content-Disposition: attachment; filename=\"".str_replace(" ", "_", $arrCheck['file'])."\"");

                    //echo the file to the user
                    echo $strFile;

                    //update the DB to say this file has been downloaded
                    mysql_query("UPDATE downloads SET downloads = downloads + 1 WHERE downloadkey = '".mysqli_real_escape_string($_GET['key'])."' LIMIT 1");

                    exit;

                }else{
                    echo "We couldn't find the file to download.";
                }
            }else{
                //this file has already been downloaded and multiple downloads are not allowed
                echo "This file has already been downloaded.";
            }
        }else{
            //this download has passed its expiry date
            echo "This download has expired.";
        }
    }else{
        //the download key given didnt match anything in the DB
        echo "No file was found to download.";
    }
}else{
    //No download key wa provided to this script
    echo "No download key was provided. Please return to the previous page and try again.";
}

?>

Since http force headers are not working for larger files... I wanna use href with download attribute so when user clicks on it it should have direct encrypted link! with token or limited session!

  • Have you looked at the error logs? Also mysql_* functions are removed in PHP 7 and deprecated after PHP5.6. You ought to switch to PDO or mysqli now and save a headache later. – aynber Apr 03 '17 at 20:38

1 Answers1

0

file_get_contents reads the entire file into memory. If the file is larger than the available memory, it fails.

Instead you can read the file contents directly to the output stream:

//read whole file into memory, whoops
//$strFile = file_get_contents($strDownload);

//set the headers to force a download
header("Content-type: application/force-download");
header("Content-Disposition: attachment; filename=\"".str_replace(" ", "_", $arrCheck['file'])."\"");

//read file to output stream
readfile($strDownload);

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

Steve
  • 20,703
  • 5
  • 41
  • 67
  • No problem, glad i could help you – Steve Apr 03 '17 at 20:51
  • It is much better now... but still on some files of 700mb or 1gb files still im getting this error while downloading "This site can’t be reached" my server is windows 2016 it has remote desktop enabled and RAM is 8gb... in php.ini i used 3GB memory limit and also used post memory 3gb in php.ini .... what you suggest what settings should i use? and using .htaccess is necessary ? –  Apr 03 '17 at 22:55
  • I have little recent experience with windows server unfortunately, and my previous experiences with it where purely c#.net not php. As a first step turn on error reporting and check the logs – Steve Apr 03 '17 at 23:13
  • This is what my logs shows... http://i.imgur.com/l7VuH1O.png please guide me what should i do? And this is my php memory setting... http://i.imgur.com/FjOVnTq.png –  Apr 03 '17 at 23:27
  • Help me fix the issue please I'll pay. @Steve –  Apr 04 '17 at 09:52
  • Sorry i just dont have the experiance with your server stack to help much. However this looks like it could be the issue (and a possible solution): http://stackoverflow.com/questions/31277672/allowed-memory-exhausted-when-using-readfile – Steve Apr 04 '17 at 12:19