I have an application written in php using the Yii framework and hosted on Openshift. I need to force the download of a pdf file, created with mpdf (using this extension http://www.yiiframework.com/extension/pdf/).
On my local server, the following line suffices to force the download with the name I want:
$mPDF1->Output($file_name , 'D');
On Openshift, however, the download is not forced and the name of the file is not correct.
This is the code from mpdf that I think it is used to create the headers of the response:
else if ($dest=='D') {
header('Content-Description: File Transfer');
if (headers_sent())
$this->Error('Some data has already been output to browser, can\'t send PDF file');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Content-Type: application/force-download');
header('Content-Type: application/octet-stream', false);
header('Content-Type: application/download', false);
header('Content-Type: application/pdf', false);
header('Content-disposition: attachment; filename="'.$name.'"');
}
These are the response headers I get on my local server:
HTTP/1.1 200 OK
Date: Tue, 07 Jul 2015 07:15:34 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.9
Expires: Sat, 26 Jul 1997 05:00:00 GMT
Cache-Control: public, must-revalidate, max-age=0
Pragma: public
Content-Description: File Transfer
Content-Transfer-Encoding: binary
Last-Modified: Tue, 07 Jul 2015 07:15:34 GMT
Content-disposition: attachment; filename="invoice.pdf"
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/pdf
And these are the response headers I get on Openshift:
HTTP/1.1 200 OK
Date: Tue, 07 Jul 2015 07:05:05 GMT
Server: Apache/2.2.15 (Red Hat)
Expires: Sat, 26 Jul 1997 05:00:00 GMT
Cache-Control: public, must-revalidate, max-age=0
Pragma: public
Content-Description: File Transfer
Content-Transfer-Encoding: binary
Last-Modified: Tue, 07 Jul 2015 07:05:07 GMT
Content-Type: application/pdf
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
So on Openshift it is missing:
Content-disposition: attachment; filename="invoice.pdf"
and the file is not downloaded but shown in the browser.
What can I do to make it work?
I think it will work if You remove Content-Type: application/pdf. Some browsers automatically open this kind of documents. Leave only application/octet-stream.
header('Content-Transfer-Encoding: binary');
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Content-Type: application/octet-stream');
header('Content-disposition: attachment; filename="'.$name.'"');
i'm using this after generating PDFs from a library. So far no problem.
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="generated.pdf"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file_to_save));
header('Accept-Ranges: bytes');
readfile($file_to_save);
where $file_to_save is the absolute path of your pdf
Related
I try download a zip file via header:
$file = '/srv/users/serverpilot/apps/elm/public/dll/files/438de5/file-c117c93c.zip';
$filename = 'file-c117c93c.zip';
if (file_exists($file))
{
$fileName = trim($filename);
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename='.$fileName);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
file will download with true size. but when I open downloaded file, zip file can not be open (invalid archive error)
what is the wrong?
After trying several solutions I realized the problem is on the Content-Encoding: gzip sent by apache. My httpd.conf is set to send this headers by default and this causes a problem on file downloads:
HTTP/1.1 200 OK
Date: Mon, 02 May 2016 21:52:08 GMT
Server: Apache
x-powered-by: PHP/5.3.3
content-transfer-encoding: Binary
Content-Disposition: attachment; filename="peace.zip"
Vary: Accept-Encoding
Content-Encoding: gzip
Connection: close
Transfer-Encoding: chunked
Content-Type: application/zip
On a different server, the returning header doesn't contain Content-Encoding: gzip and your code works flawlessly.
HTTP/1.1 200 OK
Date: Mon, 02 May 2016 21:57:43 GMT
Server: Apache/2.2.15
x-powered-by: PHP/5.4.45
Content-Description: File Transfer
Content-Disposition: attachment; filename="peace.zip"
content-transfer-encoding: binary
Expires: 0
Cache-Control: must-revalidate
Pragma: public
Content-Length: 627874
Connection: close
Content-Type: application/zip
Solution:
I've struggle for about 1 hour with this...
Add the following at the beginning of your php file:
apache_setenv('no-gzip', 1);
ini_set('zlib.output_compression', 0);
Voilá, force download works...
We are rendering minified css / js through php with following expire headers
header('Expires:'.gmdate('D, d M Y H:i:s', 1407595380 + 3600 * 24 * 90).' GMT');
header('Cache-Control: public');
header('Last-Modified: 1407595380');
header('Content-type: text/css');
Response headers we are getting mentioned in-line
Cache-Control public
Connection Keep-Alive
Content-Encoding gzip
Content-Length 3224
Content-Type text/css
Date Mon, 11 Aug 2014 14:54:55 GMT
Expires Fri, 07 Nov 2014 14:43:00 GMT
Keep-Alive timeout=5, max=100
Last-Modified 1407595380
Pragma no-cache
Server Apache/2.2.22 (Ubuntu)
But every time i refresh my page , browser gives me 200 response code instead of 304. Browser is not using own cache for php generated minified files and rest css js having 304 code on subsequent requests.
Thanks
$timeToCache = 3600 * 24 * 90;
header('Expires:'.gmdate('D, d M Y H:i:s', 1407595380 + $timeToCache).' GMT');
header('Cache-Control: public');
header('Cache-Control: max-age='.$timeToCache);
header('Last-Modified: 1407595380');
header('Content-type: text/css');
header('Pragma: cache');
Pragma: no-cache might give you clue.
Although it is for legacy HTTP/1.0, Try setting Pragma: cache .
I can't get php to set various headers when trying to return a file.
Relevant code:
if (ob_get_contents()) ob_end_clean();
header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
header('Content-Type', 'application/pdf');
if (ob_get_contents()) ob_flush();
header('Content-Disposition', 'attachment; filename="' . basename($setfile) . '"');
header('Content-length', filesize($fullpath));
readfile($fullpath);
File exists, all is well. but the header response is always:
HTTP/1.1 200 OK
Date: Sat, 09 Nov 2013 22:19:22 GMT
Server: Apache/2.2.24 (Unix) DAV/2 PHP/5.5.0 mod_ssl/2.2.24 OpenSSL/0.9.8y
X-Powered-By: PHP/5.5.0
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 20
Content-Type: text/html
I can modify the status code, i've returned 404 etc.. but the content-type is always text/html... I'm at a bit of a loss.. The content-disposition isnt being set.. hmm...
Serving the file requires a valid session, so please no 'just redirect to the file' type answers.
Thanks for any input
You are calling header() incorrectly. You want
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="' . basename($setfile) . '"');
See http://php.net/manual/en/function.header.php
what about this :
<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');
// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="YOUR_FILE.pdf"');
#rob is right, you are calling header incorrectly. also, see if you are actually able to read the file.
So I have a downloads page where you click a link, it opens /downloads/download/randomhash
randomhash is found in the db, i increment a download counter, and then redirect to the actual file e.g. /uploads/2012/file.png.
Everything works except for the redirect doing what I'd like it to do. I'm not sure why it's not working...
header("Location: " . $row->uri);
header("Content-Disposition: attachment; filename=$row->name");
On the first load of the file, it has the appropriate content-disposition header (in firebug), but it doesn't prompt the file to be downloaded (which it should, right??). Any ideas?
Response Headers:
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, public
Connection: Keep-Alive
Content-Disposition: attachment; filename=promotion_photo_2.jpg
Content-Encoding: gzip
Content-Length: 20
Content-Type: text/html; charset=utf-8
Date: Mon, 27 Feb 2012 01:01:22 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive: timeout=5, max=100
Location: /uploads/2012/mediakitD3CF.jpg
Pragma: no-cache
Server: *
Vary: Accept-Encoding
X-Powered-By: *
X-UA-Compatible: IE=Edge,chrome=1
You are setting the Content-Disposition header in the same response which tells the browser where to redirect. My suggestion is to just stream the attachment on the response, with no redirect
header('Content-Disposition: attachment; filename=file-to-be-downloaded.jpg');
header('Content-type: image/jpeg'); // or what is relevant, ie application/octet-stream
$fn=fopen("path-to-file/file-to-be-downloaded.jpg","r");
fpassthru($fn);
I'm running into a very strange error in Firefox and Chrome. The error doesn't occur in Safari. I'm displaying a PDF on a page with the following code (works fine):
header('Content-Length: ' . filesize($pdfPath));
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: inline; filename="' . $pdfId . '.pdf"');
readfile($pdfPath);
The PDF loads up beautifully, but when I click the back button in the browser (Firefox and Chrome), the page that I jump back to has the HTTP header included in the body tag.
HTTP/1.1 200 OK Date: Tue, 08 Mar 2011 00:18:47 GMT Server: Apache/2.0.63 (Unix) PHP/5.2.13 DAV/2 mod_ssl/2.0.63 OpenSSL/0.9.7l X-Powered-By: PHP/5.2.13 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 7010 Keep-Alive: timeout=15, max=92 Connection: Keep-Alive Content-Type: text/html
This header is for the current page (not the page that displayed the PDF). In debugging, I printed out the body tag with the following jQuery code:
console.log($('body').html());
The header appears before any other content in the body. Any ideas as to what could be causing this rogue header to appear?
Finally figured out what was going on, and the fix was quite simple. I just added an exit() after the readfile(), so the final code ended up looking like this:
header('Content-Length: ' . filesize($pdfPath));
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: inline; filename="' . $pdfId . '.pdf"');
readfile($pdfPath);
exit();