• Unfortunately, we have experienced significant hard drive damage that requires urgent maintenance and rebuilding. The forum will be a state of read only until we install our new drives and rebuild all the configurations needed. Please follow our Facebook page for updates, we will be back up shortly! (The forum could go offline at any given time due to the nature of the failed drives whilst awaiting the upgrades.) When you see an Incapsula error, you know we are in the process of migration.

[php] file relay/force download

Custom Title Activated
Loyal Member
Joined
Nov 28, 2004
Messages
2,236
Reaction score
0
I am stuck.

I am making a file download relay/proxy/tunnel/whatever script. I need a script which relays download through server running this php script.

Basically I am doing something like:
PHP:
$theFile = 'http://www.porno.com/downloads/alotpr0n.zip';
       header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");
       header ("Content-Type: application/octet-stream");
       header ("Content-Length: " . filesize($theFile));
       header ("Content-Disposition: attachment;");
       readfile($theFile);
Well, that is not working... I got some more examples with "header" functions, but that does not seem to be working..

SO, could anyone help me by giving the correct header syntax (or maybe there is something else that could be used down here..?). It would be nice that the script would show the correct download filename and file lenght to know how much it is left to download the file.

I also had tried to use "file_get_contents" and "file" and then I just echo the file being in that var, but this is not a good thing to do, because the file can be 1GB+ and I don't really want to load such stuff into the memory...

Thanks for showing me the right way... I DO HOPE ANYONE RESPONDS!

TY
 
Newbie Spellweaver
Joined
Jul 10, 2005
Messages
16
Reaction score
0
PHP:
$fp = fopen($file,"r");
$buffer = fread($fp,filesize($file));

header("Content-type: application/x-unknown-content-type-text");
header("Content-Lenght: ".filesize($file));
header("Content-Disposition: inline; filename=\"" . basename($file) . "\"");

echo $buffer;

try this one.
 
Custom Title Activated
Loyal Member
Joined
Nov 28, 2004
Messages
2,236
Reaction score
0
well, the file in all cases will be not in the same machine.
when i execute script + $file = "http://www.fknevezis.lt/m.png"; (my sig's image)
i got a lot of errs
Code:
Warning: filesize(): Stat failed for http://www.fknevezis.lt/m.png (errno=2 - No such file or directory) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 7

Warning: Cannot modify header information - headers already sent by (output started at C:\web\http_root\www\_learning\file_manipulation\12.php:7) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 9

Warning: filesize(): Stat failed for http://www.fknevezis.lt/m.png (errno=2 - No such file or directory) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 10

Warning: Cannot modify header information - headers already sent by (output started at C:\web\http_root\www\_learning\file_manipulation\12.php:7) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 10

Warning: Cannot modify header information - headers already sent by (output started at C:\web\http_root\www\_learning\file_manipulation\12.php:7) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 11
well, and I don't see where the header was set before so I don't understand where the error is..
 
Initiate Mage
Joined
Nov 26, 2005
Messages
1
Reaction score
0
Warning: filesize(): Stat failed for (errno=2 - No such file or directory) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 7
Warning: Cannot modify header information - headers already sent by (output started at C:\web\http_root\www\_learning\file_manipulation\12.php:7) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 9
Warning: filesize(): Stat failed for (errno=2 - No such file or directory) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 10
Warning: Cannot modify header information - headers already sent by (output started at C:\web\http_root\www\_learning\file_manipulation\12.php:7) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 10
Warning: Cannot modify header information - headers already sent by (output started at C:\web\http_root\www\_learning\file_manipulation\12.php:7) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 11

"Cannot modify header information - headers already sent by" means something has been output to the webpage. ANYTHING, absolutely ANNNYYYYTHING before the header functions can set this off.

Example:

Code:
 <?php
    header("Location: foo.bar");
?>
See the whitespace before opening the "<?php" tag? That white space would be sent to the browser which out void any other headers you wish to send.

Code:
<?php
    include("index.php");
    header("Location: foo.bar");
?>
If you are including a file, that file might be sending outputs to your browser which would also null out your headers.

You need to be sure you have the correct header formatting scheme.


Just a small note for the filesize function; I highly doubt that you can use filesize() on remote files. Logically it doesn't make sense to give that much power to a function. If you can't pull your remote file, you can try using fsockopen() to connect to your remote file.




Hope this helps some :)

--
ashton_
 
Custom Title Activated
Loyal Member
Joined
Aug 8, 2004
Messages
3,892
Reaction score
20
Try losing the content.length bit.. As mentioned by ashton, you probably can't get the filesize of a remote file unless you load it into memory which you didn't want to do.

