php force download headers - php

Which headers are most important to force a download and which headers get auto filled by the browsers
For e.g.
header('Content-Description: File Transfer');
header('Content-type: application/zip');
header('Content-Length: '.sprintf("%u", filesize($zip_out)));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Disposition: attachment; filename="'.basename($zip_out).'"');
I omit all the headers except line 1 and 2, download is working fine why/how ??

Content-Disposition: attachment tells your browser the content is an attachment. So the browser will start to download the content as a file.
According to RFC 6266:
If the disposition type matches "attachment" (case-insensitively),
this indicates that the recipient should prompt the user to save the
response locally, rather than process it normally (as per its media
type).
Content-type: application/zip says your browser that the content is zipped, and usually makes the browser to download the content as a file, even if Content-Disposition: attachment is omitted, because that is the default behavior of the browser for zipped content.
I have never seen Content-Description header in any of HTTP-related specifications and I think it does not affect download at all.

Related

Redirect to a file outside of the domain Root

I want to give a file to a person based on the users rank so I need to hide the files in a directory which is hidden.
I'm using Plesk and my structure looks like this:
api (reachable from https://api.pexlab.net)
cloud (reachable from https://cloud.pexlab.net)
default (reachable from https://pexlab.net)
error_docs
hidden (not reachable)
My PHP script is located in:
api/hub/Test.php (reachable from https://api.pexlab.net/hub/Test.php)
I have tried this:
# In Test.php
downloadFile("../../hidden/hub/download/assets/user/main.fxml");
# Function:
function downloadFile($file) {
if(file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
}
This method works but I want to redirect to this file (show it) and NOT download it. So I have tried using this:
header("Location: ../../hidden/hub/download/assets/user/main.fxml");
But this tried to redirect to https://api.pexlab.net/hidden/hub/download/assets/user/main.fxml which is invalid.
The only difference between "viewing" and "downloading" a file is what the browser does with the data. Ultimately, that's in the hands of the user, but the server can indicate what it would like to happen.
I suspect you have copied these lines without really understanding what they do:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
These are all instructions to the browser telling it what to do with the data you send.
The Content-Disposition header is used to tell the browser "rather than trying to display this content straight away, suggest the user saves it in a file, with this name". To use the browser's default behaviour, you would simply leave off this header, or give it the value inline.
The Content-Type header tells the browser what type of file this is. The value application/octet-stream means "just a bunch of bytes, don't try to interpret them in any way". Obviously, that would be no good for viewing a file in the browser, so you should send an appropriate "MIME type", like text/html or image/jpeg, as appropriate for the file you're serving. I'm guessing "FXML" is an XML-based format, so text/xml might be appropriate; or if it's human readable and you just want it displayed without any formatting, use text/plain.

PHP headers not working before a location header

On my web application, I want the user to download some information on a page and redirect after the same.
<?php
header('Content-Description: File Transfer');
header('Content-Type: text/force-donwload');
header('Content-disposition: attachment; filename=Your_Fibble_Password.txt');
header('Content-Length: '.strlen($password));
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
header('Pragma: public');
echo $password;
header('location:./');
?>
So Here the location header works and the page is been redirected but the headers for the file transfer above aren't working.
Note: I can't use exit as I got some code executing below it.
As far as I know, it's not possible do this. The technical limitation is: "You can't send headers after the content", so, in this case, you are sending the password to download (in txt format file) and then you try to send more headers to indicate a redirection.
Maybe you could simulate this behaviour from the frontend application, performing a document.location in javascript.

Downloaded file has bad mime-type

I have a PHP script that creates a Zip Archive and then passes it to the browser for download.
This can be easily done via HTTP Response Headers
header('Pragma: no-cache');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0, public')
header('Content-Type: application/zip')
header('Content-Length: ' . filesize($zipPath))
header('Content-Disposition: attachment; filename=filename.zip')
header('Content-Transfer-Encoding: binary')
echo file_get_contents($zipPath);
The file is correctly downloaded. I can also open it. However, when I check the downloaded file mime-type, it tells me : application/octet-stream instead of application/zip.
For file mime-type detection, I use the following snippet :
$pathToDownloadedFile = 'somewhere-on-disk';
$file = finfo_open(FILEINFO_MIME_TYPE);
var_dump(
file_exists($pathToDownloadedFile),
finfo_file($file, $pathToDownloadedFile)
);
which dumps out :
true
application/octet-stream
I googled the problem but with no luck.
Any piece of help would be very appreciated.

ios shows file in mobile safari rather than downloading?

I am using the following code to present a file for download to the user... in this case it is a .csv file. Works great in all browsers, BUT in IOS it loads the file in the mobile safari browser. The exact same code works fine for a .zip file (although ios gives the warning it cannot download that type of file).
What gives? Does ios completely disregard the headers or what?
if (is_file($local_path.$file))
{
//get current ts
$now = time();
// set the headers and prevent caching
header('Pragma: public');
header('Expires: -1');
header('Cache-Control: public, must-revalidate, post-check=0, pre-check=0');
header('Content-Disposition: attachment; filename="'.$now.'_'.$file.'"');
// set the mime type based on extension
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_path.$file).'');
//download
readfile($local_path.$file);
//delete file
unlink($local_path.$file);
}

PDF rendered as text

I'm using PHP to generate a PDF via browser for my web-application. Recently, the client changed the webserver to Apache and now this feature is no longer working. Instead of generating the PDF, the browser is showing the PDF as text, just as it was ignoring Content-Type (that is set to "application/pdf"). In fact, I successfully simulated the problem by commenting the line setting the Content-Type in the source code.
I need ideas about where and what to look for, any help will be very welcome :)
Since you generate PDF files through PHP, you can try to add these headers:
$file_default = 'default filename you want to appear when the user downloads.pdf';
$file_location = '/path/to/file.pdf';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$file_default);
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file_location));
ob_clean();
flush();
readfile($file_location);
I guess you'd have to force apache to download PDF content rather than showing:
check this: http://www.thingy-ma-jig.co.uk/blog/06-08-2007/force-a-pdf-to-download

Categories