ZIP Archive sent by PHP is corrupted - php

I am using php ZipArchive to create an zip file on-the-fly and send it back to the user. I temporarily store the zipped file in a folder above document root and then send it back with the code
header('Content-type:application/zip');
header('Content-Disposition: inline; filename="'.("file.zip").'"');
header("Content-Transfer-Encoding: binary");
header("Content-Length:".filesize($file));
$fh = fopen($file,'rb');
fpassthru($fh);
after having first issued a
$zip->close()
to ensure that that the file isn't open. The issue I have run into is this - the stored zip file is a valid archive which I can open in Windows 7, 7Zip, WinZIP etc. However, when I send the file down with the code above it ends up with an 0xD 0xA pair at the start of the file which is enough to render it corrupt. I cannot figure out where those characters could be coming from. Is this a known bug with fopen/fpassthru? Any help would be much appreciated.

I found when removing the header("Content-Length:".filesize($file)); line it fixed my very same problem...

After many tries to download zip file, the solution was:
$result = create_zip($files_to_zip,$fileZip,true,$path_parts['dirname']);
ob_clean();
ob_end_flush(); // more important function - (without - error corrupted
zip)
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header('Content-Type: application/zip;\n');
header("Content-Transfer-Encoding: Binary");
header("Content-Disposition: attachment; filename=\"".basename($fileZip)."\"");
readfile($fileZip);
unlink($fileZip);
exit();

What does your full script look like?
Generally speaking you should remove any closing PHP tags at the end of your script files, as it's probably output coming from the end of your script, or an included script.

Thank you #_on !
You helped me with this information.
But instead of removing header ("Content-Length:". Filesize ($ file)) ;, I inserted a line break "\\n", leaving:
header ("Content-Length:". filesize ($ file). "\\n");
And the file generated its size to assist in the download
Okay then.
Tks

Related

Force download file that's not placed on the server

I'm trying to force download a pdf file that I'm generating. I don't need the pdf file to be actually saved on the server.
So when I generate my pdf file, I get the file content. I then encode it with base64. Now the problem is that I need to force download it. I've looked all over the web, but I haven't found any search results that tells me how to do this without the file actually being placed on the site.
I've tried the following code:
header("Content-type: application/pdf");
header("Content-disposition: attachment; filename=\"invoice.pdf\"");
header("Content-Length: ".filesize($pdffile));
readfile(base64_decode($pdffile));
But, it's giving me a corrupt pdf file, (1 kb). The actual file should be around 50kb.
Any ideas, as to what I can try?
readfile trying to output content from file, but you have only data string. Try this instead:
header("Content-type: application/pdf");
header("Content-disposition: attachment; filename=\"invoice.pdf\"");
echo base64_decode($pdffile);
I also suggest rename $pdffile to $pdfcontent for even better clarification.

PHP to force download breaks document

I am using the following code in a php document to force download of a pdf form since the submission works only after you have it on your local machine rather online.
It downloads the file ok but it corrupts it.
I can no longer open the pdf document.
<?php
$file_name = 'costumer.pdf';
$file_url = 'http://www.lopezi.com/forms/' . $file_name;
header('Content-Type: application/pdf');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
?>
The Content-Transfer-Encoding header shouldn't be needed in this case. Further I suspect that you have corruption in the outputted file.
Download it somewhere, open notepad, and drag the file in there. If any PHP warnings or errors were generated you will see them at the top.
Also, try to avoid the option of having more content return from the script, causing problems with the download, end with something like:
die(file_get_contents($file_url));
This way you cannot accidentally break the code easily by adding more output.

File downloaded in PHP using Firefox is wrong size

I have a problem with invalid signing certificates on files downloaded using Firefox. IE, Opera, Safari and Chrome are all fine. If the file is downloaded directly by clicking a link in FF it's also ok but if the file is downloaded using PHP for security it is 1 byte larger, having a x0A tacked on the end and I think this is causing it to fail the validation check. The PHP is very simple:
<?php
$file = "../downloads/".$_GET['link'];
$size = filesize($file);
$type = filetype($file);
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header( "Content-Disposition: attachment; filename=".basename($file));
header("Content-Length: ".$size);
header("Content-Type: ".$type);
readfile($file);
?>
Does anyone have any idea why Firefox alone should be having problems with getting the size right here? Grateful for any ideas.
Check if file exists and is placed in allowed location - now attacker is able to download nearly every file on your webserver
Don't use closing phptag - ?>, every whitespace after it will be send to the browser
Use exit; just after readfile to make sure no other function that produces output is called.
check on the Content-Type header, you set it twice so the latter one will be used, it could be something like "Content-Type: file" due to function filetype(), the browser can't understand "file" content type and take it as a text file. I guess that's the cause of the extra 0x0a.
Comment "header("Content-Type: ".$type);" and it will work fine.
replace below line
<?php
header("Content-Length: ".strlen($file));
?>
good luck :)

