改自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
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我