-1

I am using the following code to hide the real file path to prevent hotlinking. Whenever I try to download the file through newly created address, everything including the file size and the file name are ok, but, when I try to open the file, whether a PDF file or a ZIP file, it says that the file is damaged.

When I download the file directly from the server, it works and it doesn't have any problems.

$file = 'file.pdf';

$path = $_SERVER['DOCUMENT_ROOT'].'/files/';

$file_Path = $path . $file;

list($file_Basename, $file_Ext) = explode('.', $file);

switch($file_Ext)
{
    case "pdf": $ctype = "application/pdf"; break;
    case "exe": $ctype = "application/octet-stream"; break;
    case "zip": $ctype = "application/zip"; break;
    case "rar": $ctype = "application/rar"; break;
    case "doc": $ctype = "application/vnd.ms-word"; break;
    case "xls": $ctype = "application/vnd.ms-excel"; break;
    case "ppt": $ctype = "application/vnd.ms-powerpoint"; break;
    case "gif": $ctype = "image/gif"; break;
    case "png": $ctype = "image/png"; break;
    default: $ctype = "application/force-download";
}

header('Content-Type:'. $ctype);

header('Content-Length:' . filesize($file_Path));

header('Content-Transfer-Encoding: binary');

header('Content-Disposition: attachment; filename="downloaded.pdf"');

readfile($file_Path);

exit();

enter image description here

enter image description here

What am I doing wrong?!

Afshin
  • 2,427
  • 5
  • 36
  • 56
  • Check the contents of the file in a text editor to see whether it's really what you expect it to be. – PeeHaa Nov 16 '16 at 12:20
  • @PeeHaa yes it is. when I download the file normally from the server, it works. – Afshin Nov 16 '16 at 15:26
  • @Martin doesn't help. I still get the same error. – Afshin Nov 16 '16 at 15:45
  • ok, then I'd hazard that your filesize is not quite correct somehow, so try and comment out the Content-Length header and see if the download works using the dynamic size rather than a stated fixed size. – Martin Nov 16 '16 at 15:48
  • @RyanVincent I checked it. However, I don't understand what is going on inside two files. But, this is the result : Added(155)Deleted(796)Changed(405) – Afshin Nov 16 '16 at 15:57
  • @Martin in this way the file download after some time delay and it works. What should I do?! – Afshin Nov 16 '16 at 16:08
  • [ok try this solution](http://stackoverflow.com/questions/23981159/should-content-transfer-encoding-headers-be-use-when-downloading-files-via-http). If this works you can maybe reinstate the filesize header – Martin Nov 16 '16 at 16:11
  • @Martin When I remove the transfer encoding, I still get the file damaged error. But, commenting out the file size doesn't hurt the file. Do you think that I have to remove the contect-length ?! – Afshin Nov 16 '16 at 16:26
  • I can't say for sure why, but I guess from your trial and errors that it's easiest to work with just the *Content-Type* and *Content-Disposition* headers. – Martin Nov 16 '16 at 16:34

1 Answers1

0

I changed my code and added ob_clean() and flush() to make it work:

header('Content-Type:'. $ctype);

header('Content-Disposition: attachment; filename="'.$file->file_Name.'"');
header('Content-Transfer-Encoding: binary');

header("Content-Length: " . filesize($file_Path));

//This part must be added to your code
if (ob_get_length() > 0 ) {
    ob_clean();
    flush();
}

readfile($file_Path);

exit();
Afshin
  • 2,427
  • 5
  • 36
  • 56