PHP编写简单HTTP代理程序

工作室寒假作业:写了一个简单的HTTP代理程序,以加深了对HTTP协议的理解。

http Proxy

基本原理:
用户通过浏览器向代理的客户端程序发送请求,客户端把请求组织成数据发送给代理服务器的服务端,服务端根据客户端发来的数据,还原用户的请求,再将数据返回给客户端,最后呈现给用户。

配置客户端程序Apache虚拟主机(VirtualHost)监听某一端口,并开启rewrite,将浏览器的所有请求都重定向到客户端程序的入口。

RewriteEngine on                                                       
RewriteRule ^(.*)$ index.php

客户端从$_SERVER中获取用户请求的header信息,并组织数据发送给服务端程序。

/**
* 把请求发送到代理服务器
*/
function run(){                                     
	//组织数据
	$data = $this->buildData();           
	//生成一个 curl 句柄 
	$curl = $this->buildCurl($data) ;
	//把请求数据发送给服务端
	$content = curl_exec($curl);               
	//设置header
	header ("Content-type: ".curl_getinfo($curl, CURLINFO_CONTENT_TYPE)."");
	//解密
	$content = base64_decode($content);   
	echo $content;           
	curl_close($curl);  
}

发送数据采用的是 PHP的curl,其中有两个比较重要的参数值得注意。

//把返回结果存入变量中,而不直接输出
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//自动重定向页面
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);

客户端把请求发给代理服务器,而代理服务器的编码可能与用户所请求网站的编码不同,如果直接返回就可能会出现乱码。所以需要在页面输出前手动将编码设为网页需要的编码,以避免出现编码错误。所以需要设置CURLOPT_RETURNTRANSFER.

服务端接受到客户端的数据后需要模拟用户发出请求。代码如下:

/**
* 发送http请求 
*/
function request(){
                                                          
	$url = $_REQUEST['url'];
	if( !$url ) return false;
    
	$header = $_REQUEST['header'] ? $_REQUEST['header'] : array();
	//生成一个 curl 句柄 
	$curl = $this->buildCurl($url,$header);
	$content = curl_exec($curl); 
	//设置header
	header ("Content-type: ".curl_getinfo($curl, CURLINFO_CONTENT_TYPE)."");
	//简单加密
	$content = base64_encode($content);
	echo $content;                             
	curl_close($curl);    
}

请求成功后,服务端将得到的页面返回给客户端,这样一次请求就顺利完成了。使用base64简单加密,主要是为翻墙考虑,而非数据的安全性。
最后,测试一下通过代理访问网站的实际效果.
renren by proxy

存在的问题:

  • 如果返回的数据header 中 Content-type 一项中只设置了文档类型而没有强制规定编码的话,代理服务器会自动将其设置为utf-8,这样一来,如果网页的编码不是utf-8就又乱码了 ...
  • 还有就是有的网站无法正常提交post数据,至今还是不明白为什么会这样,怀疑可能和重定向有关。
Show Comments