基于Swoole的HTTP/HTTPS代理
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代理的更多相关文章
- LaravelS - 基于Swoole加速Laravel/Lumen
LaravelS LaravelS是一个胶水项目,用于快速集成Swoole到Laravel或Lumen,然后赋予它们更好的性能.更多可能性.Github 特性 内置Http/WebSocket服务器 ...
- tcpproxy:基于 Swoole 实现的 TCP 数据包转发工具的方法
假设我们希望有一台机器A(ip 192.168.1.101)要开放端口6379给用户访问,但可能实际情况是用户无法直接访问到A(ip 192.168.1.101), 但却有一台机器B(ip 192.1 ...
- 基于 SSL 的 Nginx 反向代理
基于 SSL 的 Nginx 反向代理 描述: 线上zabbix因机房网络问题,外网接口无法对外访问,因此采用同机房的另外一台服务器做反向代理. 线上用于zabbix提供web访问的Nginx,采用h ...
- 手撸基于swoole 的分布式框架 实现分布式调用(20)讲
最近看的一个swoole的课程,前段时间被邀请的参与的这个课程 比较有特点跟一定的深度,swoole的实战教程一直也不多,结合swoole构建一个新型框架,最后讲解如何实现分布式RPC的调用. 内容听 ...
- [Sw] Swoole 生态迷局,基于 Swoole 的第 109 框架
这两天,又一全栈式 Swoole 协程框架面世了 - hyperf,实现思路是我内心点了赞同的,就集成现有 PHP 生态优质组件到 Swoole 的协程中来. 有人想到,为什么不是 Swoole 集成 ...
- websocket和基于swoole的简易即时通讯
这里描述个基于swoole的websocket 匿名群聊 UI <!DOCTYPE html> <html> <head> <meta charset=&qu ...
- 一个基于swoole的作业调度组件,已经实现了redis和rabitmq队列消息存储。
https://github.com/kcloze/swoole-jobs 一个基于swoole的作业调度组件,已经实现了redis和rabitmq队列消息存储.参考资料:swoole https:/ ...
- 房产基于Swoole的PHP RPC框架设计
房产基于Swoole的PHP RPC框架设计 https://mp.weixin.qq.com/s/XSrKEQ-0q4DvjOGTIwYYzg
- Nginx安装及支持https代理配置和禁用TSLv1.0、TSLv1.1配置
Linux安装Nginx Nginx安装及支持https代理配置和禁用TSLv1.0.TSLv1.1配置. 下载安装包 [root@localhost ~]# wget http://nginx.or ...
随机推荐
- shell使用特殊变量
shell使用特殊变量 3.1问题 本例要求编写一个脚本/root/myuse ...
- 今天无意中看到了str_split这个函数
前2天做广点通统计接口进行回调时需要加密,其中Python对字符串遍历很方便. s = 'abcd' for ch in s: print ch 但是PHP我想了半天还是老样子for循环之类的: &l ...
- New!一只菜鸟的学习之路....
今天拥有了自己的博客,希望在这里记录下自己成长的点点滴滴! 本博客主要记录: 1.在学习过程中遇到的问题及后续的解决办法: 2.技术上的困难,希望路过的大佬指点一二: 3.分享一些实用的技术材料: 4 ...
- 好玩Python——PIL项目实训
PIL学习总结: 1. 2,PIL库概述: pil库可以完成图像归档和图像处理两方面功能的需求: 图像归档:对图像进行批处理,生成图像预览,图像转换格式等: 图像处理:图像基本处理,像素处理,颜色处理 ...
- 家庭版记账本app开发之关于(数据库查找出数据)圆饼图的生成
这次完成的主要的怎样从数据库中调出数据.之后通过相关的数据,生成想要的圆饼图.以方便用户更加直观的看见关于账本的基本情况. 在圆饼图生成中用到了一些外部资源 具体的import如下: import c ...
- (js描述的)数据结构[双向链表](5)
(js描述的)数据结构[双向链表](5) 一.单向链表的缺点 1.只能按顺序查找,即从上一个到下一个,不能反过来. 二.双向链表的优点 1.可以双向查找 三.双向链表的缺点 1.结构较单向链表复杂. ...
- python部署-Flask+uwsgi+Nginx
一.Flask部分(app.py) flask即Python代码:部分参考代码如下,相信很多人如果看到这篇文章一定有flask的代码能力. from app import create_app fro ...
- TCP协议的安全性分析
有算法就有破解法,因为它们都遵循了一定的数据结构和数学知识.所以网络安全是一个相对的概念,不可能出现绝对的安全!作为当今最流行的网络协议--TCP也是如此.那么TCP的安全问题究竟是哪些因素引起的呢? ...
- Eclipse(Eclipse for android)代码自动提示设置
java代码和xml资源代码在有的eclipse中可以自己提示,但有的并不支持这个功能,还得我们人为去调整,主要原因是因为你们下载的elipse的渠道不同,获得的版本有的官方原版,有的是个人备份版等等 ...
- spark rdd元素println
1.spark api主要分两种:转换操作和行动操作.如果在转化操作中println spark打印了 我也看不到. val result = sqlContext.sql(sql) val resu ...