PHP can't display image using X-SendFile and jpeg headers - php

For some reason I can't get the image to display properly, its chucking out errors not telling me what’s wrong, any ideas?
CODE
$finfo = finfo_open(FILEINFO_MIME_TYPE);
header("Content-type: ".finfo_file($finfo, $filepath));
finfo_close($finfo);
header('Content-length: '.filesize($filepath));
header('Content-Disposition: inline; filename="'.$file.'"');
header('X-Sendfile: ' . $filepath );
HEADERS
HTTP/1.1 200 OK
Date: Mon, 07 Apr 2014 13:45:37 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.10
X-Sendfile: /path/image.jpg
Content-Length: 0
Content-Disposition: inline; filename="image.jpg"
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: image/jpeg

Are you sure your file is there?
I see Content-Length: 0. I doubt you want to send empty file.
Try to remove headers output and replace it with echos to see where your scrit fails.

The above code did work, it was x-sendfile which was not configured properly in apache

Related

invalid Zip file downloads (header+php)

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...

XSendFile Apache2 mod has zero bytes

My code, the paths are correct and the content length is correct
header("X-Sendfile: " . $savePath);
header('Content-Length: ' . filesize($savePath));
header("Content-type: $type");
header('Content-Disposition: attachment; filename="' . basename($localFilename) . '"');
exit();
My .htaccess
<Files file.php>
XSendFile on
</Files>
This always results in a zero sized file download.
The file is definitely there and in the right place. Using curl -I shows me the following which appears to be fine. But the file is still zero bytes.
HTTP/1.1 200 OK
Date: Sat, 21 Feb 2015 11:35:37 GMT
Server: Apache/2.2.29 (Amazon)
X-Powered-By: PHP/5.3.29
X-Sendfile: /var/www/html/cache/72b08eb707bb5eab58d8e5d7d9b21bb8.jpeg
Content-Length: 10004
Content-Disposition: attachment; filename="72b08eb707bb5eab58d8e5d7d9b21bb8.jpeg"
Connection: close
Content-Type: image/jpeg
What have I done wrong?
So it turns out that you need to use
XSendFile on
In your main Apache2 conf otherwise it will not work anywhere

PHP header isn't modifying the content/type

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.

PHP file download with mod-xsendfile does not download entire file

I am having problem serving downloads from our website. Large files just won't download in full. Download will stop somewhere in between... Example this file (size cca 172MB) won't download in full size (there are other files also).
I switched from entirely PHP-base download script, the one included in Kohana framework:
return download::force($filePath);
to a mod-xsendfile solution. I was reading about the possible problems with PHP based download scripts and large file and cam over mod-xsendfile is the right solution... Well looks like not, I am getting the same result with both techniques. My current download implementation using mod-xsendfile headers like this:
header("X-Sendfile: $filePath");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
What am I doing wrong?
UPDATE:
I used this HTTP sniffer to check response headers and this is the result if it helps solving this problem.
Status: HTTP/1.1 200 OK
Server: Apache
Set-Cookie: dewesoftsession=63ms5j67kc231pr4bpm8cmg1f7; expires=Sat, 30-Mar-2013 11:36:59 GMT; path=/
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
Set-Cookie: dewesoftsession=63ms5j67kc231pr4bpm8cmg1f7; expires=Sat, 30-Mar-2013 11:36:59 GMT; path=/
Content-Disposition: attachment; filename="DEWESoft_FULL_7_0_5.exe"
Last-Modified: Mon, 24 Sep 2012 12:50:12 GMT
ETag: "25814de-ac291e9-4ca7207c7fcd9"
Content-Type: application/octet-stream
Content-Length: 180523497
Date: Sat, 30 Mar 2013 09:37:01 GMT
X-Varnish: 294312007
Age: 2
Via: 1.1 varnish
Connection: close
X-Varnish-Cache: MISS
After couple of days we managed to find what cause the problem. Varnish has a start-up parameter called send_timeout which is set to 600s by default. With large file downloads you might run into this timeout which will cause your download to be interrupted.
So increasing Varnish's send_timeout parameter will help you solve this kind of issue.

Header Location + Content Disposition

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);

Categories