Sunny 网络中间件 v3.1.0 实战:拦截并修改 HTTP/WS/TCP 3类协议数据
Sunny 网络中间件 v3.1.0 实战:拦截并修改 HTTP/WS/TCP 三类协议数据
在当今快速发展的互联网环境中,网络数据拦截与修改技术已成为开发者工具箱中不可或缺的一部分。无论是进行安全测试、性能优化,还是实现特定的业务逻辑,能够精准控制网络流量都显得尤为重要。Sunny 网络中间件作为一款功能强大的跨平台网络分析组件,为开发者提供了这种能力。本文将深入探讨如何利用 aardio 封装的 Sunny 库,实现对 HTTP、WebSocket 和 TCP 三种主流网络协议数据的拦截与动态修改。
1. Sunny 网络中间件概述
Sunny 网络中间件是一款类似于 Fiddler 的跨平台网络分析组件,支持 HTTP/HTTPS/WS/WSS/TCP 等多种协议的数据拦截与分析。与同类工具相比,Sunny 具有以下显著优势:
- 无内存泄漏风险:采用高效的内存管理机制,确保长时间稳定运行
- 多协议支持:一站式解决多种网络协议的监控需求
- 二次开发友好:提供清晰的 API 接口,便于集成到现有系统中
1.1 核心功能特性
Sunny 的核心功能可以概括为以下几个方面:
| 功能类别 | 具体能力 | 适用场景 |
|---|---|---|
| 数据捕获 | 获取 HTTP/HTTPS/WS/WSS/TCP 的请求和响应数据 | 协议分析、安全审计 |
| 数据修改 | 动态修改请求头、响应体、WebSocket 消息等 | 内容替换、A/B 测试 |
| 代理控制 | 设置全局代理或指定连接使用特定代理 | 流量路由、访问控制 |
| 连接重定向 | 对 HTTP/HTTPS/WS/WSS/TCP 链接进行重定向 | 负载均衡、故障转移 |
安装准备:
# 下载 Sunny 库文件 wget http://esunny.vip/download/sunny.rar # 解压到 aardio 的 lib/godking/ 目录 unzip sunny.rar -d /lib/godking/2. 基础环境配置
在开始实战之前,我们需要完成基础环境的搭建。aardio 作为一款轻量级的自动化工具语言,与 Sunny 的配合使用能够极大提升开发效率。
2.1 初始化 Sunny 实例
首先创建一个基本的 aardio 窗体应用程序,并初始化 Sunny 实例:
import win.ui; import godking.sunny; /* 创建主窗口 */ var winform = win.form(text="Sunny 拦截演示"; right=800; bottom=600) /* 初始化 Sunny 实例 */ var sunny = godking.sunny(); /* 设置回调函数 */ sunny.callback_http = function(winform, context, id, msgid, msgtype, mod, url, err, pid) { // HTTP/HTTPS 回调处理 } sunny.callback_websocket = function(winform, context, id, msgid, msgtype, mod, url, err, pid, wsDataType) { // WebSocket 回调处理 } winform.show(); win.loopMessage();2.2 消息类型解析
Sunny 将网络消息分为三类,通过 msgType 参数进行区分:
- http_:包含 HTTP 和 HTTPS 协议消息
- ws_:包含 WebSocket 和 WSS 安全连接消息
- tcp_:纯 TCP 协议消息
每种消息类型又细分为多种子类型,例如对于 HTTP 协议:
import godking.sunny; // HTTP 消息类型判断示例 if msgtype == godking.sunny.msgType.http_request { // 处理 HTTP 请求 } else if msgtype == godking.sunny.msgType.http_response { // 处理 HTTP 响应 }3. HTTP/HTTPS 数据拦截与修改
HTTP/HTTPS 作为最常用的网络协议,是数据拦截的主要场景。Sunny 提供了完整的请求/响应生命周期控制能力。
3.1 请求拦截与修改
以下示例展示如何拦截图片请求并进行替换:
sunny.callback_http = function(winform, context, id, msgid, msgtype, mod, url, err, pid) { if msgtype == godking.sunny.msgType.http_request { var request = godking.sunny.httpRequest(msgid); // 检查是否为图片请求 if string.find(url, ".jpg") or string.find(url, ".png") { // 替换图片 URL request.setUrl("http://example.com/replacement.jpg"); // 或者直接阻止请求 // request.setUrl(""); } } }3.2 响应内容修改
除了修改请求,我们还可以修改服务器返回的响应内容:
if msgtype == godking.sunny.msgType.http_response { var response = godking.sunny.httpResponse(msgid); var contentType = response.getHeader("Content-Type"); if string.find(contentType, "text/html") { var body = response.getBodyText(); // 修改 HTML 内容 body = string.replace(body, "</body>", "<script>alert('Modified!')</script></body>"); response.setBody(body); } }3.3 请求头操作
HTTP 头信息是协议控制的重要部分,Sunny 提供了完整的头信息操作接口:
// 添加或修改请求头 request.setHeader("X-Custom-Header", "MyValue"); // 删除请求头 request.delHeader("User-Agent"); // 获取所有头信息 var headers = request.getAllHeaders();4. WebSocket 消息拦截与处理
WebSocket 作为全双工通信协议,在实时应用中广泛使用。Sunny 可以拦截 WebSocket 的发送和接收消息。
4.1 基本消息拦截
sunny.callback_websocket = function(winform, context, id, msgid, msgtype, mod, url, err, pid, wsDataType) { if msgtype == godking.sunny.msgType.ws_send { // 拦截发送的消息 var ws = godking.sunny.webSocket(msgid); var message = ws.getBodyText(); message = message + " [Modified]"; ws.setBody(message); } else if msgtype == godking.sunny.msgType.ws_received { // 拦截接收的消息 var ws = godking.sunny.webSocket(msgid); var message = ws.getBodyText(); // 消息处理逻辑... } }4.2 消息类型处理
WebSocket 支持文本和二进制两种消息格式,需要分别处理:
if wsDataType == 1 { // 文本消息 var text = ws.getBodyText(); // 文本处理逻辑... } else { // 二进制消息 var binaryData = ws.getBodyBinary(); // 二进制数据处理逻辑... }5. TCP 数据流拦截与分析
对于原始 TCP 连接,Sunny 提供了底层的数据包访问能力,适用于自定义协议的开发与调试。
5.1 TCP 数据拦截基础
// 在回调函数中处理 TCP 数据 if string.find(msgtype, "tcp_") { var tcp = godking.sunny.tcpConnection(msgid); // 获取连接信息 var localAddr = tcp.getLocalAddr(); var remoteAddr = tcp.getRemoteAddr(); // 获取原始数据 var data = tcp.getBodyBinary(); // 修改数据 // ...处理逻辑... tcp.setBody(modifiedData); }5.2 TCP 连接管理
Sunny 允许对 TCP 连接进行精细控制:
// 主动关闭连接 tcp.close(); // 获取连接状态 var state = tcp.getState(); // 设置超时时间 tcp.setTimeout(5000); // 5秒6. 实战案例:综合协议处理系统
结合上述技术,我们可以构建一个完整的网络协议处理系统。以下是一个综合示例,展示如何处理不同类型的协议数据。
6.1 协议分发器实现
sunny.callback_http = function(winform, context, id, msgid, msgtype, mod, url, err, pid) { // 协议分发处理 if string.find(msgtype, "http_") { processHttp(winform, msgid, msgtype, url); } } sunny.callback_websocket = function(winform, context, id, msgid, msgtype, mod, url, err, pid, wsDataType) { if string.find(msgtype, "ws_") { processWebSocket(winform, msgid, msgtype, wsDataType); } } function processHttp(winform, msgid, msgtype, url) { // HTTP 处理逻辑... } function processWebSocket(winform, msgid, msgtype, wsDataType) { // WebSocket 处理逻辑... }6.2 性能优化技巧
在处理大量网络数据时,性能优化至关重要:
- 减少内存拷贝:尽量直接操作原始数据缓冲区
- 异步处理:耗时操作应放在独立线程中
- 缓存利用:对频繁访问的资源进行缓存
- 选择性拦截:只处理必要的协议和URL
// 示例:使用缓存避免重复处理 var cache = {}; sunny.callback_http = function(winform, context, id, msgid, msgtype, mod, url, err, pid) { if cache[url] { return cachedResponse(url); } // 正常处理逻辑... }7. 高级应用场景
Sunny 的灵活性使其能够适应各种复杂的应用场景。
7.1 安全测试工具开发
利用 Sunny 可以快速构建安全测试工具:
// 简单的 XSS 检测 sunny.callback_http = function(winform, context, id, msgid, msgtype, mod, url, err, pid) { if msgtype == godking.sunny.msgType.http_request { var request = godking.sunny.httpRequest(msgid); var params = request.getParams(); // 检查参数中是否包含可疑脚本 for k,v in params { if string.find(v, "<script>") { logSecurityAlert("XSS Attempt", url, params); } } } }7.2 协议调试辅助工具
开发自定义协议时,Sunny 可以作为强大的调试助手:
// TCP 协议调试器示例 sunny.callback_tcp = function(winform, context, id, msgid, msgtype, mod, url, err, pid) { var tcp = godking.sunny.tcpConnection(msgid); var data = tcp.getBodyBinary(); // 以十六进制格式输出数据 var hexDump = binaryToHex(data); winform.edit.addText(hexDump + "\n"); } function binaryToHex(data) { // 二进制转十六进制实现... }7.3 流量统计与分析
Sunny 可以轻松实现流量监控功能:
var trafficStats = { http: 0, websocket: 0, tcp: 0 }; sunny.callback_http = function(...) { trafficStats.http++; updateStatsDisplay(); } sunny.callback_websocket = function(...) { trafficStats.websocket++; updateStatsDisplay(); } function updateStatsDisplay() { winform.statsText.text = string.format("HTTP: %d\nWS: %d\nTCP: %d", trafficStats.http, trafficStats.websocket, trafficStats.tcp); }8. 常见问题与解决方案
在实际使用 Sunny 过程中,可能会遇到一些典型问题,以下是常见问题的解决方法。
8.1 性能瓶颈处理
当处理大量连接时,可能会遇到性能问题。优化建议包括:
- 减少回调函数复杂度:保持回调函数尽可能简单
- 使用过滤器:只处理必要的消息类型
- 批量操作:合并多个小数据包的处理
// 使用消息类型过滤器提高性能 sunny.setMsgTypeFilter({ http_request = true, http_response = false, ws_send = true, ws_received = false });8.2 内存管理注意事项
Sunny 虽然自身内存管理良好,但在处理大量数据时仍需注意:
- 及时释放资源:特别是二进制数据
- 避免内存泄漏:检查回调函数中的循环引用
- 监控内存使用:添加内存监控逻辑
// 内存监控示例 setInterval(function() { var mem = ..process.getMemoryInfo(); if mem.workingSet > 100*1024*1024 { // 超过100MB alert("内存使用过高!"); } }, 5000);8.3 多线程安全实践
Sunny 的回调函数运行在多线程环境中,需要注意线程安全问题:
- 避免直接访问UI元素:使用线程安全的方式更新界面
- 使用同步机制:对共享资源加锁
- 减少全局变量使用:尽量使用局部变量
// 线程安全的UI更新 sunny.callback_http = function(winform, ...) { ..thread.invoke( function() { winform.log.addText("New HTTP request\n"); } ); }9. 扩展应用与进阶技巧
掌握了 Sunny 的基础用法后,可以进一步探索其高级功能。
9.1 自定义协议解析
Sunny 的 TCP 拦截能力可以用来解析自定义协议:
// 自定义协议解析器框架 var protocolParser = { buffer = "", processData = function(data) { this.buffer += data; while this.hasCompletePacket() { var packet = this.extractPacket(); this.handlePacket(packet); } }, hasCompletePacket = function() { // 实现协议特定的包完整性检查 }, extractPacket = function() { // 从缓冲区提取完整数据包 }, handlePacket = function(packet) { // 处理解析后的数据包 } } sunny.callback_tcp = function(...) { var tcp = godking.sunny.tcpConnection(msgid); var data = tcp.getBodyBinary(); protocolParser.processData(data); }9.2 与其它工具集成
Sunny 可以与其他开发工具配合使用,形成更强大的工具链:
- 与 Wireshark 配合:导出数据包进行深度分析
- 与 Postman 集成:拦截并修改 API 请求
- 与自动化测试框架结合:实现网络层的测试验证
// 导出数据到文件供其他工具分析 function exportToPcap(data) { var file = io.open("capture.pcap", "wb"); file.write(data); file.close(); }9.3 性能监控与调优
开发高性能网络应用时,监控和调优至关重要:
关键指标监控:
- 请求处理延迟
- 内存使用情况
- 网络吞吐量
性能分析工具:
- 内置性能计数器
- 外部性能分析器集成
// 简单的性能计数器 var perf = { startTime = ..time.now(), requestCount = 0, logRequest = function() { this.requestCount++; if this.requestCount % 100 == 0 { var elapsed = ..time.now() - this.startTime; var rps = this.requestCount / elapsed * 1000; console.log("Requests per second:", rps); } } }10. 最佳实践与经验分享
根据实际项目经验,总结以下使用 Sunny 的最佳实践:
- 模块化设计:将不同协议的处理逻辑分离到独立模块中
- 配置驱动:通过配置文件控制拦截规则,避免硬编码
- 完善的日志:记录详细的操作日志,便于问题排查
- 错误处理:健壮的错误处理机制确保稳定性
- 资源清理:确保所有资源在程序退出时正确释放
// 配置驱动的拦截规则示例 var config = { http = { intercept = true, modifyHeaders = true, redirectRules = { {"example.com", "alternate.com"} } }, websocket = { intercept = false } }; // 根据配置初始化 Sunny if config.http.intercept { sunny.callback_http = createHttpHandler(config.http); }在实际项目中,我们发现对 WebSocket 消息进行实时修改时,保持消息顺序至关重要。特别是在高频交易系统中,即使微小的延迟或顺序错乱都可能导致严重问题。为此,我们实现了基于时间戳的消息队列机制,确保处理后的消息保持原有顺序。