改自php reverse proxy prp,,修改了原版中的一些错误,支持了文件上传以及上传文件类型识别,支持指定ip,自适应sae环境。
使用方法
port=8080;$proxy->host=www.jb51.net;//$proxy->ip=1.1.1.1;$proxy->forward_path=;$proxy->connect();$proxy->output();?>
源代码
version=php reverse proxy (prp) 1.0; $this->port=8080; $this->host=127.0.0.1; $this->ip=; $this->content=; $this->forward_path=; $this->path=; $this->content_type=; $this->user_agent=; $this->http_code=; $this->xff=; $this->request_method=get; $this->ims=false; $this->cachetime=72000; $this->lastmodified=gmdate(d, d m y h:i:s,time()-72000). gmt; $this->cookie=; $this->xrequestedwith = ; $this->authorization = ; } function translateurl($servername) { $this->path=$this->forward_path.$_server['request_uri']; if(is_sae)return $this->translateserver($servername).$this->path; if($_server['query_string']==)return $this->translateserver($servername).$this->path; else return $this->translateserver($servername).$this->path.?.$_server['query_string']; } function translateserver($servername) { $s = empty($_server[https]) ? '': ($_server[https] == on) ? s: ; $protocol = $this->left(strtolower($_server[server_protocol]), /).$s; if($this->port==)return $protocol.://.$servername; elsereturn $protocol.://.$servername.:.$this->port; } function left($s1, $s2) { return substr($s1, 0, strpos($s1, $s2)); } function preconnect(){ $this->user_agent=$_server['http_user_agent']; $this->request_method=$_server['request_method']; $tempcookie=; foreach ($_cookie as $i => $value) {$tempcookie=$tempcookie. $i=$_cookie[$i];; } $this->cookie=$tempcookie; if(empty($_server['http_x_forwarded_for'])){$this->xff=$_server['remote_addr']; } else {$this->xff=$_server['http_x_forwarded_for']., .$_server['remote_addr']; }} function connect(){ if(empty($_server['http_if_modified_since'])){$this->preconnect();$ch=curl_init();if($this->request_method==post){curl_setopt($ch, curlopt_post,1);$postdata = array();$filepost = false;$uploadpath = 'uploads/';if (is_sae)$uploadpath = sae_tmp_path;if(count($_files)>0){if(!is_writable($uploadpath)){die('you cannot upload to the specified directory, please chmod it to 777.');}foreach($_files as $key => $filearray){copy($filearray[tmp_name], $uploadpath . $filearray[name]);$proxylocation = @ . $uploadpath . $filearray[name] . ;type= . $filearray[type];$postdata = array($key => $proxylocation);$filepost = true;}}foreach($_post as $key => $value){if(!is_array($value)){$postdata[$key] = $value;}else{$postdata[$key] = serialize($value);}}if(!$filepost){//$postdata = http_build_query($postdata);$poststring = ;$firstloop = true;foreach($postdata as $key => $value){$parameteritem = urlencode($key).=.urlencode($value);if($firstloop){$poststring .= $parameteritem;}else{$poststring .= &.$parameteritem;}$firstloop = false;}$postdata = $poststring;}//echo print_r($postdata);//curl_setopt($ch, curlopt_verbose, 0);//curl_setopt($ch, curlopt_returntransfer, 1);//curl_setopt($ch, curlopt_useragent, mozilla/4.0 (compatible;));$this->sendpost = $postdata;//var_dump(file_exists(str_replace('@','',$postdata['imgfile'])));exit;curl_setopt($ch, curlopt_postfields,$postdata);//curl_setopt($ch, curlopt_postfields,file_get_contents($proxylocation));//curl_setopt($ch, curlopt_postfields,file_get_contents(php://input));}//gets rid of mulitple ? in url$translateurl = $this->translateurl(($this->ip)?$this->ip:$this->host);if(substr_count($translateurl, ?)>1){$firstpos = strpos($translateurl, ?, 0);$secondpos = strpos($translateurl, ?, $firstpos + 1);$translateurl = substr($translateurl, 0, $secondpos);}curl_setopt($ch,curlopt_url,$translateurl);$proxyheaders = array(x-forwarded-for: .$this->xff,user-agent: .$this->user_agent,host: .$this->host);if(strlen($this->xrequestedwith)>1){$proxyheaders[] = x-requested-with: .$this->xrequestedwith;//echo print_r($proxyheaders);}curl_setopt($ch,curlopt_httpheader, $proxyheaders);if($this->cookie!=){curl_setopt($ch,curlopt_cookie,$this->cookie);}curl_setopt($ch,curlopt_followlocation,false);curl_setopt($ch,curlopt_autoreferer,true);curl_setopt($ch,curlopt_header,true);curl_setopt($ch,curlopt_returntransfer,1);$output=curl_exec($ch);$info = curl_getinfo( $ch );curl_close($ch);$this->postconnect($info,$output); }else {$this->lastmodified=$_server['http_if_modified_since'];$this->ims=true; } } function postconnect($info,$output){ $this->content_type=$info[content_type]; $this->http_code=$info['http_code']; //var_dump($info);exit; if(!empty($info['last_modified'])){$this->lastmodified=$info['last_modified']; } $this->resultheader=substr($output,0,$info['header_size']); $content = substr($output,$info['header_size']);if($this->http_code=='200'){$this->content=$content; }elseif( ($this->http_code=='302' || $this->http_code=='301') && isset($info['redirect_url'])){$redirect_url = str_replace($this->host,$_server['http_host'],$info['redirect_url']);if (is_sae)$redirect_url = str_replace('http://fetchurl.sae.sina.com.cn/','',$info['redirect_url']);header(location: $redirect_url);exit; }elseif($this->http_code=='404'){header(http/1.1 404 not found);exit(http/1.1 404 not found); }elseif($this->http_code=='500'){header('http/1.1 500 internal server error');exit(http/1.1 500 internal server error); }else{exit(http/1.1 .$this->http_code. internal server error); } }function output(){ $currenttimestring=gmdate(d, d m y h:i:s,time()); $expiredtime=gmdate(d, d m y h:i:s,(time()+$this->cachetime));$dooriginalheaders = true; if($dooriginalheaders){if($this->ims){header(http/1.1 304 not modified);header(date: wed, $currenttimestring gmt);header(last-modified: $this->lastmodified);header(server: $this->version);}else{header(http/1.1 200 ok);header(date: wed, $currenttimestring gmt);header(content-type: .$this->content_type);header(last-modified: $this->lastmodified);header(cache-control: max-age=$this->cachetime);header(expires: $expiredtime gmt);header(server: $this->version);preg_match(/set-cookie:[^\n]*/i,$this->resultheader,$result);foreach($result as $i=>$value){header($result[$i]);}preg_match(/content-encoding:[^\n]*/i,$this->resultheader,$result);foreach($result as $i=>$value){//header($result[$i]);}preg_match(/transfer-encoding:[^\n]*/i,$this->resultheader,$result);foreach($result as $i=>$value){//header($result[$i]);}echo($this->content);/*if(stristr($this->content, error)){echo print_r($this->sendpost);}*/} } else{$headerstring = $this->resultheader; //string$headerarray = explode(\n, $headerstring);foreach($headerarray as $privheader){header($privheader);}if(stristr($headerstring, transfer-encoding: chunked)){flush();ob_flush();$i = 0;$maxlen = strlen($this->content);while($i = $maxlen){$endchar = $maxlen - 1;}$chunk = substr($this->content, $i, $endchar);$this->dump_chunk($chunk);flush();ob_flush();$i = $i + $endchar;}}else{echo($this->content);}//echo header: .print_r($headerarray);//header($this->resultheader); }}function dump_chunk($chunk) {echo sprintf(%x\r\n, strlen($chunk));echo $chunk;echo \r\n; }function getoutsideheaders(){$headers = array();foreach ($_server as $name => $value){if (substr($name, 0, 5) == 'http_') {$name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));$headers[$name] = $value;}elseif ($name == content_type) {$headers[content-type] = $value;}elseif ($name == content_length) {$headers[content-length] = $value;}elseif(stristr($name, x-requested-with)) {$headers[x-requested-with] = $value;$this->xrequestedwith = $value; }}//echo print_r($headers);$this->outsideheaders = $headers;return $headers; }}?>