Ow, and that headers already sent error is caused by the error message, since that is output and as has been said: output means broken header ;)
 
Custom Title Activated
Loyal Member
Joined
Nov 28, 2004
Messages
2,236
Reaction score
0
well, nothing post a header before this...
PHP:
<?php
$file = "http://www.fknevezis.lt/m.png";
$fp = fopen($file,"r");
$buffer = fread($fp,filesize($file));
header("Content-type: application/x-unknown-content-type-text");
header("Content-Lenght: ".filesize($file));
header("Content-Disposition: inline; filename=\"" . basename($file) . "\"");
echo $buffer;
?>
 
Custom Title Activated
Loyal Member
Joined
Feb 27, 2004
Messages
1,378
Reaction score
50
it is best practice to actually, check if the file is there ...

$fp = fopen....
if ($fp) {

do ur thing

**

mind is not working atm... will test later.
 
Last edited:
Custom Title Activated
Loyal Member
Joined
Nov 28, 2004
Messages
2,236
Reaction score
0
hey, I'm a beginner..
but the file is there. have look when have time if you know how it should go.
 
Newbie Spellweaver
Joined
Jul 10, 2005
Messages
16
Reaction score
0
Code:
Warning: filesize(): Stat failed for http://www.fknevezis.lt/m.png (errno=2 - No such file or directory) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 7

Warning: Cannot modify header information - headers already sent by (output started at C:\web\http_root\www\_learning\file_manipulation\12.php:7) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 9

Warning: filesize(): Stat failed for http://www.fknevezis.lt/m.png (errno=2 - No such file or directory) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 10

Warning: Cannot modify header information - headers already sent by (output started at C:\web\http_root\www\_learning\file_manipulation\12.php:7) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 10

Warning: Cannot modify header information - headers already sent by (output started at C:\web\http_root\www\_learning\file_manipulation\12.php:7) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 11

this is your error...
to begin with, this "headers already sent by" is only being shown because of the 1st error (this is whats being returned b4 the headers...). so work on the 1st error:

Code:
Warning: filesize(): Stat failed for http://www.fknevezis.lt/m.png (errno=2 - No such file or directory) in C:\web\http_root\www\_learning\file_manipulation\12.php on line 7

by reading it you should understand the file doesnt exist. since you said it surely does, dont be so lazy. check and you'll notice that it doesnt work with remote files. but if ur even less lazy, you'll find this workaround by someone:

PHP:
<?php
function filesize_url($url){
   return ($data = @file_get_contents($url)) ? strlen($data) : false;
**
?>

use it to get the filesize... and enjoy.

ps: the ** thing should be a bracket to close the function -> { <- thing. replace it ;P stupid forum
 
Last edited:
Custom Title Activated
Loyal Member
Joined
Nov 28, 2004
Messages
2,236
Reaction score
0
okey, I re-wrote the code and now it is correct, but listen. I said it should RELAY, not DOWNLOAD AND SEND. Now the file is being loaded into $buffer and only after server downloads it to dunno where or in memory only then the script allows to save the file. Now imagine the file size is 1GB. So how do I stream that file through the php script?
PHP:
<?php
//$file = "http://www.fknevezis.lt/m.png";
$file = "http://mamboforge.net/frs/download.php/7835/MamboV4.5.3h.tar.gz";

$fp = fopen($file,"r");
$filesize = filesize_url($file);
$buffer = fread($fp,$filesize);

header("Content-type: application/x-unknown-content-type-text");
header("Content-Lenght: ".$filesize);
header("Content-Disposition: inline; filename=\"" . basename($file) . "\"");
echo $buffer;




function filesize_url($url)
{ 
	return ($data = @file_get_contents($url)) ? strlen($data) : false; 
**
?>
 
Custom Title Activated
Loyal Member
Joined
Nov 28, 2004
Messages
2,236
Reaction score
0
ohey, here's what I was looking for. combined 4 scripts and got the following:
PHP:
<?php

///////////////////////////
//DATA
///////////////////////////
//$filename = "http://download.microsoft.com/download/f/0/3/f03c202d-1ce4-4267-9393-a8a4b400a982/Vs6sp6B.exe";
$filename = "http://mamboforge.net/frs/download.php/7835/MamboV4.5.3h.tar.gz";
$filesize = filesize_url($file);

// required for IE, otherwise Content-disposition is ignored
if(ini_get('zlib.output_compression'))
  ini_set('zlib.output_compression', 'Off');

//filetype manipulation
$file_extension = file_type($filename);
$ctype = ctype($file_extension);

//output header
header("Pragma: public"); // required
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-Type: $ctype");
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".$filesize);
readfile("$filename");
exit();





///////////////////////////
//FUNCTIONS
///////////////////////////

//function for finding out the file size
function filesize_url($url)
{ 
	$filesize = ($data = @file_get_contents($url)) ? strlen($data) : false;
	return $filesize;
**

//function for file type determination
function file_type($filename)
{
	$file_extension = strtolower(substr(strrchr($filename,"."),1));
	return $file_extension;
**

//function for the file ctype determination
function ctype($file_extension)
{
	switch( $file_extension )
		{
		case "pdf": $ctype="application/pdf"; break;
		case "exe": $ctype="application/octet-stream"; break;
		case "zip": $ctype="application/zip"; break;
		case "doc": $ctype="application/msword"; break;
		case "xls": $ctype="application/vnd.ms-excel"; break;
		case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
		case "gif": $ctype="image/gif"; break;
		case "png": $ctype="image/png"; break;
		case "jpeg": $ctype="image/jpg"; break;
		case "jpg": $ctype="image/jpg"; break;
		default: $ctype="application/force-download";
		**

	return $ctype;
**
?>
but the filesize is not shown. now I just need improvemensts, and if you know how to add filesize without downloading the file at first and only then reading the lenght as melo_yello's code does
 
Last edited:
Custom Title Activated
Loyal Member
Joined
Aug 8, 2004
Messages
3,892
Reaction score
20
melo_yello said:
PHP:
<?php
function filesize_url($url){
   return ($data = @file_get_contents($url)) ? strlen($data) : false;
**
?>
use it to get the filesize... and enjoy.

Problem with that is this piece'a code: file_get_contents. If you look up the php docs for this baby you'll know why suddenly you can get the filesize as well as why it starts downloading the file:

The important part there is:
file_get_contents -- Reads entire file into a string
In other words, it can get remote filesize only because it loads the file into a string and then checks the string for its length.

Now, you can EITHER load the file onto the server, OR get the filesize. Not both. At least, not unless you do it some totally different way.

A totally different way would be for instance to store all file info into a local database. I'm not sure what exactly you're planning with this, but if its about a not-regularly-changing amount of files you can simply add their info and length into a local database along with links.

Other option would be to schedule a cronjob to download all the files and put their length into the database, or even run that on the remote server if you can since it'll save you the trouble of your server having to download everything.

Hope this makes enough sence :D
 
Custom Title Activated
Loyal Member
Joined
Feb 27, 2004
Messages
1,378
Reaction score
50
actually i dont see the reason for this.. not unless ur trying to make a proxy downloader from rapidshare that disables timelimit, bandwidth limit, etc etc.
 
Custom Title Activated
Loyal Member
Joined
Nov 28, 2004
Messages
2,236
Reaction score
0
john_d said:
actually i dont see the reason for this.. not unless ur trying to make a proxy downloader from rapidshare that disables timelimit, bandwidth limit, etc etc.
found a function for filesize
PHP:
function remote_file_size($url) 
{
   $head = "";
   $url_p = parse_url($url);
   $host = $url_p["host"];
   $path = $url_p["path"];
	
   $fp = fsockopen($host, 80, $errno, $errstr, 20);
   if(!$fp) 
   {
   return false;
   ** 
   else 
   {
       fputs($fp, "HEAD ".$url." HTTP/1.1\r\n");
       fputs($fp, "HOST: dummy\r\n");
       fputs($fp, "Connection: close\r\n\r\n");
       $headers = "";
       while (!feof($fp))
	   {
           $headers .= fgets ($fp, 128);
       **
   **
   fclose ($fp);
   $return = false;
   $arr_headers = explode("\n", $headers);
   foreach($arr_headers as $header)
   {
       $s = "Content-Length: ";
       if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s))
	   {
           $return = substr($header, strlen($s));
           break;
       **
   ** 
   return $return;
**
seems to be OK, but only for HTTP files.


well, john_d, imagine I am in a big LAN. lan users got 128kb/s connection limit. There is a server, which has no connection limit. Now imagine I have the access to that server and can relay file downloads..
 
Custom Title Activated
Loyal Member
Joined
Feb 27, 2004
Messages
1,378
Reaction score
50
would u still be downloading at 128kb/s ... doesnt matter wat the server speed is.. ur still will be stuck at 128... but i do see the relevance of this... since sometimes i use my DD servers to download large files for me and ill jsut get it from there later on.
 
Custom Title Activated
Loyal Member
Joined
Nov 28, 2004
Messages
2,236
Reaction score
0
the script I am making to will be easier solution than the one I use now. I speed up my connection from <128kbps to ~2400kbps. that's a lot for me..
 
Back
Top