I have this remote Windows 2012 (see last edit) server with latest xampp installed.
The users can normally download files (small and very big ones) from there but there are some files (pdf and zips containing the same pdfs, but not rar with the same files inside) whose download stops always at the same size.
Basically the download start normally but at a certain size, always the same on the same file, it hang for a while then stop.
This is the current code:
header("X-Sendfile: ".$pathTofile);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$filename\"");
Some things I'm sure of:
File size does not matter. The problem show either with big or small files and I've non problem with other very big files
I'v tried at least 5 different php scripts all with the same result
I've implemented xsendfile. Same result
If I try to view the pdf in the browser, it won't work either
If I download the files directly from the server they work properly in every aspect
I've tried different browser and different ISP. Same result
If I do the same operation on the site, but locally on server, everything works perfectly
EDIT:
I've changed webserver in favor of Uniform Server (see last edit) and was tryng another php script:
function send_file($position, $name) {
ob_end_clean();
$path = $position.$name;
if (!is_file($path) or connection_status()!=0) return(FALSE);
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Content-Type: application/octet-stream");
$filesize=filesize($path);
header("Content-Length: ".$filesize);
header("Content-Disposition: inline; filename=$name");
header("Content-Transfer-Encoding: binary\n");
if ($file = fopen($path, 'rb')) {
while(!feof($file) and (connection_status()==0)) {
print(fread($file, 1024*8));
flush();
}
fclose($file);
}
return((connection_status()==0) and !connection_aborted());
}
Strangley the page ignored the Content-Length header and the download worked!!
Even more strangley, I've tried to made Content-Length working by adding this line:
header("Content-Range: 0-".($filesize-1)."/".$filesize);
or/and disabling gzip compression like this:
apache_setenv('no-gzip', '1');
in both cases the Content-Length worked but the download stopped at the same point!!!
It's driving me crazy!!!
EDIT 23-10-2018: we recently switch on a debian server with fresh apache installation. The problem seems to remain. I've also try the same identical script on a shared webserver from a local provider and surprisingly it work perfectly.
Any help appreciated....
Related
I am creating downloadable zip file, it works fine almost everywhere. But in Mozilla Firefox on save of this zip I get strange message that my_zip.zip is HTM file (sorry for the language, but I hope it is pretty understandable):
If I choose save option it will be saved as normal zip (no sign of HTM at all), but in "open as" section there are only programms for opening HTM
So, the question is How to make Firefox detect this zip as zip?
I am currently using this headers (set by PHP):
header('Content-Description: File Transfer');
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$zipFileName");
header("Content-Transfer-Encoding: binary");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-store");
header('Pragma: no-cache');
header("Content-length: " . filesize($zipFileName));
readfile($zipFileName);
Already tried using header("Content-Type: application/zip"); , does not work; plus application/zip is not standart (as I read here in some headers related question).
I am using Mozilla Firefox v40.0.3, the php project is using Laravel 5.1 (I doubt it has anything to do with this)
UPDATE:
While trying different application\[format]s , I added a dump and die command after headers
//bunch of kosher headers here...
readfile($zipFileName);
dd(headers_list());//dumps and dies
And I get a zip type in download window. Then I figured out that after die or exit I will always get right download type of zip; Then I deleted all dump-and-die sections , but download type remains as zip. I have no idea what i have fixed by this manipulations.
I would love to have an explanation of this strange situation
A quick google search suggests the Content-Type seems to be the culprit
header("Content-Type: application/octet-stream");
Try setting it to application/x-zip-compressed ?
ALso the comments in this bug report may be useful: https://bugzilla.mozilla.org/show_bug.cgi?id=540900
I am accessing spreadsheets which are not located inside in the web directory and serving them to the browser. I am using the following code to do this:
$filePath = WEBSITE_ROOT_PATH.'/../where_the_spreadsheets_are/file_name.xls';
if(file_exists($filePath)){
$contents = file_get_contents($filePath);
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=file_name.xls");
header("Content-Transfer-Encoding: binary");
echo $contents;
}
This code works correctly on 20+ separate servers, but not on one. On the one that fails Excel says that the spreadsheet is corrupt.
The server that fails has a mirror server, so the same file path and file name exists, and on this server the spreadsheet is ok.
It's a Win server 2007 running WAMP. All the rest are also Win Servers running WAMP.
Does anyone know the reason for this?
I have a little script which sets the header to force download of a zip file with:
if(ini_get('zlib.output_compression')) {
ini_set('zlib.output_compression', 'Off');
}
header("Pragma: public");
header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="'.$mp3.'"');
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".#filesize($file));
#readfile($file) OR die("<html>...</html>");
exit;
Everything works fine in Chrome and Firefox but fails in IE 9. I have tried many different ways of setting those headers after googling around but nothing helps. Then I tried a different smaller zip file and it worked! Then I tried a bigger zip file and again fail. Would this be some setting on the server or the php.ini or something? Why does it only affect IE?
When it fails in IE it looks like it downloads.. says completed. But the file is 0 bytes.
Thanks for any help!
If the file is large enough you may have issues related to memory, execution time, etc.
Instead of trying to read the file, you could use the x-sendfile header:
header('x-sendfile: '.$file);
Check out this article about it: http://www.jasny.net/articles/how-i-php-x-sendfile/
I am trying to add a download link to a large video file (approx 300MB) on someone's site but unfortunately they're on shared hosting (i've told them they will have to upgrade if they get many people downloading it). I don't want people to have to 'Save Target As' and I usually use this code to force downloads:
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // some day in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename={$file}");
header("Content-Transfer-Encoding: binary");
readfile($file);
This works fine with smaller files but not with larger ones and even after turning errors on I get no errors and no error log. I'm sure this is to do with the shared memory limit (or possibly a timeout) but does anyone know how I go about forcing downloads of large files on shared servers, ideally without javascript as i'm sure i won't be able to set the memory limits to be high enough?
Thanks very much,
Dave
The usual solution is to do the file output yourself and let the web server's own buffers handle things:
$fh = fopen($file, 'rb') or die("Unable to open $file");
while($data = fread($fh, 10240)) { // 10kbyte chunks.
echo $data;
}
fclose($fh);
I have just moved a web application to a windows server and having some problems. One of it is -
application stores list of names of files in a database table. when a files is requested for download it is sent to output by sending proper headers (depending upon mime type and then a readfile("document location/filename.extension");
it works fine in firefox but if I try to download in IE it throws
IE can not dowload this document from
www.mysite.com .. IE was unable to
open this Internet site. The requested
file is either unavailable or cannot
be found. Please try again later.
As it was working fine on previous server (non-windows), I tried to print document location and it read somewhat like C:/Apache/htdocs/FILENAME.ext and I guess this C:/ is causing problem in IE but not in firefox??
How do I get it working right in IE??
Thanks
UPDATE
I have got it working by
adding some more headers among others .. I think first 2 are more important for IE or so (atleast working for me for now :)
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
It works :
if (strstr($_HTTP_USER_AGENT, "MSIE")) {
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: doit-revalider, post-check = 0, pré-check = 0");
header("Content-Type: application de téléchargement; name=\"$sFilename\"");
header("Content-Length: $iTaille");
header("Content-Disposition: attachment; filename=\"$sFilename\"");
header("Content-Transfer-Encoding: binary");
} else {
header("Content-Type: application de téléchargement; name=\"$sFilename\"");
header("Content-Length: $iTaille");
header("Content-Disposition: attachment; filename=\"$sFilename\"");
}
this question had already been answered here PHP: Force file download and IE, yet again
Is this by any chance over SSL? If so, there are a whole host of bugs in MSIE which could be affecting your app. Try setting a very short caching time.
If it works on Firefox using the the same server, then the problem unlikely to be anything to do with the path on the server. Although beware that (IME) IIS seems to tunnel authorization from MSIE clients (but not others) in some instances.