ProCx
ProCx

Reputation: 309

Download files php always damaged

Im trying to make a script to download images from my localhost. Just for a schoolproject.

I get the filename via the url ("$_GET['file']"). Then i run this script. Every time the file is damaged and can't be viewed. I want to download images, but when i tried a word document it also was damaged. This is my code:

<?php
//get file
$file = $_GET['file'];
//set path of file
$path = $_SERVER['DOCUMENT_ROOT']."/blackbox/mediafiles/"; 
$fullPath = $path.$file;
if ($fd = fopen ($fullPath, "r")) {
    $path_parts = pathinfo($fullPath);
        header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // fore a download
        header("Content-type: application/octet-stream");
        header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
}
    header("Cache-control: private"); // open files directly
    while(!feof($fd)) {
        $buffer = fread($fd, 2048);
        echo $buffer;
    }
fclose ($fd);
exit;
?>

Anybody has and idea what goes wrong?

Thanks in advance!!

Upvotes: 1

Views: 1478

Answers (4)

DaveRandom
DaveRandom

Reputation: 88647

Either something is throwing an error from PHP, or you have leading whitespace before the opening tag in the file (<?php).

Do two things:

  • Make sure the < of <?php is the first character in the file. Make sure your script doesn't have a byte order marker in it.
  • Add these lines to the top of the script: error_reporting(0); ini_set('display_errors', 0);

Note that if disabling errors fixes your problem it means that there is an error which needs to be fixed, it is not a final solution to the problem!

Using readfile() is also shorter, safer and more efficient than opening a file pointer and looping it.

Upvotes: 1

Ren&#233; H&#246;hle
Ren&#233; H&#246;hle

Reputation: 27285

At first its not your answer. But you should really look at Security in PHP. On Your script you can access all files over the GET Parameter and DOCUMENT_ROOT.

Don't trust a user.

You should filter your variables at first or map them with a known list of files before deliver them to a user.

PHPSec

Upvotes: 1

Maxim Krizhanovsky
Maxim Krizhanovsky

Reputation: 26699

You can use readfile instead of manually reading file and outputting.

Also, please note, that $_GET['file'] can contain '../' and open any file, which is a security risk. Use the basename function (if all files are in the same directory) or restrict access to files outside the mediafiles directory

<?php
//get file
$file = $_GET['file'];
//set path of file
$path = $_SERVER['DOCUMENT_ROOT']."/blackbox/mediafiles/"; 
$fullPath = $path. basename($file);
if (is_readable($fullPath) {
    $path_parts = pathinfo($fullPath);
    header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // fore a download
    header("Content-type: application/octet-stream");
    header("Content-length: " . filesize($fullPath));
    header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
    header("Cache-control: private"); // open files directly
    readfile($fullPath);
}
exit;
?>

Upvotes: 1

catchmeifyoutry
catchmeifyoutry

Reputation: 7349

Try opening the file explicitly in binary mode:

if ($fd = fopen ($fullPath, "rb")) {

As the documentation on fopen states:

Windows offers a text-mode translation flag ('t') which will transparently translate \n to \r\n when working with the file. In contrast, you can also use 'b' to force binary mode, which will not translate your data. To use these flags, specify either 'b' or 't' as the last character of the mode parameter.

The default translation mode depends on the SAPI and version of PHP that you are using, so you are encouraged to always specify the appropriate flag for portability reasons. You should use the 't' mode if you are working with plain-text files and you use \n to delimit your line endings in your script, but expect your files to be readable with applications such as notepad. You should use the 'b' in all other cases.

If you do not specify the 'b' flag when working with binary files, you may experience strange problems with your data, including broken image files and strange problems with \r\n characters.

Upvotes: 3

Related Questions