改自PHP Reverse Proxy PRP,修改了原版中的一些错误,支持了文件上传以及上传文件类型识别,支持指定IP,自适应SAE环境。
使用方法
<?php $proxy=new PhpReverseProxy(); $proxy->port=\"8080\"; $proxy->host=\"www.phpstudy.net\"; //$proxy->ip=\"1.1.1.1\"; $proxy->forward_path=\"\"; $proxy->connect(); $proxy->output(); ?>
源代码
<?php //Source Code: http://www.xiumu.org/technology/php-reverse-proxy-class.shtml class PhpReverseProxy{ public $publicBaseURL; public $outsideHeaders; public $XRequestedWith; public $sendPost; public $port,$host,$ip,$content,$forward_path,$content_type,$user_agent, $XFF,$request_method,$IMS,$cacheTime,$cookie,$authorization; private $http_code,$lastModified,$version,$resultHeader; const chunkSize = 10000; function __construct(){ $this->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; else return $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 = $i + self::chunkSize; if($endChar >= $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; } } ?>
本文地址:https://www.stayed.cn/item/1229
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我