I currently have several servers, the main ones a web server and an internal storage server. Data is stored in a SQL server database.
Without giving too much access to the user, how would I pull a specific document from the storage server for display to the user from the web server?
For example, I have document c:/memberID/info.pdf on the storage server and I want to display it to the client via PHP without giving them access to the internal storage server.
I hope this makes sense!
Look into readfile as well as headers
<?php
$file = 'monkey.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
Related
I want to "proxy" a file located on a remote server (let's call it Server B) and force its download to the visitor, from Server A.
Only Server A can access the ressource on Server B (IP address secured). The ressource can weight up to a few gigabytes.
Here is my code so far:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$filename);
header('Content-Transfer-Encoding: chunked');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
$stream = fopen('php://output', 'w');
$ch = curl_init($ruri);
curl_setopt($ch, CURLOPT_READFUNCTION, function($ch, $fd, $length) use ($stream) {
return fwrite($stream, fread($fd, $length));
});
curl_exec($ch);
curl_close($ch);
It works partially.
Problem number 1:
The visitor cannot browse any page of the website on Server A while he is downloading the ressource. Why?
Problem number 2:
It does not support pause or resume download. Apparently I can solve it using "range" headers. I did not try yet since "problem number 1" is a big problem, and I would like to solve it first before going further in that direction.
Please note:
I do not want the ressource to be fully downloaded on Server A's disk before serving it to the visitor, I want it to be "forwarded" directly to the visitor (aka "proxy"?)
I read posts about readfile() and file_get_content(), I tried, same problems. Not even mentionning how much these functions "stress" Server A (CPU, Memory), especially with big files.
Isn't there a way to do it more efficiently? I mean without PHP, but rather trough Apache or Nginx?
I am willing to "proxy" a file located on a remote server (let's call it Server B) and force its download to the visitor, from Server A.
Only Server A can access the ressource on Server B (IP address secured). The ressource can weight up to a few gigabytes.
Here is my code so far:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$filename);
header('Content-Transfer-Encoding: chunked');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
$stream = fopen('php://output', 'w');
$ch = curl_init($ruri);
curl_setopt($ch, CURLOPT_READFUNCTION, function($ch, $fd, $length) use ($stream) {
return fwrite($stream, fread($fd, $length));
});
curl_exec($ch);
curl_close($ch);
It works partially.
Problem number 1:
The visitor cannot browse any page of the website on Server A while he is downloading the ressource. Why?
Problem number 2:
It does not support pause or resume download. Apparently I can solve it using "range" headers. I did not try yet since "problem number 1" is a big problem, and I would like to solve it first before going further in that direction.
Please note:
I do not want the ressource to be fully downloaded on Server A's disk before serving it to the visitor, I want it to be "forwarded" directly to the visitor (aka "proxy"?)
I read posts about readfile() and file_get_content(), I tried, same problems. Not even mentionning how much these functions "stress" Server A (CPU, Memory), especially with big files.
Isn't there a way to do it more efficiently? I mean without PHP, but rather trough Apache or Nginx?
Header("location:index.php"); is not working for me.
$file is path of file.
if (file_exists($file)) {
header('Content-Description: File Transfer');
//header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
header("Content-Type: application/force-download");
readfile($file);
header("location:index.php");
exit;
}
Your browser makes a call to the server. The server responds with headers ("I will be sending a file") and sends the content. Browser reads headers and instead of showing the new page it offers you to save the file. All further actions are ignored.
If you want both file download and redirect, you have to send the request for download to another container (new tab, new window, iframe) and redirect the main window elsewhere with javascript.
I am trying to force the browser to download an mp3 when the user visits this site. The issue I am running into is if i set the Content-Length header the page throws a 502 Bad Gateway error, and if I don't it attempts to download the file, but the file is 0 bytes in size. The site happens to be running wordpress. Any direction would be really appreciated. I am not familiar with wordpress.
$file = '../uploads/2015/01/Thunder.mp3';
header('Content-type: application/mp3');
header("Content-Disposition: attachment; filename=\"$file\"");
header('Content-Length: '.filesize($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
Try Adding:
readfile($file);
after:
header('Pragma: public');
I have a host for store data and a download host (this host doesn't have database). I want to read a file from download host in store host and give it to user for download but I don't want to use monthly bandwidth transfer of store host when user is downloading file and just use download host bandwidth transfer.
There are two ways that I know:
ftp_get download the file and save it in a local file and then set header for download. I don't want use this way because download file in store host.
// in store host
$local_file = 'app.apk';
$ftp_file = '/uploads/2015/06/1eb6a628c60bb69a6b6092d03e252c29.apk';
// download file and save it in local
ftp_get($conn_id , $local_file, $ftp_file, FTP_BINARY);
$file_name = 'app.apk';
$file_size = filesize($local_file);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $file_name);
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $file_size);
readfile($local_file);
I don't know file_get_contents use bandwidth transfer of store host when user is downloading file or not.
// in store host
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $file_name);
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $file_size);
// readfile($local_file);
$c = file_get_contents('ftp://login:pass#download-host.com/uploads/2015/06/app.apk');
echo $c;
I don't want to use bandwidth transfer in store host; Which way can I use? Way 2 or another way?
There's no way to download a contents from the "download host" directly to the client, without providing the client with all the information needed for the download ("download link").
If you need to hide the download information from the client, you need to download the file on the "store host" and then forward it to the client. Hence you are consuming bandwidth data of the "store host". It does not matter what technology, protocol or function you use. And the ftp_get and file_get_contents("ftp://...") use both the same code behind anyway.
Simply said, there's no way to both hide the download information from the client and not use bandwidth data of the "store host".