<?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. 2022年5月11日,NBMiner发布了41.3版本,在内核中加入了100%LHR解锁器,从此NVIDIA的显卡再无锁卡一说

           2022年5月11日,NBMiner发布NBMiner_41.3版本,主要提升了稳定性.         2022年5月8日,NBMiner发布NBMiner_41.0版本,在最新的内核 ...

  2. PPP PPOE详解

    PPP协议是在串行线IP协议SLIP(Serial Line Internet Protocol)的基础上发展起来的.由于SLIP协议具有只支持异步传输方式.无协商过程(尤其不能协商如双方IP地址等网 ...

  3. Spring Security之简单举例

    核心功能 Spring Security提供了三个核心的功能: 认证(你是谁) 授权(你能干什么) 攻击防护(防止伪造身份) 一个简单例子 默认情况 在前面的开发中,都是将spring securit ...

  4. CoaXPress 线缆和接插件的设计要求

    本文的原理部分内容不仅适用于CoaXPress 协议,也同样适用于其它高速信号传输情形.在高速.低干扰信号传输时,线缆和接插件的选取是非常讲究的,我们在实际应用中经常会遇到线缆原因.阻抗匹配原因导致的 ...

  5. 『忘了再学』Shell基础 — 31、字符处理相关命令

    目录 1.排序命令sort (1)sort命令介绍 (2)练习 2.取消重复行命令uniq 3.统计命令wc 1.排序命令sort (1)sort命令介绍 sort命令可针对文本文件的内容,以行为单位 ...

  6. 高性能 Jsonpath 框架,Snack3 3.2.29 发布

    Snack3,一个高性能的 JsonPath 框架 借鉴了 Javascript 所有变量由 var 申明,及 Xml dom 一切都是 Node 的设计.其下一切数据都以ONode表示,ONode也 ...

  7. MySQL 千万数据库深分页查询优化,拒绝线上故障!

    文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站:xiaomage.info 优化项目代码过程中发现一个千万级数据深分页问题,缘由是这样的 库里有一张耗材 MCS_PROD 表,通过同步 ...

  8. 【Spring】AOP实现原理(一):AOP基础知识

    AOP相关概念 在学习AOP实现原理之前,先了解下AOP相关基础知识. AOP面向切面编程,它可以通过预编译方式或者基于动态代理对我们编写的代码进行拦截(也叫增强处理),在方法执行前后可以做一些操作, ...

  9. 打字练习-编程语言关键字系列-html

    以下是小编整理的部分html关键字,专门给有需要的朋友进行打字练习用,通过打字练习的方式,既提高了打字速度,又可以熟悉html关键字~~~ www, url, http, W3C, html, htm ...

  10. 你是否有一个梦想?用JavaScript[vue.js、react.js......]开发一款自定义配置视频播放器

    前言沉寂了一周了,打算把这几天的结果呈现给大家.这几天抽空就一直在搞一个自定义视频播放器,为什么会有如此想法?是因为之前看一些学习视频网站时,看到它们做的视频播放器非常Nice!于是,就打算抽空开发一 ...