【www.gdgbn.com--安卓教程】
try{
$tor = new TorHttp("127.0.0.1", 9050);
$data = array("username" => "liujun");
$headers = array("Cookie" => "php教程id=123456; xx=v");
echo $tor->get("http://host.com/testsocks.php", $headers);
$tor->newId("123456");
}catch(Exception $e){
if($e->getCode() == 9999){
$tor->newId("123456");
}
echo $e->getMessage() . "n";
}
*/
class Tool_TorHttp
{
/**
* Tor提供的socks服务器
*
* @var
private $_host;
/**
* socks服务的连接
*
* @var
*/
private $_sock;
/**
* 构造函数
*
* @param
* @param
*/
public function __construct($host = "127.0.0.1", $port = 9050)
{
$this->_host = $host;
@ $this->_sock = fsockopen($host, $port, $errorCode, $error, 5);
if($errorCode){
throw new Exception("不能连接代理服务器");
}
//建立应用层的连接
fwrite($this->_sock, pack("C3", 5, 1, 0));
$resp = fread($this->_sock, 1024);
$resp = unpack("Cversion/Cmethod", $resp);
if($resp["version"] != 5 || $resp["method"] != 0){
$this->_sock = null;
throw new Exception("代理服务器不可用或者需要连接密码");
}
}
/**
* 连接目标主机
*
* @param
* @param
*/
private function _connect($host, $port)
{
//ip和域名描述的服务器用不同的报文格式
$lip = ip2long($host);
if(empty($lip)){
$pack = pack("C5", 5, 1, 0, 3, strlen($host)) . $host . pack("n", intval($port));
}else{
$pack = pack("C4Nn", 5, 1, 0, 1, $lip, $port);
}
fwrite($this->_sock, $pack);
$resp = "";
$counter = 0;
while(true){
if(feof($this->_sock)){
break;
}
$resp .= fread($this->_sock, 1024);
if(!empty($resp) || $counter == 50){
break;
}
$counter += 1;
}
$resp = unpack("Cversion/Crep", $resp);
if(($resp["version"] != 5) || ($resp["rep"] != 0)){
throw new Exception("请求的服务[$host:$port]暂时不可用,或者Tor不能到达,如果反复发生,请尝试重启Tor", 9999);
}
}
/**
* 发起一次http的get请求
*
* @param
* @return
*/
public function get($url, $headers = array())
{
$ua = parse_url($url);
if(empty($ua["port"])){
$ua["port"] = 80;
}
$this->_connect($ua["host"], $ua["port"]);
$requestUri = $ua["path"];
if(!empty($ua["query"])){
$requestUri .= "?" . $ua["query"];
}
$headers["Host"] = $ua["host"];
if(!isset($headers["User-Agent"])){
$headers["User-Agent"] = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 GTB5";
}
$headers["Connection"] = "close";
fwrite($this->_sock, "GET {$requestUri} HTTP/1.1n");
foreach ($headers as $key => $val){
fwrite($this->_sock, "{$key}: {$val}n");
}
fwrite($this->_sock, "n");
$resp = "";
while(!feof($this->_sock)){
$resp .= fread($this->_sock, 1024);
}
return $resp;
}
/**
* 发起一次http的post请求
*
* @param
* @param
* @param
* @return
*/
public function post($url, $data, $headers = array())
{
$ua = parse_url($url);
if(empty($ua["port"])){
$ua["port"] = 80;
}
$this->_connect($ua["host"], $ua["port"]);
if(isset($ua["path"]) && !empty($ua["path"])){
$requestUri = $ua["path"];
}else{
$requestUri = "/";
}
if(!empty($ua["query"])){
$requestUri .= "?" . $ua["query"];
}
if(!isset($headers["User-Agent"])){
$headers["User-Agent"] = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 GTB5";
}
$headers["Connection"] = "close";
$data = $this->_parseData($data);
fwrite($this->_sock, "POST {$requestUri} HTTP/1.1n");
fwrite($this->_sock, "Host: {$ua["host"]}n");
fwrite($this->_sock, "Content-Type: application/x-www-form-urlencodedn");
fwrite($this->_sock, "Content-Length: " . strlen($data) . "n");
foreach ($headers as $key => $val){
fwrite($this->_sock, "{$key}: {$val}n");
}
fwrite($this->_sock, "n");
fwrite($this->_sock, $data . "n");
$resp = "";
while(!feof($this->_sock)){
$resp .= fread($this->_sock, 1024);
}
return $resp;
}
/**
* 更新Tor的身份
*
* @param
* @param
* @return
*/
public function newId($password = "", $port = 9051)
{
if(!empty($password) && $password[0] != """){
$password = """ . $password . """;
}
//创建到tor控终端的连接
@ $sock = fsockopen($this->_host, $port, $errorCode, $error, 5);
if($errorCode){
throw new Exception("不能连接代理服务器控制端,请检查端口号");
}
fwrite($sock, "AUTHENTICATE {$password}n");
$resp = fread($sock, 1024);
if(!preg_match("/^250/", $resp)){
throw new Exception("Tor控制认证失败,请确认密码正确");
}
fwrite($sock, "SIGNAL NEWNYMn");
$resp = fread($sock, 1024);
if(!preg_match("/^250/", $resp)){
throw new Exception("更新身份失败,请重试");
}
return true;
}
private function _parseData($data)
{
if(empty($data) || !is_array($data)){
return $data;
}
$encoded = "";
while (list($k, $v) = each($data)) {
$encoded .= $k . "=" . $v . "&";
}
return substr($encoded, 0, -1);
}
public function __destruct()
{
fclose($this->_sock);
$this->_sock = null;
}
}