How to use multiple http headers? - php

I have a php page which downloads zip files. Normally after the download, it automatically revert back the user to a previous page(myfiles.php) using header('location:myfiles.php');.
When I execute the page, it bring me to myfiles.php but the download pop up won't show up, thus preventing me to download my zip file. When I remove the line header('location:myfiles.php');, I am able to download my zip file as expected.
Below is an extract of my code.
//Some codes
if(file_exists($zip_name)){
// push to download the zip
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$zip_name.'"');
readfile($zip_name);
// remove zip file is exists in temp path
unlink($zip_name);
}
session_start();
$_SESSION['correct']="Files downloaded sucessfully";
header('location:myfiles.php');
Can you please help me finding a way to fix it? Thank you.

Think about what those headers are doing
These 2 and the readfile
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$zip_name.'"');
readfile($zip_name);
are sending a file to the current page that is on the browser.
This one, which will run as well as the code above
header('location:myfiles.php');
attempts to tell the browser to go to another page. If it did do that then the file you sent to the browser would just disappear
So basically done together as one flow, they do not make sense!
Also you cannot send a header('location:...) after any actual data has been sent to the browser, which of course you did when you ran the readfile($zip_name);

Related

Download different file to that requested php

In Joomla auto updater the file is requested from one domain
http://download.abc.com/?ext=addmenu&src=core&pro=1&file=update.zip
which then downloads a different file
/mnt/storage/vhosts/newdomain.com/httpdocs/tmp/addmenu-v1.1.4.zip
I've been trying to mimic this effect by calling a file release.php which is
header("Location: /addmenu/updates/com_addmenu.zip");
but it just downloads release.php and not com_addmenu.zip
I've also tried it with
header('HTTP/1.1 307 Temporary Redirect');
before the header(Location
But I can't get it to work this way. I'm guessing that I'm not able to substitute one file for another but I'm hoping someone can help.
thanks
I understood that you have a zip file on your server which shall be downloaded under a different name by the visitor's browser when s/he opens up your webpage.php.
<?php
$file_url = '/addmenu/updates/release.zip';
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header('Content-disposition: attachment; filename=com_addmenu.zip');
readfile($file_url);

PHP file download with no changes to the file

I am trying to make a file download by using PHP but the file downloaded is a clean mp3 file without tags/metadata and not the one that is on my server.
Here's a detailed explanation:
I have a mp3 file with saved ID3 tags and all information on my server.
I run this code to start the download:
header('Content-Type: application/mp3');
header('Content-Disposition: attachment; filename="file.mp3"');
header('Pragma: no-cache');
readfile("file.mp3");
This starts a file download, but the file that is downloaded loses all its meta data, including any info and album art. Is there a way around this?
For example opening the file url and right clicking -> Save As, downloads it and preserves all the information stored in the file.
How can I prevent the deletion of all the metadata? Thanks for your help
Just add these two lines:
ob_end_clean();
flush();
readfile("file.mp3");

PHP header attachment download corrupts ZIP file

I have a file like "983Y4938920820894838947" on my server, and I'd like the user to save it as "subject.zip".
Using header location makes downloading work and the file is not damaged.
Whenever i use the headers with attachment, content type and the new filename, the download zip file is corrupt (I think?).
Whenever I open the ZIP file (e.g. test.zip), it makes a new file called test.zip.cpgz. I assume this is mac's way of saying the file is corrupt.
I'm using the following code
// Download the ZIP File
header("Content-Type: application/zip");
header('Content-Disposition: attachment; filename="' . stripslashes($new_filename) . '"');
readfile($filename);
This makes the file corrupt, while the below code works perfectly (but doesn't change the name):
header("Location: $filename");
I tried other headers without any success. Does anybody have any idea? Thanks!
You are missing a header there, if you dont specify the content length, the browser will not know what the size of the file is:
header("Content-Length: {{replace.with.your.file.size}}");
Maybe this will solve your problems.
The problem was that I had an echo. The echo made the zip corrupt. So it makes sense that it only worked the header location and not the regular headers for changing the filename. Removing the echo fixed it for me.

Creating and serving zipped files with php

I'm trying to use the following code to create a zip file from a directory and serve it to the user via an http download:
// write the file
file_put_contents($path . "/index.html", $output);
// zip up the contents
chdir($path);
exec("zip -r {$course->name} ./");
$filename = "{$course->name}.zip";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' .urlencode($filename));
header('Content-Transfer-Encoding: binary');
readfile($filename);
I am able to create the zip file, but downloading it over http is not working. If I download the zip file that's created using an ftp client then Mac's Stuffit Expander unzips the files just fine, but if I download it over http, the mac unzipper creates an endless loop. What I mean by this is say the file I download is called course.zip, then unzipping the file gives course.zip.cpgz and unzipping that file gives course.zip again..and on and on.
Anyone have any ideas?
Thanks!
I had this problem and it turned out the downloaded zip file had a new line inserted at the very beginning.
Solved by using ob_clean and flush functions
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".basename($archive_file_name));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($archive_file_name));
ob_clean();
flush();
echo readfile("$archive_file_name");
Re-zipping it every time it is requested is not a good idea. Try doing that only if the ZIP file does not exist already.
If is a volatile file or just a single small file you want to transfer compressed, try using ob_start('ob_gzhandler') instead, simplier, smaller, cleaner. The file is transfered compressed, but it is saved in its original format by the client-side.
Specifying the Content-Length header is needed to allow the downloader to know the end of the file, allowing progress control, detection of corruption of the file and avoiding the hang of the HTTP session (if Connection is in Keep-Alive mode), maybe the lack of this header is the root of the problem.
As suggested by karim79, I'll put my comment as an answer: what happens if you change the MIME type from application/octet-stream to application/zip?
Also, I see you're using a command line zip program, but you don't check for success of the zip, and also don't check if the file exists before attempting to send it out to the end users browser. Try hard coding a file name, manually using zip to guarantee a properly formed zip file, and then see if your code will spit it to your browser properly.
What you're seeing is that the archive utility is not recognizing the zip file as a zip file, and tried to zip up the zip archive itself. The second operation simply unzips the first file created, so never actually opening the file at all. This is due to the zip being corrupted.
It is possible that the browser somehow mangled the zip file (newline conversions anyone?) during the download process. As mentioned, check the mime type and use the php header() to set the correct MIME type (application/zip).

file download with php (working on apache under localhost)

I'm trying to create a file download page. This page when requested should prompt the user to download a file. Here is the source code for the page:
<?php
header('Content-disposition: attachment; filename=zip.zip')
header('Content-type: application/zip');
readfile('zip.zip');
?>
This works ok.
The problems starts when I want to move the file zip.zip from the folder where this script is in. I tried using relative and absolute URLs but I always get strange results,
the browser still prompts for file download but somehow it's just an odd file name converted from the URI I supplied somthing like ".._.._files_zip.zip instead of ../../files/zip.zip.
Any suggestions why this happens?
Thanks
Use basename to get just the file name:
$file = '../../files/zip.zip';
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Type: application/zip');
readfile($file);

Categories