I have a zip files that I want users to be able to download. The trick is I don't want the users to see what the url is and I don't want to download the file to my server.
So I want users to click a link like this:
http://example.com/download/4
which server-side accesses my S3 bucket with this url:
https://s3.amazonaws.com/my-bucket/uploads/4.zip
I've tried cURL, using S3 methods, and various headers() in my download($file_id) function but can't get this to work. This has to be easy, right?
Your right, its quite easy. Probably you will have to write something like this:
$path = '/my-bucket/uploads/4.zip'; // the file made available for download via this PHP file
$mm_type="application/x-compressed"; // modify accordingly to the file type of $path, but in most cases no need to do so
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("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary\n");
readfile($path); // outputs the content of the file
exit();
You set various headers to make your user download the .zip. Afterwards you put your file into the output buffer with readfile() Afterwards you end your script with exit() for security's sake. This should work for you! Remember to change the path to your file.
Thanks #Xatenev for the help. This is actually what worked for me:
$path = '/my-bucket/uploads/4.zip'; // the file made available for download via this PHP file
$mm_type="application/zip"; // modify accordingly to the file type of $path, but in most cases no need to do so
header("Content-Type: " . $mm_type);
header('Content-Disposition: attachment; filename="'.basename($path).'"');
readfile($path); // outputs the content of the file
exit();
Related
<?php
$file = $_GET['name'];
$path = './curr/'.$file.'.pdf'; // the file made available for download via this PHP file
$mm_type="application/pdf"; // modify accordingly to the file type of $path, but in most cases no need to do so
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("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary\n");
readfile($path); // outputs the content of the file
?>
This is a snippet of code in file.php. I am referring to the file using:
File 1
The intent is that on click of the link, ./curr/First File.pdf should download. I do get a download, but on inspecting, it's the webpage with the pdf embedded in the file. Could anyone assist?
If you want to have just the PDF loaded, the above code is all code to be executed.
Drop all surrounding menus, header or footers. Make sure, that no HTML or any other output besides the PDF from readfile() remains, when calling this link.
Try to change the content type to :
header("Content-Type: application/force-download");
I have the following code to push a zip file for download.
$filename = "ResourcePack_".time().".zip";
$destination = $basepath."downloads/$filename";
if($this->createdownload($files,$destination,false)){
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Length: ". filesize("$destination").";");
header("Content-Disposition: attachment; filename='$filename'");
header("Content-Type: application/octet-stream; ");
header("Content-Transfer-Encoding: binary");
ob_end_flush();
#readfile($destination);
if(file_exists($destination)){
unlink($destination);
}
}
I know the createdownload function is working to generate the zip file just fine because I see the file being created on the server. The problem is file is being written to the browser as a bunch of garbage instead of opening a download stream. Am I missing something in my headers?
EDIT
I was right. My problem is not with the php, but that calling the php file that generates this code via a JQuery $.ajax call is the problem. Using $.ajax automatically sets the Accept-Encoding request header to values incompatible with zip files. So, intead of using $.ajax I just used a simple window.open javascript command to call the same php page and it works just fine with the headers.
try to put a die after the #readfile
and remove the #, to see if you have any other error related with the file reading.
i have some code doing the same thing and this works for me:
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false); // required for certain browsers
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-type: application/zip');
//header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($destination));
readfile($destination);
die();
try passing proper type for that file. I think its fileinfo mime type see http://www.php.net/manual/en/ref.fileinfo.php
header("Content-Type: $file_type");
Also you have semicolon after octet-stream remove it
header("Content-type: application/octet-stream");
I've been wrestling around with this for awhile now. I am trying to make it so when a user click a link it will force a download. Here's my code so far:
<?php
function Download()
{
$fullpath = $_SERVER['DOCUMENT_ROOT']."front.dwg"; //Full path of document
$filename = "front.dwg"; //Document file nmae
$mm_type="application/octet-stream";
header("Cache-Control: public, must-revalidate");
header("Pragma: hack");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($fullpath)) );
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary\n");
}
?>
<html>
<body>
Test
</body>
</html>
Your going to need to pull out your function and save it as "download.php"
Then just have a link that goes to it:
<a href="download.php">
Download.php should look like this:
$fullpath = $_SERVER['DOCUMENT_ROOT']."front.dwg"; //Full path of document
$filename = "front.dwg"; //Document file nmae
$mm_type="application/octet-stream";
header("Cache-Control: public, must-revalidate");
header("Pragma: hack");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($fullpath)) );
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary\n");
PHP is not a client-side function. You can't say onclick="somePHP".
You need a separate PHP script where you will force your download in, and simply link to that script.
In this script, you also need to actually output the file contents.
You need to set the appropriate calls to header first. These have worked for me:
header('Pragma: public'); // required
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header("Content-disposition: attachment; filename=\"{$filename}\"");
header("Content-Type: {$mime}"); // also works with file extension
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($filename));
readfile($filename);
die();
You can never FORCE a download. You can change the window location to the download file and it will prompt them, but if you could force downloads, there would be some major security issues.
First, your $fullpath may not contain the data you expect, because you did not insert a forward slash ('/') before the filename. This is correct:
$fullpath = $_SERVER['DOCUMENT_ROOT']."/front.dwg";
You can check the contents of $fullpath using error_log( "Fullpath: $fullpath" ); or echo "Fullpath: $fullpath\n".
Second, you need to make the PHP portion of your code a standalone script. You will not be able to embed PHP function calls in Javascript. All of your PHP executes before the Javascript runs, so you need a way to call the PHP separately.
Third, you should verify that the file exists and is readable using file_exists() and is_readable(). If PHP reports that the file does not exists, you should specify the full path. If it is not readable, you can change the file permissions to allow your PHP script to read it.
I'm using a script to download video, but it take lot of time to download. Are there any processes or other scripts that could help me?
// set headers
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("Content-Type: $mtype");
header("Content-Disposition: attachment; filename=\"$asfname\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $fsize);
// download
// #readfile($file_path);
$file = #fopen($file_path,"rb");
if ($file) {
while(!feof($file)) {
print(fread($file, 1024*100));
flush();
if (connection_status()!=0) {
#fclose($file);
die();
}
}
#fclose($file);
}
Using the readfile() function (as you originally had) will allow you to spool directly from the file to output, rather than using a chunking loop and printing as you're doing. So why have you chosen to do this chunk loop?
As above, readfile() is one way.
The other, even more preferred method depends on your webserver. NginX, Lighttpd and there's also a module for Apache, allows you to pass a header with a filepath/name to the server, and it will send the file directly from the server itself, and so not need to use PHP resources to do it. If thats not possible, then readfile() is the best you probably have - if you can't just give someone a direct URL to download it.
I am downloading a file from another server. I wish to push this file to my users rather than saving it to my server.
In other words, pass them the file handle so it just passes through my server and saves to their machine. How can I do this? I have this so far:
$handle = fopen($_GET['fileURL'], 'r');
$filename = stream_get_contents($handle);
How do I push this to the user, maybe using headers?
Thank you for any help and direction.
EDIT
I have the headers:
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: $ctype");
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
readfile("$filename");
Its just that it doesn't push the headers. I just get a blank page after about 15 seconds which looks like it downloading the file but not giving it to me.
I wish for the script to immediately send the headers to the user as a stream.
exit();
You can try this
$filetype = mime_content_type($filename);
header('Content-type: '.$filetype);
header('Content-Disposition: attachment; filename="'.$filename.'"');
UPDATE for your EDIT:
Do you have errors disabled, since this sounds like the headers already sent error?
error_reporting(E_ALL | E_STRICT);
You don't have to use fopen() when using readfile();
Just include the filename inside readfile() like this:
readfile($_GET['fileUrl']);
Although this is very dangerous security-wise as the user could specify any file on your file server. If you only have a few files you want someone to be able to download perhaps you should store them in an array (or database, preferebly)
Here's an array example:
$files = array('file1.jpg', 'file2.png', 'file3.pdf');
//assume $_GET['file_id'] == 0, 1 or 2
if (file_exists($files[$_GET['file_id']]))
readfile($files[$_GET['file_id']]);