Re: Timeout while waiting for a server->client transfer to start (large files)
| From: | Casey | Date: | Sat, 02 Feb 2008 02:03:55 +0000 |
| Subject: | Re: Timeout while waiting for a server->client transfer to start (large files) | ||
| References: | 1 2 3 4 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-268552@lists.php.net to get a copy of this message | ||
On Feb 1, 2008, at 5:45 PM, szalinski <barneytramble@gmail.com> wrote:
On Thu, 31 Jan 2008 07:13:55 -0000, Per Jessen <per@computer.org> wrote:I had no time to read the whole thing, but maybe remove the trailing ?Richard Lynch wrote:Well I got it to work, much thanks to Richard Lynch, but now everytime I download a file, it is corrupt. For example, when I download small .rar file, just to test, it is always corrupt ('Unexpected end of archive'). I also cleared my browser cache just to be sure, but same problem. Here is the code as it stands. I just can't get my head around why it wouldn't be working as it is... <?php //ob_start(); //ob_end_flush(); //ob_implicit_flush(TRUE); $rslogin = ''; $rspass = ''; $link = addslashes(trim($_POST['link'])); 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)Your script is reading the whole file, 64 measly bytes at a time, into a monstrous string $tmp. Then, finally, when you've loaded the whole [bleep] file into RAM in $tmp, you just echo it out, right? Don't do that. :-) while (!feof($fp)){ echo fread($fp, 2048); }And if the OP is opening the file anyway, he might as well use readfile() instead. /Per Jessen, Zürich{ $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); while (!feof($fp)) { $string .= fgets($fp, 256); } //Tell us what data is returned //print($string); @fclose($fp);if (stristr($string, "Location:")) { $redirect = trim(cut_str($string, "Location:", "\n")); $full_link = addslashes(trim($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, 256); $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 //application/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);$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); } $f2vars = "dl.start=PREMIUM&uri={$furl['path']}&directstart=1"; $head2 = "Host: {$furl['host']}\r\n"; $head2 .= "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"; $head2 .= "Authorization: Basic ".base64_encode("{$rslogin}:{$rspass}")."\r\n"; $head2 .= "Content-Type: application/x-www-form-urlencoded\r\n"; if($range != "") $head2 .= "Range: bytes={$range}-\r\n"; $head2 .= "Content-Length: ".strlen($fvars)."\r\n"; $head2 .= "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, 120); fwrite($fp, "POST {$furl['path']} HTTP/1.1\r\n"); fwrite($fp, $head2.$f2vars); fflush($fp); while (!feof($fp)) { $download = fread($fp, 2048); echo $download; //ob_flush(); //php.net suggestion }//These two buggers 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=\"link\" style=\"text-align:center\" name=\"link\" size=\"60\" onfocus=\"if(this.value=='Enter rapidshare.com URL here'){this.value=''}\">\n"; $data .= "<br><input type=\"submit\" value=\"Download\"></form>"; echo $data;} ?> Thanks to anyone who has already helped, I hope some genius can spot an obvious error, because this is just beyond me! --PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
.