0

I have never written an PHP Download File Script neither have any experience with it and I am really not a pro. I got the snippet of code you can see below from another website and tried to make use of it. I understand what is written in the script but I just don't get the message of the errors or rather said, I don't know how to prevent these.

Here is the download.php script - I have put it into the /download/ folder below my main domain:

<?php

ignore_user_abort(true);
set_time_limit(0); // disable the time limit for this script

$path = "/downloads/"; // change the path to fit your websites document structure

$dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\).]|[\.]{2,})", '', $_GET['download_file']); // simple file name validation
$dl_file = filter_var($dl_file, FILTER_SANITIZE_URL); // Remove (more) invalid characters
$fullPath = $path.$dl_file;

if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
    case "pdf":
    header("Content-type: application/pdf");
    header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a file download
    break;
    // add more headers for other content types here
    default;
    header("Content-type: application/octet-stream");
    header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
    break;
}
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
while(!feof($fd)) {
    $buffer = fread($fd, 2048);
    echo $buffer;
}
}
fclose ($fd);
exit;

Now in the /download/ folder, which contains the download.php I have a folder /downloads, which contains the .pdf that should be downloaded.

The link I use on my webpage is: PHP download file (why isn't it displayed, included the 4 white spaces :

Now I get the following errors when I click on the link:

Warning: Cannot set max_execution_time above master value of 30 (tried to set unlimited) in /var/www/xxx/html/download/download.php on line 4

Warning: fopen(/downloads/test.pdf): failed to open stream: No such file or directory in /var/www/xxx/html/download/download.php on line 12

Warning: fclose() expects parameter 1 to be resource, boolean given in /var/www/xxx/html/download/download.php on line 34

If I use an absolute path (https://www.my-domain.de/downloads/) for the $path variable, I get these errors:

Warning: Cannot set max_execution_time above master value of 30 (tried to set unlimited) in /var/www/xxx/html/download/download.php on line 4

Warning: fopen(): https:// wrapper is disabled in the server configuration by allow_url_fopen=0 in /var/www/xxx/html/download/download.php on line 12

Warning: fopen(https://www.my-domain.de/downloads/test.pdf): failed to open stream: no suitable wrapper could be found in /var/www/xxx/html/download/download.php on line 12

Warning: fclose() expects parameter 1 to be resource, boolean given in /var/www/xxx/html/download/download.php on line 34

I am thankful for any advices!

Franky2207
  • 163
  • 2
  • 19
  • you're trying to use your php script as a general web proxy, and the necessary back-end support has been disabled in your php configuration. you also have no error handling whatsoever in the code, so anytime something fails, you just keep blundering onwards causing further errors. e.g. fopen() failed, but you assumed it never would, so tried to use the boolean FALSE that fopen returned as if that was a valid file handle – Marc B Apr 28 '16 at 15:52
  • Hi Marc B, as I stated, I am really not that advanced concerning these download scripts; how can I enable the back-end support in my php configuration or how else do I use it if not as a general web proxy? Or do I have to consult my Provider for that? Actually I just followed the steps that were explained on that website.. still failed :(. Thanks for your advices! – Franky2207 Apr 28 '16 at 16:45
  • 1
    Then answer is here : http://stackoverflow.com/questions/36577020/failed-to-open-stream-no-such-file-or-directory – Vic Seedoubleyew Apr 30 '16 at 11:42
  • @Vic thank you very much! – Franky2207 May 02 '16 at 11:02
  • @Vic thank you Vic. Nice Instructions! I went through them and tried to apply your 2. point: `$path = __DIR__ ."/downloads/";` in my case but then I got another error followed by a very long page with unreadable signs and symbols: `Warning: Cannot modify header information - headers already sent by (output started at /var/www/xxx/html/download/download.php:4) in /var/www/xxx/html/download/download.php on line 28 %PDF-1.5 %µµµµ 1 0 obj <>>> endobj 2 0 obj <> endobj 3 0 obj <>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/MediaBox` followed by the endless list of strange symbols^^ – Franky2207 May 04 '16 at 14:39
  • 1
    @Franky2207 it means that you solved your first problem, and then discovered your second :) This is totally unrelated, and usually happens when you have already outputted something with "echo", or simply a blank line, before sending headers (such as "Location:") – Vic Seedoubleyew May 04 '16 at 14:43
  • @Vic false alarm in my comment written before (just deleted). Currently looking for the thing that triggers that headers error – Franky2207 May 04 '16 at 15:19
  • @Vic solved it, the `set_time_limit(0);` triggered the headers error - now it works!! – Franky2207 May 04 '16 at 15:43
  • Glad it works now :) – Vic Seedoubleyew May 05 '16 at 09:58

1 Answers1

0
<?php

ignore_user_abort(true);
//set_time_limit(0); disable the time limit for this script

$path = "downloads/"; // change the path to fit your websites document structure

$dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\).]|[\.]{2,})", '', $_GET['download_file']); // simple file name validation
$dl_file = filter_var($dl_file, FILTER_SANITIZE_URL); // Remove (more) invalid characters
$fullPath = $path.$dl_file;

if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
    case "pdf":
    header("Content-type: application/pdf");
    header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a file download
    break;
    // add more headers for other content types here
    default;
    header("Content-type: application/octet-stream");
    header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
    break;
}
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
while(!feof($fd)) {
    $buffer = fread($fd, 2048);
    echo $buffer;
}
}
fclose ($fd);
exit;
?>

Try this code Your server is probably not allowing you for a maximum execution time limit for infinite seconds. Check it in php.ini file Also the relative path was wrong, and "https://www.my-domain.de/downloads/" is not a path, it's a url for the server