N行代码实现一个简单的代理服务器

<?php
/**
* Web代理服务器(支持http/https)
* @author zhjx922
*/
class WebProxyServer
{
private $_client = [];
private $_server; /**
* 日志打印
* @author zhjx922
* @param string $message
*/
protected function log($message)
{
echo $message . PHP_EOL;
} /**
* 获取代理ip
* @author zhjx922
*/
protected function getLocalIp()
{
//获取代理IP
$ipList = swoole_get_local_ip();
foreach($ipList as $interface => $ip) {
$this->log("{$interface}:{$ip}");
}
} /**
* 初始化
* @author zhjx922
*/
protected function init()
{
$this->getLocalIp(); $this->_server = new swoole_server("0.0.0.0", 8889); $this->_server->set([
'buffer_output_size' => 64 * 1024 *1024, //必须为数字
]);
} /**
* 跑起来
* @author zhjx922
*/
public function run()
{
$this->init(); $this->_server->on('connect', function ($server, $fd){
$this->log("Server connection open: {$fd}");
}); $this->_server->on('receive', function ($server, $fd, $reactor_id, $buffer){ //判断是否为新连接
if(!isset($this->_client[$fd])) {
//判断代理模式
list($method, $url) = explode(' ', $buffer, 3);
$url = parse_url($url); //ipv6为啥外面还有个方括号?
if(strpos($url['host'], ']')) {
$url['host'] = str_replace(['[', ']'], '', $url['host']);
} //解析host+port
$host = $url['host'];
$port = isset($url['port']) ? $url['port'] : 80; //ipv4/v6处理
$tcpMode = strpos($url['host'], ':') !== false ? SWOOLE_SOCK_TCP6 : SWOOLE_SOCK_TCP;
$this->_client[$fd] = new swoole_client($tcpMode, SWOOLE_SOCK_ASYNC); if($method == 'CONNECT')
{
$this->_client[$fd]->on("connect", function (swoole_client $cli) use ($fd) {
$this->log("隧道模式-连接成功!");
//告诉客户端准备就绪,可以继续发包
$this->_server->send($fd, "HTTP/1.1 200 Connection Established\r\n\r\n");
});
} else {
$this->_client[$fd]->on("connect", function(swoole_client $cli) use ($buffer) {
$this->log("正常模式-连接成功!");
//直接转发数据
$cli->send($buffer);
});
} $this->_client[$fd]->on("receive", function(swoole_client $cli, $buffer) use ($fd){
//将收到的数据转发到客户端
if($this->_server->exist($fd)) {
$this->_server->send($fd, $buffer);
}
}); $this->_client[$fd]->on("error", function(swoole_client $cli) use ($fd){
$this->log("Client {$fd} error");
}); $this->_client[$fd]->on("close", function(swoole_client $cli) use ($fd){
$this->log("Client {$fd} connection close");
}); $this->_client[$fd]->connect($host, $port);
} else {
//已连接,正常转发数据
if($this->_client[$fd]->isConnected()) {
$this->_client[$fd]->send($buffer);
}
} }); $this->_server->on('close', function ($server, $fd) {
$this->log("Server connection close: {$fd}");
unset($this->_client[$fd]);
}); $this->_server->start();
}
} $server = new WebProxyServer();
$server->run();

