feat: sync httpdns sdk/platform updates without large binaries
This commit is contained in:
253
HttpDNSSDK/sdk/ios/NewHttpDNSTests/Network/MOCK_SERVER.md
Normal file
253
HttpDNSSDK/sdk/ios/NewHttpDNSTests/Network/MOCK_SERVER.md
Normal 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
|
||||
Reference in New Issue
Block a user