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
Related
I have an application where a number of otherwise static javascript files are being generated via PHP to allow configuration options to alter the static files (path like: mystaticfile.js.php). Everything works fine EXCEPT that I can't seem to get the cache settings to work and these resources are being reloaded with every page load.
The PHP file uses the following headers to try to set the cache settings:
$expires= 60 * 60 * 24 * 60; //cache for 60 days
header('Pragma: public');
header('Cache-Control: max-age=' . $expires);
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT');
header("content-type: application/x-javascript");
However, when the files are served they're showing headers that look like:
HTTP/1.1 200 OK
Date: Sun, 06 Nov 2016 19:18:00 GMT
Server: Apache/2.2.15 (CentOS)
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 744
Keep-Alive: timeout=15, max=95
Connection: Keep-Alive
Content-Type: application/x-javascript
My first thought was that it was that it might be because Apache has the ExpiresActive flag set on but I don't see any ExpiresByType rules set for PHP files.
Reading online it sounds like ETag issues could be the problem, but I've added
Header unset Pragma
FileETag None
Header unset ETag
to the http.conf file (and restarted the service) and still no dice.
Any thoughts?
Source: PHP: Worry about some magical added “Cache-Control” Header ?
These headers are automatically set by the PHP Session module to
prevent browser/proxy based caching of your pages. Depending on your
environment setup, it’s possible to control these headers by using the
session_cache_limiter() function or use the php.ini
To disable these behaviour just pass an empty string to the
session_cache_limiter() function as mentioned in the documentation:
session_cache_limiter('');
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...
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
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.
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.