Firefox downloads(tries to open) .zip file as .HTM - php

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

Related

File download stops either with php or xsendfile

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

File Download using PHP/Apache2 and Google Chrome

The download method I am using:
I have a "Export" button in HTML which when clicked sends some data to the server.
The server processes the data, writes the CSV to a file and whether the writing was successful or not, sends an appropriate JSON message.
On receiving a success message, I do a window.open with the proper url and attached file name to start the download.
The download happens on Firefox in Ubuntu 15.04 alright as well as IE 11 on Windows 7.
However the download fails on Google Chrome 45.0.2454.85 m on Windows 7. It just opens a new blank window and then nothing happens. I have browser cache cleared. What is the right way to start a file download for Chrome?
Here is the PHP code responsible for the download.
header("Content-Description: File Transfer");
header("Content-Type: text/csv");
header("Content-Disposition: attachment; filename=". basename($filename));
header("Expires: 0");
header("Cache-Control: must-revalidate");
header("Pragma: public");
header("Content-Length: ". filesize($filename));
ob_clean();
flush();
readFile($filename);
Try write all your headers after ob_clean().
ob_clean() clear all data with headers.

Large file download taking more time

I have used following code to download approximate 920MB file,
set_time_limit(0);
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("X-Sendfile: $zipname"); // For Large Files
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=\"".$zipname."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($directory_location . '/' . $zipname));
ob_end_flush();
readfile($directory_location . '/' . $zipname);
Before this code i did some study with the following links Using X-Sendfile with Apache/PHP, Streaming a large file using PHP and Limit download speed using PHP but not much helpful to me because file download still takes more time with just (2MB) file. It's not showing and transfer rate or anything else. I want download start to serve file with around 60Kbps, with all files (Large or small)
UPDATE: One more thing i noticed its not showing any download process just executing and after sometime display the pop-up to choose the location, and after hitting save button its direct save to the computer without any downloading process window :(
Please help me to guide the right way.
Based on above comments there are two solutions:
1) Just download the file directly. You don't appear to be doing any validation, so if not, then just pass the user to the file to download and let apache handle it.
2) If you do need validation / pre-processing, then check mod_xsendfile - adding the header isn't enough, you actually need to add the mod to apache. If you're in Linux then compile from source (https://tn123.org/mod_xsendfile/). If you're not in Linux then mod_xsendfile for Win x64? has a response from the author saying he can provide binaries - but that's in 2010. There's a bit of advice around the web - although it's been a while since I looked at it so can't really help much more.

Script to Download File from Android Browser

I am not a web developer by all means. But I am trying to help someone deliver a video from their server. Basically when the user clicks a button on the website, we want the user to be prompted to download the video. So after Googling for a while I figured out how to write a short php script using content-disposition:
<?php
$fn = 'videoFile.mp4';
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header('Content-Description: File Transfer');
header('Content-type: video/mp4');
header('Content-Length: '.filesize($fn));
header('Content-disposition: attachment; filename='.$fn);
readfile($fn);
?>
So the button on the website points to this script. PC browsers seem to start the download with no problem. But the main focus of this is for Android phones. When you click to download the file on the default Android Browser, it fails and all it says is "Download Unsuccessful".
Another thing is that on my computer (using Firefox), the download starts and at about 200MB, it just stops. It doesn't show any signs of failure, it just looks like it finished downloading. The actual file size is about 1GB.
I have played around with the content-type quite a bit, hoping that was the problem. I used "video/mpeg" and "application/force-download" and neither of them worked.
Is there something I'm not doing write? Could the 2 problems be related? Should I be going about this a different way? Thanks for any input.
The Android browser does not appear to like Content-disposition: and related headers. I recommend just a plain redirect to the file in question.

Internet explorer file download error while doing "readfile" - PHP

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.

Categories