Hello Richard
Well, thank you for pointing that out to me! I was actually trying to
read
it into RAM, but that was a silly mistake.
But now I have the problem that, even though you are correct, the
problem
seems to still remain, in the sense that I actually *need* to read the
start of the file just to get the header info (so i can retrieve the
Content-Length, and the filename).
Since I tried your method above, I thought I had got the script to
finally
work - which it seemed to - but every file I download with it is
corrupt.
I tried downloading a WinRAR file, and I get 'unexpected end of
archive'.
:( I know for a fact that the archive itself is NOT corrupt, because I
tried it with various different files and all of them ended up
corrupt!
I found some info on the net about fread() and fgets(), and it seems
that
fgets() only reads one line of data up to 1024 bytes, or in my case,
64
bytes. This is what I want to happen, because I need the 'reading' to
abort/break when I have read the required info from the header...I
wish
(and hope!) there was an easier way to get this info other than
searching
for it. :|
Now I am truly vexed because the files are all corrupt when
downloaded,
because I can't see anything wrong with the code. I have added a few
comments, so you can see what I think is the problematic area.
By the way, many thanks for your enthusiastic help so far! - I hope
you
don't take this email to mean I will be mailing you frequently,
believe me
I know you must be busy, and I only mailed you as a last resort!
Thanks again!
<?php
//ob_start();
//ob_end_flush();
//ob_implicit_flush(TRUE);
$rslogin = '';
$rspass = '';
$link = addslashes(trim($_POST['url']));
function cut_str($str, $left, $right)
{
$str = substr(stristr($str, $left), strlen($left));
$leftLen = strlen(stristr($str, $right));
$leftLen = $leftLen ? -($leftLen) : strlen($str);
$str = substr($str, 0, $leftLen);
return $str;
}
// Get the full premium link, and store it in $full_link after the
redirect. *Surely* there is an easier way to get redirections?
if(strlen($link)>0)
{
$url = @parse_url($link);
$fp = @fsockopen($url['host'], 80, $errno, $errstr);
if (!$fp)
{
$errormsg = "Error: <b>$errstr</b>, please try again
later.";
echo $errormsg;
exit;
}
$vars = "dl.start=PREMIUM&uri={$url['path']}&directstart=1";
$out = "POST {$url['path']} HTTP/1.1\r\n";
$out .= "Host: {$url['host']}\r\n";
$out .= "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT
5.1)\r\n";
$out .= "Authorization: Basic
".base64_encode("{$rslogin}:{$rspass}")."\r\n";
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
$out .= "Content-Length: ".strlen($vars)."\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
fwrite($fp, $out.$vars);
unset($string);
while (!feof($fp))
{
$string.= fgets($fp, 64);
}
//Tell us what data is returned
//print($string);
@fclose($fp);
if (stristr($string, "Location:"))
{
$redirect = trim(cut_str($string, "Location:", "\n"));
$full_link = $redirect;
}
//print($string);
//print("<html><body><h1>".$full_link."</h1>");
if ($full_link)
{
// Get info about the file we want to download:
$furl = parse_url($full_link);
$fvars =
"dl.start=PREMIUM&uri={$furl['path']}&directstart=1";
$head = "Host: {$furl['host']}\r\n";
$head .= "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0;
Windows
NT 5.1)\r\n";
$head .= "Authorization: Basic
".base64_encode("{$rslogin}:{$rspass}")."\r\n";
$head .= "Content-Type:
application/x-www-form-urlencoded\r\n";
$head .= "Content-Length: ".strlen($fvars)."\r\n";
$head .= "Connection: close\r\n\r\n";
$fp = @fsockopen($furl['host'], 80, $errno, $errstr);
if (!$fp)
{
echo "The script says <b>$errstr</b>, please try again
later.";
exit;
}
fwrite($fp, "POST {$furl['path']} HTTP/1.1\r\n");
fwrite($fp, $head.$fvars);
while (!feof($fp))
{
//Keep reading the info until we get the filename and size from the
returned Header - is there no easy way
//of doing this? I also don't like the way I have to 'find' the
redirected link (above).??
$tmp .= fgets($fp, 64);
$d = explode("\r\n\r\n", $tmp);
// I tried changing this to if ($d), { etc.., (instead of $d[1])
and
the download of the rar file *wasn't* corrupt, it just had a filetype
of
x-rar-compressed instead of
//apppication/octet-stream, and the filesize was 'unknown' - now
this
is just confusing me...! :( So i think (and guess) the problem of the
file
corruption is here,
//because it must add some data to the filestream which corrupts
it.
Darn.
if($d[1])
{
preg_match("#filename=(.+?)\n#", $tmp, $fname);
preg_match("#Content-Length: (.+?)\n#", $tmp,
$fsize);
$h['filename'] = $fname[1] != "" ? $fname[1] :
basename($furl['path']);
$h['fsize'] = $fsize[1];
break;
}
}
@fclose($fp);
//print($tmp);
$filename = $h['filename'];
$fsize = $h['fsize'];
//Now automatically download the file:
@header("Cache-Control:");
@header("Cache-Control: public");
@header("Content-Type: application/octet-stream");
@header("Content-Disposition: attachment;
filename=".$filename);
@header("Accept-Ranges: bytes");
if(isset($_SERVER['HTTP_RANGE']))
{
list($a, $range)=explode("=",$_SERVER['HTTP_RANGE']);
$range = str_replace("-", "", $range);
$new_length = $fsize - $range;
@header("HTTP/1.1 206 Partial Content");
@header("Content-Length: $new_length");
}
else
{
@header("Content-Length: ".$fsize);
}
$fvars =
"dl.start=PREMIUM&uri={$furl['path']}&directstart=1";
$head = "Host: {$furl['host']}\r\n";
$head .= "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0;
Windows
NT 5.1)\r\n";
$head .= "Authorization: Basic
".base64_encode("{$rslogin}:{$rspass}")."\r\n";
$head .= "Content-Type:
application/x-www-form-urlencoded\r\n";
if($range != "") $head .= "Range: bytes={$range}-\r\n";
$head .= "Content-Length: ".strlen($fvars)."\r\n";
$head .= "Connection: close\r\n\r\n";
$fp = @fsockopen($furl['host'], 80, $errno, $errstr);
if (!$fp)
{
echo "<span style='color:#688000;
background-color:#BBDB54;
font-size : 10pt; text-decoration: none; font-family: Trebuchet
MS;'>The
script says <b>$errstr</b>, please try again later.</span>";
exit;
}
@stream_set_timeout($fp, 300);
fwrite($fp, "POST {$furl['path']} HTTP/1.1\r\n");
fwrite($fp, $head.$fvars);
fflush($fp);
while (!feof($fp))
{
echo fread($fp, 2048);
//ob_flush(); //php.net suggestion
}
//These were here originally, but I don't even know if I am supposed
to
have them here.
// flush();
// ob_flush;
@fclose($fp);
exit;
}
}
else
{
$data = "<form method=\"post\">\n";
$data .= "<input type=\"text\" id=\"url\"
style=\"text-align:center\" name=\"url\" size=\"60\"
onfocus=\"if(this.value=='Enter rapidshare.com URL
here'){this.value=''}\">\n";
$data .= "<br><input type=\"submit\"
value=\"Download\"></form>";
echo $data;
}
?>