• PHP反向代理(转)


    <?php
    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;
        public 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 = "";
            set_time_limit(0);//设置过期时间为永不过期
        }
        public 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'];
        }
        public 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;
        }
        public function left($s1, $s2){
            return substr($s1, 0, strpos($s1, $s2));
        }
        public 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'];
            }
        }
        public 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;
                    }
                    //curl_setopt($ch, CURLOPT_VERBOSE, 0);
                    //curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                    //curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
                    $this->sendPost = $postData;
                    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 = 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;
                }
                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;
            }
        }
        public function postConnect($info, $output){
            $this->content_type = $info["content_type"];
            $this->http_code = $info['http_code'];
            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");
            }
        }
        public 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:[^
    ]*/i", $this->resultHeader, $result);
                    foreach($result as $i=>$value){
                        header($result[$i]);
                    }
                    preg_match("/Content-Encoding:[^
    ]*/i", $this->resultHeader, $result);
                    foreach($result as $i=>$value){
                        header($result[$i]);
                    }
                    preg_match("/Transfer-Encoding:[^
    ]*/i", $this->resultHeader, $result);
                    foreach($result as $i=>$value){
                        header($result[$i]);
                    }
                    echo($this->content);
                }
            }else{
                $headerString = $this->resultHeader; //string
                $headerArray = explode("
    ", $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);
                }
            }
        }
        public function dump_chunk($chunk){
            echo sprintf("%x
    ", strlen($chunk));
            echo $chunk;
            echo "
    ";
        }
        public 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;
                }
            }
            $this->outsideHeaders = $headers;
            return $headers;
        }
    }
    ?>
    

      

  • 相关阅读:
    zend studio常见问题解答
    瀑布流插件(jquery.masonry.js)
    仿jQuery中undelegate()方法功能的函数
    Linux 常用命令
    linux debugfs 找回rm 的文件
    jq 添加和移除样式
    CentOS 搭建 nginx python django web server
    Linux vim 配置文件
    CentOS 安装python 3.3.2
    login.defs和shadow文件区别
  • 原文地址:https://www.cnblogs.com/isuben/p/7066547.html
Copyright © 2020-2023  润新知