域名綁定到workerman服務(wù)器,
然后workerman識(shí)別 http協(xié)議中的域名,
然后系統(tǒng)內(nèi)部映射域名源站,
新建AsyncTcpConnection(源站)
轉(zhuǎn)發(fā)的數(shù)據(jù),修改其中的host即可,這樣可以實(shí)現(xiàn) 訪問a.com(ip為workerman),反向代理到B服務(wù)器并且回源域名為:b.com, 這樣 a.com就能打開b.com的頁(yè)面
代碼如下:
public function onMessage(TcpConnection $connection, $data)
{
// Parse http header.
list($method, $addr, $http_version) = explode(' ', $data);
$_headers=explode("\r\n",$data);
$headers=[];
foreach ($_headers as $_header){
$_point=strpos($_header,':');
if ($_point===false) continue;
$headers[substr($_header,0,$_point)]=trim(trim(substr($_header,$_point),':'));
}
//替換request 中的回源host
$replace_domain='a.com';
//源站IP地址,
$source_ip='123.123.123.123';
$data=preg_replace('/Host: (.*)/i','Host: '.$replace_domain,$data);
// Async TCP connection.
$remote_connection = new AsyncTcpConnection('tcp://'.$source_ip);
// CONNECT.
if ($method !== 'CONNECT') {
$remote_connection->send($data);
// POST GET PUT DELETE etc.
} else {
$connection->send("HTTP/1.1 200 Connection Established\r\n\r\n");
}
print_r($data);
// Pipe.
$remote_connection ->pipe($connection);
$connection->pipe($remote_connection);
$remote_connection->connect();
}
目前遇到這個(gè)問題,chrome第一次訪問a.com 確實(shí)反向代理了 123.123.123.123的服務(wù)器host為b.com。但是,再次刷新瀏覽器,123.123.123.123 提示無(wú)法找到站點(diǎn),也就是說可能Host替換失效了,并且第二次刷新瀏覽器沒有觸發(fā) print_r ()
目前我使用這樣的辦法解決了,但是不知道后面是會(huì)有問題
<?php
namespace app\cdn\process;
use Workerman\Connection\AsyncTcpConnection;
use Workerman\Connection\TcpConnection;
class CdnTcp
{
public function onConnect(TcpConnection $connection)
{
}
public function onWebSocketConnect(TcpConnection $connection, $http_buffer)
{
echo "onWebSocketConnect\n";
}
public function onMessage(TcpConnection $connection, $data)
{
// Parse http header.
list($method, $addr, $http_version) = explode(' ', $data);
$_headers=explode("\r\n",$data);
$headers=[];
foreach ($_headers as $_header){
$_point=strpos($_header,':');
if ($_point===false) continue;
$headers[substr($_header,0,$_point)]=trim(trim(substr($_header,$_point),':'));
}
//源站IP地址
$source_ip='123.123.123.123';
$source_host='www.baidu.com';
print_r('用戶IP:'.$connection->getRemoteAddress().'| 訪問域名:'.$headers['Host'] .' | 源站:'.gethostbyname($source_ip).'| 回源域名'.$source_host);
// Async TCP connection.
$remote_connection = new AsyncTcpConnection('tcp://'.$source_ip);
// CONNECT.
if ($method !== 'CONNECT') {
//替換request 中的回源host
$remote_connection->send(CdnTcp::replaceHost($data,$source_host));
// POST GET PUT DELETE etc.
} else {
$connection->send("HTTP/1.1 200 Connection Established\r\n\r\n");
}
$remote_connection->onMessage=function (TcpConnection $SourceConn, $SourceData)use ($connection){
$connection->send($SourceData);
};
$remote_connection->onClose = function ($source) use ($connection) {
$connection->close();
};
$remote_connection->onBufferFull = function ($SourceConn) use ($connection) {
$connection->pauseRecv();
};
$remote_connection->onBufferDrain = function ($SourceConn) use ($connection) {
$connection->resumeRecv();
};
$connection->onMessage=function (TcpConnection $ClientConn, $ClientData)use ($remote_connection,$source_host){
$remote_connection->send(CdnTcp::replaceHost($ClientData,$source_host));
};
$connection->onClose = function (TcpConnection $ClientConn) use ($remote_connection) {
$remote_connection->close();
};
$connection->onBufferFull = function (TcpConnection $ClientConn) use ($remote_connection) {
$remote_connection->pauseRecv();
};
$connection->onBufferDrain = function (TcpConnection $ClientConn) use ($remote_connection) {
$remote_connection->resumeRecv();
};
$remote_connection->connect();
}
public static function replaceHost(string $data,$host):string
{
return preg_replace('/Host: (.*)/i','Host: '.$host,$data);
}
public function onClose(TcpConnection $connection)
{
echo "onClose\n";
}
}