改自php reverse proxy prp,修改了原版中的一些错误,支持了文件上传以及上传文件类型识别,支持指定ip,自适应sae环境。
使用方法
<?php
$proxy=new phpreverseproxy();
$proxy->port="8080";
$proxy->host="www.jb51.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("%xrn", strlen($chunk));
echo $chunk;
echo "rn";
}
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;
}
}
?>
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:)!