基于Swoole的HTTP/HTTPS代理的更多相关文章

  1. LaravelS - 基于Swoole加速Laravel/Lumen

    LaravelS LaravelS是一个胶水项目,用于快速集成Swoole到Laravel或Lumen,然后赋予它们更好的性能.更多可能性.Github 特性 内置Http/WebSocket服务器 ...

  2. tcpproxy:基于 Swoole 实现的 TCP 数据包转发工具的方法

    假设我们希望有一台机器A(ip 192.168.1.101)要开放端口6379给用户访问,但可能实际情况是用户无法直接访问到A(ip 192.168.1.101), 但却有一台机器B(ip 192.1 ...

  3. 基于 SSL 的 Nginx 反向代理

    基于 SSL 的 Nginx 反向代理 描述: 线上zabbix因机房网络问题,外网接口无法对外访问,因此采用同机房的另外一台服务器做反向代理. 线上用于zabbix提供web访问的Nginx,采用h ...

  4. 手撸基于swoole 的分布式框架 实现分布式调用(20)讲

    最近看的一个swoole的课程,前段时间被邀请的参与的这个课程 比较有特点跟一定的深度,swoole的实战教程一直也不多,结合swoole构建一个新型框架,最后讲解如何实现分布式RPC的调用. 内容听 ...

  5. [Sw] Swoole 生态迷局,基于 Swoole 的第 109 框架

    这两天,又一全栈式 Swoole 协程框架面世了 - hyperf,实现思路是我内心点了赞同的,就集成现有 PHP 生态优质组件到 Swoole 的协程中来. 有人想到,为什么不是 Swoole 集成 ...

  6. websocket和基于swoole的简易即时通讯

    这里描述个基于swoole的websocket 匿名群聊 UI <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  7. 一个基于swoole的作业调度组件,已经实现了redis和rabitmq队列消息存储。

    https://github.com/kcloze/swoole-jobs 一个基于swoole的作业调度组件,已经实现了redis和rabitmq队列消息存储.参考资料:swoole https:/ ...

  8. 房产基于Swoole的PHP RPC框架设计

    房产基于Swoole的PHP RPC框架设计 https://mp.weixin.qq.com/s/XSrKEQ-0q4DvjOGTIwYYzg

  9. Nginx安装及支持https代理配置和禁用TSLv1.0、TSLv1.1配置

    Linux安装Nginx Nginx安装及支持https代理配置和禁用TSLv1.0.TSLv1.1配置. 下载安装包 [root@localhost ~]# wget http://nginx.or ...

随机推荐

  1. Scratch 第2课淘气男孩儿

    素材及视频下载 链接:https://pan.baidu.com/s/1qX0T2B_zczcLaCCpiRrsnA提取码:xfp8

  2. 第二章 IBM

    1.不要招惹IBM,这可是一家做过军火的公司,一家参与了曼哈顿计划的公司. 同时也是世界上最大的服务公司.第二大软件公司.第二大数据库公司.拥有工业界最大的实验室.第一专利申请大户.最大的开源linu ...

  3. MAC中PHP7.3安装mysql扩展

    1.下载mysql扩展http://git.php.net/?p=pecl/database/mysql.git;a=summary 2.解压tar xzvf mysql-d7643af.tar.gz ...

  4. iOS 头条一面 面试题

    1.如何高效的切圆角? 切圆角共有以下三种方案: cornerRadius + masksToBounds:适用于单个视图或视图不在列表上且量级较小的情况,会导致离屏渲染. CAShapeLayer+ ...

  5. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(一)之Introduction

    Learn Java I found out that I and other speakers tended to give the typical audience too many topics ...

  6. Julia基础语法字符和字符串

    1.Julia字符串  2.字符

  7. ASE课程总结 by 冯晓云

    开始的开始,采访往届ASE班的blog:http://www.cnblogs.com/legs/p/4894362.html 和北航软工M1检查:http://www.cnblogs.com/legs ...

  8. stand up meeting 1-4

    放假归来第一天,组内成员全员到齐,满血复活. 今天主要对下边最后半个月的任务做了规划和分配. UI的优化部分在假期前静雯已经完成在了UI分支上,国庆会在这两天把UI设计的更新merge到master分 ...

  9. Python巩固 - 第N天

    一.函数解释: def fact(n, m = 1): s = 1 for j in range(1, n+1): s = s*j return n, m, s//m print(fact(10, 5 ...

  10. [YII2] 3步发送邮件,有图有真相!

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABOQAAAIcCAYAAABW0HFSAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjw ...