<?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:[^\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);
}
}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);
}
}
}
public function dump_chunk($chunk){
echo sprintf("%x\r\n", strlen($chunk));
echo $chunk;
echo "\r\n";
}
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;
}
}
?>

  

PHP反向代理(转)的更多相关文章

  1. nginx配置反向代理或跳转出现400问题处理记录

    午休完上班后,同事说测试站点访问接口出现400 Bad Request  Request Header Or Cookie Too Large提示,心想还好是测试服务器出现问题,影响不大,不过也赶紧上 ...

  2. 使用python自动生成docker nginx反向代理配置

    由于在测试环境上用docker部署了多个应用,而且他们的端口有的相同,有的又不相同,数量也比较多,在使用jenkins发版本的时候,不好配置,于是想要写一个脚本,能在docker 容器创建.停止的时候 ...

  3. Windos环境用Nginx配置反向代理和负载均衡

    Windos环境用Nginx配置反向代理和负载均衡 引言:在前后端分离架构下,难免会遇到跨域问题.目前的解决方案大致有JSONP,反向代理,CORS这三种方式.JSONP兼容性良好,最大的缺点是只支持 ...

  4. Nginx反向代理,负载均衡,redis session共享,keepalived高可用

    相关知识自行搜索,直接上干货... 使用的资源: nginx主服务器一台,nginx备服务器一台,使用keepalived进行宕机切换. tomcat服务器两台,由nginx进行反向代理和负载均衡,此 ...

  5. 使用Nginx反向代理 让IIS和Tomcat等多个站点一起飞

    使用Nginx 让IIS和Tomcat等多个站点一起飞 前言: 养成一个好习惯,解决一个什么问题之后就记下来,毕竟“好记性不如烂笔头”. 这样也能帮助更多的人 不是吗? 最近闲着没事儿瞎搞,自己在写一 ...

  6. 使用nginx反向代理,一个80端口下,配置多个微信项目

    我们要接入微信公众号平台开发,需要填写服务器配置,然后依据接口文档才能实现业务逻辑.但是微信公众号接口只支持80接口(80端口).我们因业务需求需要在一个公众号域名下面,发布两个需要微信授权的项目,怎 ...

  7. 腾讯云下安装 nodejs + 实现 Nginx 反向代理

    本文将介绍如何给腾讯云上的 Ubuntu Server 12.04 LTS 64位主机安装 node 及 nginx,并简单配置反向代理. 笔者在整个安装过程中遇到不少麻烦(不赘述),如果你希望少踩坑 ...

  8. 简易nginx TCP反向代理设置

    nginx从1.9.0开始支持TCP反向代理,之前只支持HTTP.这是我的系统示意图: 为何需要? 为什么需要反向代理?主要是: 负载均衡 方便管控 比如我现在要更新后端服务器,如果不用负载均衡的话, ...

  9. 反向代理与 Real-IP 和 X-Forwarded-For

    开篇语:开涛新作<亿级流量网站架构核心技术>出版计划公布以来,博文视点遭受到一波又一波读者询问面世时间的DDos攻击.面对亿级流量的热情,感激之余,我们也很庆幸——这部作品质量的确过硬,不 ...

  10. Nginx服务器 之反向代理与负载均衡

    一.反向代理 正向代理: 客户端要获取的资源就在服务器上,客户端请求的资源路径就是最终响应资源的服务器路径,这就是正向代理.正向代理的特点:就是我们明确知道要访问哪个网站地址. 反向代理: 客户端想获 ...

随机推荐

  1. linux篇-centos7搭建apache服务器(亲测可用)

    1安装apache yum install httpd httpd-devel -y 2开启服务器 systemctl start httpd.service 3开机自启 systemctl enab ...

  2. 05-STL

    Day01 笔记 1 STL概论 1.1 STL六大组件 1.1.1 容器.算法.迭代器.仿函数.适配器.空间配置器 1.2 STL优点 1.2.1 内建在C++编译器中,不需要安装额外内容 1.2. ...

  3. MVC 调试页面路径变成 Views/Controller/Action.cshtml问题

    MVC在路由里面已经写好了路径,但是调试时地址栏还是会变成 Views/Controller/Action.cshtml,导致报404错误,找不到路径. 原因可能是你将某一页面设为了起始页,导致每次运 ...

  4. es6.4.2api

    这是讲数据库的数据导入到es里  所有用到了mysql! 1.依赖 <?xml version="1.0" encoding="UTF-8"?> & ...

  5. 4.怎么理解相互独立事件?真的是没有任何关系的事件吗? 《zobol的考研概率论教程》

    1.从条件概率的定义来看独立事件的定义 2.从古典概率的定义来看独立事件的定义 3.P(A|B)和P(A)的关系是什么? 4.由P(AB)=P(A)P(B)推出"独立" 5.从韦恩 ...

  6. BUUCTF-ningen

    ningen 从16进制看可以发现其中有压缩包,存在着504b0304,使用binwalk分离即可 压缩包带密码,根据提示是四位纯数字 使用ARCHPR破解即可

  7. python基础知识-day8(函数实战)

    1 def out(): 2 username=input("请输入用户名:\n") 3 password=input("请输入密码:\n") 4 return ...

  8. CVPR2022 | 可精简域适应

    前言 在本文中,作者引入了一个简单的框架,即Slimmable Domain Adaptation,以通过权重共享模型库改进跨域泛化,从中可以对不同容量的模型进行采样,以适应不同的精度效率权衡.此外, ...

  9. Prometheus安装教程

    Prometheus安装教程 欢迎关注H寻梦人公众号 参考目录 docker安装Prometheus 基于docker 搭建Prometheus+Grafana prometheus官方文档 dock ...

  10. cve-2021-42287和cve-2021-42278漏洞复现

    一.漏洞概述 cve-2021-42287 : 由于Active Directory没有对域中计算机与服务器账号进行验证,经过身份验证的攻击 者利用该漏洞绕过完全限制,可将域中普通用户权限提升为域管理 ...