anonymous123
anonymous123

Reputation: 851

Download any file using PHP

How can I download files(text/pdf/etc) using php with a header that pops-up in order for the user to choose Save or Open? The file is stored in (admin/)

I'm using this but it won't work. The downloaded file is empty! Here's my code:

 //get the filename
$filename = $_GET['filename'];

//open the file based in filename and path
$fp = fopen('admin/'.$filename, 'w') or die("can't open file");


header("Content-type:  text/pdf");
header("Content-Disposition: attachment; filename=file.txt");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");        

//echo file_get_contents($filename);
exit;   

Upvotes: 0

Views: 4944

Answers (5)

gianebao
gianebao

Reputation: 18958

//echo file_get_contents($filename);

Is this really supposed to be commented out?

Edited:

And use readfile

The reason why you can see ANYTHING is because your not showing ANYTHING after the header declaration.

Upvotes: 3

Jet
Jet

Reputation: 1325

I think this code would solve your problem.

<?php

     $allowed_files = array('filename1.pdf', 'filename2.pdf'); //list content allowed files
      $file = $_GET["file"];
        if(in_array($file , $allowed_files)) { 
                header("Content-type:  text/pdf");
                header("Content-Disposition: attachment; filename=file.txt");
                header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
                    readfile($file);
                        exit;
        }

        else die('you do not have permission to download this file');
?> 

Upvotes: 0

deceze
deceze

Reputation: 522510

Some problems:

$filename = $_GET['filename'];
$fp = fopen('admin/'.$filename, 'w') or die("can't open file");

What if I use /page.php?filename=../../../../list_of_secret_passwords? This is called a directory traversal attack, something you need to protect against. Furthermore, you don't need to open a file handle (with write access no less), just use file_exists or is_readable to check if the file exists.

//echo file_get_contents($filename);

If this line is commented out, of course nothing will happen. You should first and foremost use readfile though. file_get_contents will read the entire file into memory, then echo it like a regular string. This is hugely wasteful and might crash your script for large files. readfile outputs the file directly to the user output, using almost no extra memory.

This is probably your real problem though:

/* $fp = fopen( */ 'admin/'.$filename /* , 'w') or die("can't open file"); */
/* echo file_get_contents( */ $filename /* ); */

'admin/'.$filename vs. $filename

Which one is it?

Upvotes: 0

Johnus
Johnus

Reputation: 720

This sounds like a dangerous thing you are attempting. Why do you want the user to be able to download any file? Are you sure you don't want them to just be able to download files in a certain directory? With your script they could have access to all your PHP scripts and potentially find security loopholes in your server.

Also, with the commented out line, you might consider replacing it with a less memory intensive solution

while ($fp !== false && ($file_contents_buffer = fgets($fp, 10000)) !== false) {
    echo $file_contents_buffer;
}

Upvotes: 0

chakrit
chakrit

Reputation: 61558

Try

header("Content-type: application/octet-stream");

Upvotes: 1

Related Questions