feat: sync httpdns sdk/platform updates without large binaries

This commit is contained in:
robin
2026-03-04 17:59:14 +08:00
parent 853897a6f8
commit 532891fad0
700 changed files with 6096 additions and 2712 deletions

View File

@@ -0,0 +1,253 @@
# HTTP Mock Server for Integration Tests
本目录包含用<EFBFBD><EFBFBD>?`HttpdnsNWHTTPClient` 集成测试<E6B58B><E8AF95>?HTTP/HTTPS mock server用于替<E4BA8E><E69BBF>?httpbin.org<72><67>?
---
## 为什么需<E4B988><E99C80>?Mock Server<65><72>?
1. **可靠<E58FAF><E99DA0>?*: httpbin.org 在高并发测试下表现不稳定经常返回非预期<E9A284><E69C9F>?HTTP 状态码(如 429 Too Many Requests<74><73>?
2. **速度**: 本地服务器响应更快,缩短测试执行时间
3. **离线测试**: 无需网络连接即可运行集成测试
4. **可控<E58FAF><E68EA7>?*: 完全掌控测试环境,便于调试和复现问题
---
## 快速开<E9809F><E5BC80>?
### 1. 启动 Mock Server
```bash
# 进入测试目录
cd TrustHttpDNSTests/Network
# 启动服务器(无需 sudo 权限使用非特权端口<E7ABAF><E58FA3>?
python3 mock_server.py
```
**注意**:
- **无需 root 权限**(使用非特权端口 11080/11443-11446<34><36>?
- 首次运行会自动生成自签名证书 (`server.pem`)
- <20><>?`Ctrl+C` 停止服务<E69C8D><E58AA1>?
### 2. 运行集成测试
在另一个终端窗<EFBFBD><EFBFBD>?
```bash
cd ~/Project/iOS/Trust-ios-sdk-httpdns
# 运行所有集成测<E68890><E6B58B>?
xcodebuild test \
-workspace TrustHttpDNS.xcworkspace \
-scheme TrustHttpDNSTests \
-destination 'platform=iOS Simulator,name=iPhone 15' \
-only-testing:TrustHttpDNSTests/HttpdnsNWHTTPClientIntegrationTests
# 运行单个测试
xcodebuild test \
-workspace TrustHttpDNS.xcworkspace \
-scheme TrustHttpDNSTests \
-destination 'platform=iOS Simulator,name=iPhone 15' \
-only-testing:TrustHttpDNSTests/HttpdnsNWHTTPClientIntegrationTests/testConcurrency_ParallelRequestsSameHost_AllSucceed
```
---
## 支持<E694AF><E68C81>?Endpoints
Mock server 实现了以<E4BA86><E4BBA5>?httpbin.org 兼容<E585BC><E5AEB9>?endpoints:
| Endpoint | 功能 | 示例 |
|----------|------|------|
| `GET /get` | 返回请求信息headers, args, origin<69><6E>?| `http://127.0.0.1:11080/get` |
| `GET /status/{code}` | 返回指定状态码<E68081><E7A081>?00-599<39><39>?| `http://127.0.0.1:11080/status/404` |
| `GET /stream-bytes/{n}` | 返回 chunked 编码<E7BC96><E7A081>?N 字节数据 | `http://127.0.0.1:11080/stream-bytes/1024` |
| `GET /delay/{seconds}` | 延迟指定秒数后返回<EFBC88><E69C80>?0秒 | `http://127.0.0.1:11080/delay/5` |
| `GET /headers` | 返回所有请求头<E6B182><E5A4B4>?| `http://127.0.0.1:11080/headers` |
| `GET /uuid` | 返回随机 UUID | `http://127.0.0.1:11080/uuid` |
| `GET /user-agent` | 返回 User-Agent 头部 | `http://127.0.0.1:11080/user-agent` |
**端口配置**:
- **HTTP**: `127.0.0.1:11080`
- **HTTPS**: `127.0.0.1:11443`, `11444`, `11445`, `11446`<EFBFBD><EFBFBD>?个端口用于测试连接池隔离<E99A94><E7A6BB>?
<EFBFBD><EFBFBD>?endpoints <20><>?HTTP <20><>?HTTPS 端口上均可访问<E8AEBF><E997AE>?
---
## 实现细节
### 架构
- **HTTP 服务<E69C8D><E58AA1>?*: 监听 `127.0.0.1:11080`
- **HTTPS 服务<E69C8D><E58AA1>?*: 监听 `127.0.0.1:11443`, `11444`, `11445`, `11446`<EFBFBD><EFBFBD>?个端口,使用自签名证书)
- **多端口目<E58FA3><E79BAE>?*: 测试连接池的端口隔离机制确保不同端口使用独立的连接<E8BF9E><E68EA5>?
- **并发模型**: 多线程(`ThreadingMixIn`支持高并发请<EFBFBD><EFBFBD>?
### TLS 证书
- 自动生成自签名证书RSA 2048位有效<E69C89><E69588>?365 天)
- CN (Common Name): `localhost`
- 证书文件: `server.pem`同时包含密钥和证书<EFBFBD><EFBFBD>?
**重要**: 集成测试通过环境变量 `HTTPDNS_SKIP_TLS_VERIFY=1` 跳过 TLS 验证,这是安全的,因为:
1. 仅在测试环境生效
2. 不影响生产代<E4BAA7><E4BBA3>?
3. 连接限制为本<E4B8BA><E69CAC>?loopback (127.0.0.1)
### 响应格式
<EFBFBD><EFBFBD>?JSON 响应遵循 httpbin.org 格式<EFBC8C><E4BE8B>?
```json
{
"args": {},
"headers": {
"Host": "127.0.0.1",
"User-Agent": "HttpdnsNWHTTPClient/1.0"
},
"origin": "127.0.0.1",
"url": "GET /get"
}
```
Chunked 编码响应示例 (`/stream-bytes/10`):
```
HTTP/1.1 200 OK
Transfer-Encoding: chunked
a
XXXXXXXXXX
0
```
---
## 故障排除
### 端口已被占用
**错误信息**:
```
<EFBFBD><EFBFBD>?端口 80 已被占用,请关闭占用端口的进程或使用其他端口
```
**解决方法**:
1. 查找占用进程:
```bash
sudo lsof -i :80
sudo lsof -i :443
```
2. 终止占用进程:
```bash
sudo kill -9 <PID>
```
3. 或修<E68896><E4BFAE>?mock_server.py 使用其他端口:
```python
# 修改端口号同时需要更新测试代码中<E7A081><E4B8AD>?URL<52><4C>?
run_http_server(port=8080)
run_https_server(port=8443)
```
### 缺少 OpenSSL
**错误信息**:
```
<EFBFBD><EFBFBD>?未找<E69CAA><E689BE>?openssl 命令,请安装 OpenSSL
```
**解决方法**:
```bash
# macOS (通常已预<E5B7B2><E9A284>?
brew install openssl
# Ubuntu/Debian
sudo apt-get install openssl
# CentOS/RHEL
sudo yum install openssl
```
### 权限被拒<E8A2AB><E68B92>?
**错误信息**:
```
<EFBFBD><EFBFBD>?错误: 需<><E99C80>?root 权限以绑<E4BBA5><E7BB91>?80/443 端口
```
**解决方法**:
必须使用 `sudo` 运行:
```bash
sudo python3 mock_server.py
```
---
## 切换<E58887><E68DA2>?httpbin.org
如需使用真实<EFBFBD><EFBFBD>?httpbin.org 进行测试(例如验证兼容性):
1. 编辑 `HttpdnsNWHTTPClientIntegrationTests.m`
2. 将所<E5B086><E68980>?`127.0.0.1` 替换<E69BBF><E68DA2>?`httpbin.org`
3. 注释<E6B3A8><E9878A>?setUp/tearDown 中的环境变量设置
---
## 开发与扩展
### 添加<E6B7BB><E58AA0>?Endpoint
<EFBFBD><EFBFBD>?`mock_server.py` <20><>?`MockHTTPHandler.do_GET()` 方法中添<E4B8AD><E6B7BB>?
```python
def do_GET(self):
path = urlparse(self.path).path
if path == '/your-new-endpoint':
self._handle_your_endpoint()
# ... 其他 endpoints
def _handle_your_endpoint(self):
"""处理自定<E887AA><E5AE9A>?endpoint"""
data = {'custom': 'data'}
self._send_json(200, data)
```
### 调试模式
取消注释 `log_message` 方法以启用详细日<E7BB86><E697A5>?
```python
def log_message(self, format, *args):
print(f"[{self.address_string()}] {format % args}")
```
---
## 技术栈
- **Python 3.7+** (标准库,无需额外依赖)
- **http.server**: HTTP 服务器实<E599A8><E5AE9E>?
- **ssl**: TLS/SSL 支持
- **socketserver.ThreadingMixIn**: 多线程并<E7A88B><E5B9B6>?
---
## 安全注意事项
1. **仅用于测<E4BA8E><E6B58B>?*: 此服务器设计用于本地测试,不适合生产环境
2. **自签名证<E5908D><E8AF81>?*: HTTPS 使用不受信任的自签名证书
3. **无身份验<E4BBBD><E9AA8C>?*: 不实现任何身份验证机<E8AF81><E69CBA>?
4. **本地绑定**: 服务器仅绑定<E7BB91><E5AE9A>?`127.0.0.1`,不接受外部连接
---
**最后更<E5908E><E69BB4>?*: 2025-11-01
**维护<E7BBB4><E68AA4>?*: Claude Code