这篇文章主要介绍了PHP反向代理类代码,需要的朋友可以参考下
改自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 反向代理 (PRP) 1.0"; $这个->端口=“8080”; $this->主机=“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->授权 = ""; } 函数translateURL($serverName) { $this->path=$this->forward_path.$_SERVER['REQUEST_URI']; 如果(IS_SAE) 返回 $this->translateServer($serverName).$this->path; if($_SERVER['QUERY_STRING']=="") 返回 $this->translateServer($serverName).$this->path; 别的 return $this->translateServer($serverName).$this->path."?".$_SERVER['QUERY_STRING']; } 函数translateServer($serverName) { $s = 空($_SERVER["HTTPS"]) ? ” : ($_SERVER["HTTPS"] == "开启") ? “s” :“”; $protocol = $this->left(strtolower($_SERVER["SERVER_PROTOCOL"]), "/").$s; if($this->端口=="") 返回 $protocol."://".$serverName; 别的 return $protocol."://".$serverName.":".$this->port; } 左函数($s1, $s2) { 返回 substr($s1, 0, strpos($s1, $s2)); } 函数预连接(){ $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; 如果(空($_SERVER['HTTP_X_FORWARDED_FOR'])){ $this->XFF=$_SERVER['REMOTE_ADDR']; } 别的 { $this->XFF=$_SERVER['HTTP_X_FORWARDED_FOR'].", ".$_SERVER['REMOTE_ADDR']; } } 函数连接(){ 如果(空($_SERVER['HTTP_IF_MODIFIED_SINCE'])){ $this->preConnect(); $ch=curl_init(); if($this->request_method=="POST"){ curl_setopt($ch, CURLOPT_POST,1); $postData = 数组(); $filePost = false; $uploadPath = '上传/'; 如果(IS_SAE) $uploadPath = SAE_TMP_PATH; 如果(计数($_FILES)> 0){ if(!is_writable($uploadPath)){ die('无法上传到指定目录,请CHMOD为777。'); } foreach($_FILES as $key => $fileArray){ 复制($fileArray["tmp_name"], $uploadPath .$fileArray["name"]); $proxyLocation = "@" 。 $上传路径。 $fileArray["名称"] 。 “;类型=”。 $fileArray["类型"]; $postData = array($key => $proxyLocation); $filePost = true; } } foreach($_POST as $key => $value){ if(!is_array($value)){ $postData[$key] = $value; } 别的{ $postData[$key] = 序列化($value); } } 如果(!$filePost){ //$postData = http_build_query($postData); $postString = ""; $firstLoop = true; foreach($postData as $key => $value){ $parameterItem = urlencode($key)."=".urlencode($value); 如果($firstLoop){ $postString .= $parameterItem; } 别的{ $postString .= "&".$parameterItem; } $firstLoop = false; } $postData = $postString; } //回显 print_r($postData); //curl_setopt($ch, CURLOPT_VERBOSE, 0); //curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (兼容;)"); $this->sendPost = $postData; //var_dump(file_exists(str_replace('@','',$postData['imgfile'])));退出; 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")); } //摆脱多个?在网址中 $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 = 数组( "X-Forwarded-For: ".$this->XFF, “用户代理:”.$this->user_agent, "主机:".$this->主机 ); if(strlen($this->XRequestedWith)>1){ $proxyHeaders[] = "X-Requested-With: ".$this->XRequestedWith; //回显 print_r($proxyHeaders); } curl_setopt($ch,CURLOPT_HTTPHEADER, $proxyHeaders); if($this->cookie!=""){ curl_setopt($ch,CURLOPT_COOKIE,$this->cookie); }curl_setopt($ch,CURLOPT_FOLLOWLOCATION,假); curl_setopt($ch,CURLOPT_AUTOREFERER,true); curl_setopt($ch,CURLOPT_HEADER,true); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); $输出=curl_exec($ch); $info=curl_getinfo($ch); 卷曲关闭($ch); $this->postConnect($info,$output); }别的 { $this->lastModified=$_SERVER['HTTP_IF_MODIFIED_SINCE']; $this->IMS=true; } } 函数 postConnect($info,$output){ $this->content_type=$info["content_type"]; $this->http_code=$info['http_code']; //var_dump($info);退出; 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->内容=$内容; }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']); 如果(IS_SAE) $redirect_url = str_replace('http://fetchurl.sae.sina.com.cn/','',$info['redirect_url']); header("位置:$redirect_url"); 出口; }elseif($this->http_code=='404'){ header("HTTP/1.1 404 未找到"); 退出(“HTTP/1.1 404未找到”); }elseif($this->http_code=='500'){ header('HTTP/1.1 500 内部服务器错误'); exit("HTTP/1.1 500 内部服务器错误"); }别的{ exit("HTTP/1.1 ".$this->http_code." 内部服务器错误"); } } 函数输出(){ $currentTimeString=gmdate("D, d M Y H:i:s",time()); $expiredTime=gmdate("D, d M Y H:i:s",(time() $this->cacheTime)); $doOriginalHeaders = true; 如果($doOriginalHeaders){ if($this->IMS){ header("HTTP/1.1 304 未修改"); header("日期:星期三,$currentTimeString GMT"); header("最后修改时间:$this->lastModified"); header("服务器:$this->版本"); }别的{ 标头(“HTTP/1.1 200 确定”); header("日期:星期三,$currentTimeString GMT"); header("内容类型:".$this->content_type); header("最后修改时间:$this->lastModified"); header("Cache-Control: max-age=$this->cacheTime"); header("过期时间:$expiredTime GMT"); header("服务器:$this->版本"); preg_match("/Set-Cookie:[^n]*/i",$this->resultHeader,$result); foreach($结果为$i=>$值){ 标头($结果[$i]); } preg_match("/Content-Encoding:[^n]*/i",$this->resultHeader,$result); foreach($结果为$i=>$值){ //标题($结果[$i]); } preg_match("/传输编码:[^n]*/i",$this->resultHeader,$result); foreach($结果为$i=>$值){ //标题($结果[$i]); } echo($this->内容); /* if(stristr($this->内容, "错误")){ echo print_r($this->sendPost); } */ } } 别的{ $headerString = $this->resultHeader; //细绳 $headerArray = 爆炸("n", $headerString); foreach($headerArray 作为 $privHeader){ 标头($privHeader); } if(stristr($headerString, "传输编码:分块")){ 冲洗(); ob_flush(); $i = 0; $maxLen = strlen($this->内容); while($i = $maxLen){ $endChar = $maxLen - 1; } $chunk = substr($this->内容, $i, $endChar); $this->dump_chunk($chunk); 冲洗(); ob_flush(); $i = $i $endChar; } } 别的{ echo($this->内容); } //回显“标题:”.print_r($headerArray); //标题($this->resultHeader); } } 函数 dump_chunk($chunk) { echo sprintf("%xrn", strlen($chunk)); 回显$块; 回声“rn”; } 函数 getOutsideHeaders(){ $标头=数组(); foreach ($_SERVER as $name => $value){ if (substr($name, 0, 5) == 'HTTP_') { $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))); $标头[$名称] = $值; }elseif ($name == "CONTENT_TYPE") { $headers["内容类型"] = $value; }elseif ($name == "CONTENT_LENGTH") { $headers["内容长度"] = $value; }elseif(stristr($name, "X-Requested-With")) { $headers["X-Requested-With"] = $value; $this->XRequestedWith = $value; } } //回显 print_r($headers); $this->outsideHeaders = $headers; 返回 $headers; } } ?>