Server environment:
- Linux RHEL5 x86_64, Apache, PHP
Client environment:
- Windows 10 64 bit (VirtualBox MacOS host), 4GB Ram, 30GB free space, Browser IE11 (also tested with Edge/Firefox), 7zip
The scenario is the following:
- I upload a zip (there is a file inside the archive that is 2.5GB) via browser to my PHP web server, SHA2 checksum match when the zip arrived on server side
- I unpack the zip on the server, generates an XML file based on the files inside, then add the XML file back into the original zip. eg:
$xml->addFromString("hello.xml", $xmldata);
- I then close the zip and let the user download the zip file.
The problem is that when I try to open the downloaded zip, the xml I added is “missing”, 7zip reported that there are data after the payload
. If I unpack the exact same zip on the server side, everything is in there… If I scp
the zip to my local machine, then transfer over to my Windows machine, and opens it there, it is fine too…
Which lead me to think, the header I’m setting might be wrong… I’ve tried various different ways, but still couldn’t resolve it… here is the latest header that I have…
ob_start(); header("Content-type: application/octet-stream"); header("Content-Transfer-Encoding: binary"); header('Content-Length: ' . filesize($filename)); header("Content-Disposition: attachment; filename="$filename""); while (ob_get_level()) { ob_end_clean(); } readfile($filename);
I also tried with application/zip
, that doesn’t work either.
Update:
So if I download the zip file via browser (IE11) the file’s checksum is different than the zip generated on the server… If I scp
the zip from server to local and then checksum it, they match… so it looks like there is something that broke the zip during the transfer but this only happens with large file(s) inside the zip.
Can someone tell me why is the huge file has different attributes stor
than other? And why is it that the xml that I added has 0.0 fat
whereas the others has 6.3
?
less 123456.zip -rw-a-- 6.3 fat 140 bx defN 3-Feb-16 12:22 123456/CONFIG.LDR -rw-a-- 6.3 fat 140 bx defN 8-Apr-16 10:55 123456/FILES.LUM -rw-a-- 6.3 fat 100 bx defN 3-Feb-16 12:23 123456/LOADS.LUM -rw-a-- 6.3 fat 2621440000 bx stor 16-Feb-17 15:09 123456/huge.lup -rw-a-- 6.3 fat 142 bx defN 3-Feb-16 12:23 123456/PBA123456.LUH -rw---- 0.0 fat 25196 b- defN 17-Feb-17 16:13 123456/crate.xml 6 files, 2621465718 bytes uncompressed, 2621451952 bytes compressed: 0.0%
I noticed that everything (eg: LUH and xml) after the huge file is lost after the file is being downloaded via browser.
Update2:
Ok, this is insane… so I unpack the zip on linux with unzip
then repack it using zip
and download the file the same way via the browser. I’m now losing different files in the archive… THIS MAKES ABSOLUTELY ZERO SENSE!
After I unpack and repack, I get this below, everything after the large file is not viewable in Windows.
drwxr-xr-x 2.3 unx 0 bx stor 17-Feb-17 17:03 123456/ -rw-r--r-- 2.3 unx 140 bx defN 8-Apr-16 10:55 123456/FILES.LUM -rw-r--r-- 2.3 unx 142 bx defN 3-Feb-16 12:23 123456/PBA123456.LUH -rw-r--r-- 2.3 unx 25196 tx defN 17-Feb-17 16:51 123456/crate.xml -rw-r--r-- 2.3 unx 2621440000 bx defN 16-Feb-17 15:09 123456/huge.lup -rw-r--r-- 2.3 unx 100 bx defN 3-Feb-16 12:23 123456/LOADS.LUM -rw-r--r-- 2.3 unx 140 tx defN 3-Feb-16 12:22 123456/CONFIG.LDR
Advertisement
Answer
PHP readfile() can get problematic with large files. Try using stream_copy_to_stream() instead:
set_time_limit(0); $stdout = fopen('php://output', 'w'); $bfname = basename($fname); header("Content-type: application/octet-stream"); header("Content-Disposition: attachment; filename="$bfname""); $filein = fopen($fname, 'r'); stream_copy_to_stream($filein, $stdout); fclose($filein); fclose($stdout);