PHP File Download

I'm currently building a script that will allow a user to download a file via a URL without actually seeing the filename or where the file is stored. So far I have everything built out, but I need to know how I would go about calling the file to open and download. I currently have a working version (code below), but for some reason the PHP is corrupting the download. Everytime I try to open a file that downloads to my desktop I get a corrupt error message. When I open the same file on the server itself, the file works just fine.
URL Structure:
http://www.example.com/download/file/cjVQv0ng0zr2
Code that initiates the download
$fullpath = BASE_PATH . '../uploads/brochures/' . $vendors['0']['filename'];
header("Content-type: application/pdf");
header('Content-disposition: attachment; filename="' . $fullpath . '"');
Am I doing something wrong that would cause the file to become corrupt? Am I missing a header or two?
Thanks in advance,
Jake
You need to call the following line after sending the header.
readfile($fullpath);
and also adjust in the header like this:
header('Content-disposition: attachment; filename="' . basename($fullpath) . '"');
One thing i am not sure about is the $fullpath .. try to see if the $fullpath you have is correct and you can actually reach the file, this needs to be the full physical path of the file.
I think it would also be a good idea to add the following header as well:
header("Content-Transfer-Encoding: binary");
I had a similar issue a while back. Make sure you don't have any extra whitespace in your script file, either before the "<?php" tag or after the "?>" tag. In my case the last character of my script was "\n" instead of the expected ">".
I had faced the same problem sometime back, following worked for me; put a
while( #ob_end_clean() );
just before header functions:
header("Content-Type: ". $row['p_mime']);
header("Content-Length: ". $row['p_size']);
header("Content-Disposition: inline; filename=".$row["p_name"]);
Content-disposition: attachment/inline has to be set according to cases (1. prompt for download / 2. open in browser)
NOTE: Take care that you are not echoing and value before the header function, and being over cautious will not do any harm, silent out all the function before header function which you think would fail or spawn a warning message prefixing "#" symbol to those lines of php code.
all the best :)
Make sure you exit...
(i'm using a blob)
header("Content-Type: " . $response['content_type'] );
header("Cache-Control: maxage=1");
header("Pragma: public"); //fixes ie bug
echo trim($_data);
exit();

PHP generated Excel file is different when downloaded

I have a PHP file that generates xls files using the module found at http://pear.php.net/package/Spreadsheet_Excel_Writer/
I can create the sample document just fine and when I open it, it looks fine.
My next step it to turn it into a downloadable link. To do that, I did this:
$mimeType = "application/vnd.ms-excel";
$file_name = "test.xls";
$file_path = "/tmp/".$file_name;
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-Type: application/' . $mimeType);
header('Content-Length: '.$size);
header("Content-Disposition: attachment;filename=$file_name ");
header("Content-Transfer-Encoding: binary ");
// open the file in binary read-only mode
// display the error messages if the file canĀ“t be opened
$file = & fopen($file_path, 'rb');
if ($file) {
// stream the file and exit the script when complete
fpassthru($file);
exit;
} else {
echo $err;
}
When I download the file however, it contains a lot of garbage data both in Excel and OpenOffice. The diff says that then binary file in the /tmp folder and the downloaded file are different from each other. I'm guessing that it has something to do with the headers or with fpassthru but I haven't had much luck with debugging the issue.
Any ideas on what the problem is?
The multiple Content-Type headers are uncessary. You're essentially saying that the file is a muffin and a pizza and a ford taurus all at the same time. All you need is the application/octet-stream version, unless you want to serve up the exact mime type.
As well, is there any reason you're trying to turn the file handle returned by fopen() into a reference?
Try something simpler:
<?php
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment;filename=$file_name");
readfile("/tmp/test.xls");
exit();
?>
and see if that does any better.
Just make sure that you don't send ANYTHING out to the browser BEFORE the actual file content gets send.
It might just be some php 'error' or even 'notice' that Spreadsheet_Excel_Writer is producing and you don't even see. Or it might be a closing '?>' tag thats followed by s simple space or newline.
I had a similar error where the file that was generated inside the web folders were working. However the delivery using header('...') gave me corrupt files. This was due to a single space at the end of one php file after the closing '?>' tag.
I am using the same library and I just discovered that the files in the library itself are creating the whitespace.
Solution: In the following files remove the whitespace at the end of the file, or remove the ?> closing tag at the end.
Files to edit (all files in the Spreadsheet_Excel_Writer package):
Writer.php
Workbook.php
Worksheet.php
PPS.php
Parser.php
OLE.php
Parser.php
File.php
BIFFWriter.php
Validator.php
Root.php
Add the following code at the top of the page where the excel file is generated
ob_clean();
This would clear all the gibberish data.Also check for any echo statements.If echo statements are present, remove them. The data should always present in format specified by excel package.

Categories