5

Basically I want to download a file from an external host and pass it directly to the user without having to be saved on the server, in practice, act as a proxy for this file, so that the request is always made from my server and not the user. Should I simulate this request:

GET / servername / filename.ext HTTP/1.1 (any large file) 
Host: namehost 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv: 27.0) Gecko/20100101 Firefox/27.0 
Accept: text / html, application / xhtml + xml, application / xml; q = 0.9, * / * q = 0.8 
Accept-Language: en-us, en; q = 0.8, en-US; q = 0.5, en; q = 0.3 
Accept-Encoding: gzip, deflate 
Referer: sitename / ... 
Cookie: .... 
Connection: keep-alive 

I already have the necessary cookies, and all the necessary headers but I can not start the download, I tried using different scripts in Curl, but the download does not start.

Can anyone help me please.

Akhilesh
  • 1,064
  • 15
  • 28
user3297894
  • 61
  • 1
  • 4

2 Answers2

5

You want to fetch the file from remote server and serve it to your user. Below is the fetch and serve proxy sample code. I am expecting that you know the file name, URL, file extension and mime type

<?php
function get_size($url) {
    $my_ch = curl_init();
    curl_setopt($my_ch, CURLOPT_URL,$url);
    curl_setopt($my_ch, CURLOPT_HEADER, true);
    curl_setopt($my_ch, CURLOPT_NOBODY, true);
    curl_setopt($my_ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($my_ch, CURLOPT_TIMEOUT, 10);
    $r = curl_exec($my_ch);
    foreach(explode("\n", $r) as $header) {
        if(strpos($header, 'Content-Length:') === 0) {
            return trim(substr($header,16));
        }
    }
    return '';
}
// Set operation params
$mime = filter_var($_GET['mime']);
$ext = str_replace(array('/', 'x-'), '', strstr($mime, '/'));
$url = base64_decode(filter_var($_GET['url']));
$name = urldecode($_GET['title']). '.' .$ext;

// Fetch and serve
if ($url)
{
$size=get_size($url);
// Generate the server headers
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE)
{
header('Content-Type: "' . $mime . '"');
header('Content-Disposition: attachment; filename="' . $name . '"');
header('Expires: 0');
header('Content-Length: '.$size);
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
}
else
{
header('Content-Type: "' . $mime . '"');
header('Content-Disposition: attachment; filename="' . $name . '"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Content-Length: '.$size);
header('Pragma: no-cache');
}

readfile($url);
exit;
}

// Not found
exit('File not found');
?>

Usage: simplly save it as download.php and call like

$encoded_url =  base64_encode($file_to_download_url);
$download_url = 'http://www.example.com/download.php?mime='.$mime.'&title='.$title.'&url='.$encoded_url;

It will work like a charm!

Akhilesh
  • 1,064
  • 15
  • 28
  • thank you for your answer, your method works, but I'm not sure that you use the bandwidth of my server to download because controlling the bandwidth used in my server remains the same.One more thing is possible hide url sourced to the user? Thanks for your answer again – user3297894 Feb 12 '14 at 00:13
  • whatever method you use, your server BW will consume. Your server is acting like a proxy. Fetch and serve comes with a cost. You can hide url using base64_encode and retrieve it using base64_decode. – Akhilesh Feb 12 '14 at 11:04
  • thanks, with your help I was able to understand and do what I wanted;), I ask you one other thing, if you can help me understand, with this method the link is created in this way htttp :/ / serverexterno / linkname if I wanted the download link that the user was instead http://myserver/nomelink should be possible to do it? basically you download the file on my server and passes the user immediately but with the new web address, and after downloading it from being erased after a certain time? – user3297894 Feb 14 '14 at 13:50
  • Basically you don't want to show the exact URL to your users, right? If it is then you can hide url using base64_encode and retrieve it using base64_decode. See example above, I have updated the code – Akhilesh Feb 15 '14 at 16:44
  • many thanks, that thou hast advised with base64_encode I did, and succeeds perfectly, what I wanted to do now was to throw the file on my server and then the USER without but have to click again on download, more or less like the leech of services, from an external link to create a link on their servers, I hope i explained myself better now. Thank you for your time and your answers are very useful and well explained for me to better understand my doubts about php;) – user3297894 Feb 17 '14 at 17:16
  • If your problem solved then you close it as solved by accepting the answer – Akhilesh Feb 17 '14 at 21:40
  • Hello @Akhilesh, Its not working with external mp3 file URL? Can anyone help me ? External file url like ***https://s3-us-west-2.amazonaws.com/soundclouduploads/APS+-+Challa+mix.mp3*** – Sanchit Gupta Jun 16 '16 at 09:49
  • Is above code secure from any exploit attacks if not please update? – Mark Fulghum Dec 05 '17 at 09:48
0

You can simply put the URI of the file that you want to download a the value for the hyperlink:

<a href="URI" target="_blank">Click to download</a>

If you don't want them to click anything, and have the file download right away, you could use the php header() function. See example 1 here: http://uk.php.net/manual/en/function.header.php

wolakpaul
  • 27
  • 2
  • thanks for the reply, but by doing so they call directly the host that contains the files from their browsers, but I would like the request to pass through my server. I would like something like this: client user -> call my server -> external host file external host response file -> my server -> user downloads I hope I explained myself better. – user3297894 Feb 11 '14 at 16:43