Skip to content
Advertisement

Unable to unzip large Linux zipped archive in Windows

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);
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement