Re: Timeout while waiting for a server->client transfer to start (large files)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thanks

I have already another post dealing with this issue. (check newsgroup for Server to client file transfer always corrupt).

I had figured out the problem that was corrupting the file, it is the response headers that are being added to the file when it is downloaded, and i don't know how to trim them. I am using a different trim method i 'borrowed' from another script (where it seems to work perfectly!), and I just can't understand why it won't work for me, unless as u say, there are other errors being output, but I have looked at the text file and I don't see anything other than the headers there. When I use the trim script to remove them, it also seems to remove part of the start and end of the text file.

I think the most annoying aspect of whole thing is why it is so difficult to find a solution to this problem, i'm sure other people must have come across this problem?

thanks again :)

On Sun, 03 Feb 2008 16:28:34 -0000, Richard Lynch <ceo@xxxxxxxxx> wrote:

You can use filesize() to get the file size...
http://php.net/filesize

If that's not going to work because you are stripping out part of the
file, or something, Use fgets to get the header info, and then use
fseek to reset the file pointer to the beginning:
http://php.net/fseek
<?php fseek($file, 0);?>

You can then read as much or as little as you like with fread.

As far as the corrupt files go, compare what you got with the download
and the original in a text editor or a hex editor to see what
happened.

You might have some PHP warnings or notices at the front of the file,
or at the end, messing the file contents up.

On Thu, January 31, 2008 12:11 pm, szalinski wrote:
On Thu, 31 Jan 2008 00:02:55 -0000, Richard Lynch <ceo@xxxxxxxxx>
wrote:

<snip>


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;
}
?>




--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux