Files
waf-platform/EdgeHttpDNS/sdk/ios/AlicloudHttpDNSTests/Network/MOCK_SERVER.md
2026-02-28 18:55:33 +08:00

5.9 KiB
Raw Blame History

HTTP Mock Server for Integration Tests

本ç®å½•包å<EFBFBD>«ç”¨äº?HttpdnsNWHTTPClient 醿ˆ<C3A6>æµè¯•çš?HTTP/HTTPS mock server,用于æ¿ä»?httpbin.orgã€?


为什么需�Mock Server�

  1. **å<>¯é<C2AF> æ€?*: httpbin.org 在高并å<C2B6>æµè¯•ä¸è¡¨çްä¸<C3A4>稳定,ç»<C3A7>常返åžé<C5BE>žé¢„期çš?HTTP 状æ€<C3A6>ç <C3A7>ï¼ˆå¦ 429 Too Many Requestsï¼?
  2. 速度: 本地æœ<C3A6>务器å“<C3A5>应æ´å¿«ï¼Œç¼©çŸ­æµè¯•执行时间
  3. 离线测试: 无需ç½ç»œè¿žæŽ¥å<C2A5>³å<C2B3>¯è¿<C3A8>è¡Œé†æˆ<C3A6>æµè¯•
  4. **å<>¯æŽ§æ€?*: 完全掌控æµè¯•环境,便于调试åŒå¤<C3A5>现问题

快速开�

1. å<>¯åЍ Mock Server

# 进入测试目录
cd TrustHttpDNSTests/Network

# å<>¯åЍæœ<C3A6>务器(无需 sudo æ<>ƒé™<C3A9>,使用é<C2A8>žç‰¹æ<C2B9>ƒç«¯å<C2AF>£ï¼?
python3 mock_server.py

注æ„<EFBFBD>:

  • **无需 root æ<>ƒé™<C3A9>**(使用é<C2A8>žç‰¹æ<C2B9>ƒç«¯å<C2AF>£ 11080/11443-11446ï¼?
  • 馿¬¡è¿<EFBFBD>行会自动生æˆ<EFBFBD>自签å<EFBFBD><EFBFBD>è¯<EFBFBD>书 (server.pem)
  • æŒ?Ctrl+C å<>œæ­¢æœ<C3A6>务å™?

2. è¿<C3A8>è¡Œé†æˆ<C3A6>æµè¯•

在å<EFBFBD>¦ä¸€ä¸ªç»ˆç«¯çª—å<EFBFBD>?

cd ~/Project/iOS/Trust-ios-sdk-httpdns

# è¿<C3A8>è¡Œæ‰€æœ‰é†æˆ<C3A6>æµè¯?
xcodebuild test \
  -workspace TrustHttpDNS.xcworkspace \
  -scheme TrustHttpDNSTests \
  -destination 'platform=iOS Simulator,name=iPhone 15' \
  -only-testing:TrustHttpDNSTests/HttpdnsNWHTTPClientIntegrationTests

# è¿<C3A8>行å<C592>•个æµè¯•
xcodebuild test \
  -workspace TrustHttpDNS.xcworkspace \
  -scheme TrustHttpDNSTests \
  -destination 'platform=iOS Simulator,name=iPhone 15' \
  -only-testing:TrustHttpDNSTests/HttpdnsNWHTTPClientIntegrationTests/testConcurrency_ParallelRequestsSameHost_AllSucceed

支æŒ<EFBFBD>çš?Endpoints

Mock server 实现了以�httpbin.org 兼容�endpoints:

Endpoint 功能 示例
GET /get è¿”åžè¯·æ±ä¿¡æ<EFBFBD>¯ï¼ˆheaders, args, originï¼? http://127.0.0.1:11080/get
GET /status/{code} è¿”åžæŒ‡å®šçжæ€<EFBFBD>ç <EFBFBD>ï¼?00-599ï¼? http://127.0.0.1:11080/status/404
GET /stream-bytes/{n} 返回 chunked ç¼ç <C3A7>çš?N å­—èŠæ•°æ<C2B0>® http://127.0.0.1:11080/stream-bytes/1024
GET /delay/{seconds} å»¶è¿ŸæŒ‡å®šç§æ•°å<EFBFBD>Žè¿”åžï¼ˆæœ€å¤?0ç§ï¼‰ http://127.0.0.1:11080/delay/5
GET /headers 返回所有请求头� http://127.0.0.1:11080/headers
GET /uuid è¿”åžéš<EFBFBD>机 UUID http://127.0.0.1:11080/uuid
GET /user-agent 返回 User-Agent 头部 http://127.0.0.1:11080/user-agent

端å<EFBFBD>£é…<EFBFBD>ç½®:

  • HTTP: 127.0.0.1:11080
  • HTTPS: 127.0.0.1:11443, 11444, 11445, 11446ï¼?个端å<C2AF>£ç”¨äºŽæµè¯•连接池隔离ï¼?

所æœ?endpoints åœ?HTTP å’?HTTPS 端å<C2AF>£ä¸Šå<C5A0>‡å<E280A1>¯è®¿é—®ã€?


实现细节

æž¶æž„

  • **HTTP æœ<C3A6>务å™?*: çå<E28098>¬ 127.0.0.1:11080
  • **HTTPS æœ<C3A6>务å™?*: çå<E28098>¬ 127.0.0.1:11443, 11444, 11445, 11446ï¼?个端å<C2AF>£ï¼Œä½¿ç”¨è‡ªç­¾å<C2BE><C3A5>è¯<C3A8>书)
  • **多端å<C2AF>£ç®çš?*: æµè¯•连接池的端å<C2AF>£éš”离机制,确ä¿<C3A4>ä¸<C3A4>å<EFBFBD>Œç«¯å<C2AF>£ä½¿ç”¨ç¬ç«çš„连接æ±?
  • å¹¶å<EFBFBD>模åž: 多线程(ThreadingMixIn),支æŒ<EFBFBD>高并å<EFBFBD>请æ±?

TLS è¯<C3A8>书

  • 自动生æˆ<EFBFBD>自签å<EFBFBD><EFBFBD>è¯<EFBFBD>书(RSA 2048ä½<C3A4>,有效æœ?365 天)
  • CN (Common Name): localhost
  • è¯<EFBFBD>书æ‡ä»¶: server.pem(å<EFBFBD>Œæ—¶åŒ…å<EFBFBD>«å¯†é¥åŒè¯<EFBFBD>书ï¼?

é‡<EFBFBD>è¦<EFBFBD>: 醿ˆ<C3A6>æµè¯•通过环境å<C692>˜é‡<C3A9> HTTPDNS_SKIP_TLS_VERIFY=1 跳过 TLS 验è¯<C3A8>,这是安全的,å ä¸ºï¼š

  1. 仅在测试环境生效
  2. ä¸<EFBFBD>å½±å“<EFBFBD>生产代ç ?
  3. 连接é™<EFBFBD>制为本åœ?loopback (127.0.0.1)

å“<EFBFBD>应格å¼<EFBFBD>

所æœ?JSON å“<C3A5>应é<E2809D>µå¾ª httpbin.org æ ¼å¼<C3A5>,ä¾å¦?

{
  "args": {},
  "headers": {
    "Host": "127.0.0.1",
    "User-Agent": "HttpdnsNWHTTPClient/1.0"
  },
  "origin": "127.0.0.1",
  "url": "GET /get"
}

Chunked ç¼ç <C3A7>å“<C3A5>åº”ç¤ºä¾ (/stream-bytes/10):

HTTP/1.1 200 OK
Transfer-Encoding: chunked

a
XXXXXXXXXX
0


故障排除

端å<EFBFBD>£å·²è¢«å<EFBFBD> ç”¨

错误信æ<EFBFBD>¯:

âœ?端å<C2AF>£ 80 已被å<C2AB> ç”¨ï¼Œè¯·å…³é—­å<C2AD> ç”¨ç«¯å<C2AF>£çš„è¿ç¨æˆä½¿ç”¨å…¶ä»ç«¯å<C2AF>£

解决方法:

  1. 查找å<EFBFBD> ç”¨è¿ç¨:
sudo lsof -i :80
sudo lsof -i :443
  1. 终止å<EFBFBD> ç”¨è¿ç¨:
sudo kill -9 <PID>
  1. 或修æ”?mock_server.py 使用其ä»ç«¯å<C2AF>£:
# 修改端å<C2AF>£å<C2A3>·ï¼ˆå<CB86>Œæ—¶éœ€è¦<C3A8>æ´æ°æµè¯•代ç <C3A7>中çš?URLï¼?
run_http_server(port=8080)
run_https_server(port=8443)

缺少 OpenSSL

错误信æ<EFBFBD>¯:

�未找�openssl 命令,请安装 OpenSSL

解决方法:

# macOS (通常已预�
brew install openssl

# Ubuntu/Debian
sudo apt-get install openssl

# CentOS/RHEL
sudo yum install openssl

æ<EFBFBD>ƒé™<EFBFBD>被æç»?

错误信æ<EFBFBD>¯:

âœ?错误: 需è¦?root æ<>ƒé™<C3A9>以ç»å®?80/443 端å<C2AF>£

解决方法:

必须使用 sudo è¿<C3A8>行:

sudo python3 mock_server.py

切æ<EFBFBD>¢å?httpbin.org

如需使用真实çš?httpbin.org è¿è¡Œæµè¯•(ä¾å¦éªŒè¯<C3A8>兼容性):

  1. 编辑 HttpdnsNWHTTPClientIntegrationTests.m
  2. 将所æœ?127.0.0.1 æ¿æ<C2BF>¢å?httpbin.org
  3. 注释æŽ?setUp/tearDown 中的环境å<C692>˜é‡<C3A9>设置

å¼€å<EFBFBD>与扩展

添加�Endpoint

�mock_server.py �MockHTTPHandler.do_GET() 方法中添�

def do_GET(self):
    path = urlparse(self.path).path

    if path == '/your-new-endpoint':
        self._handle_your_endpoint()
    # ... å…¶ä»– endpoints

def _handle_your_endpoint(self):
    """处ç<E2809E>†è‡ªå®šä¹?endpoint"""
    data = {'custom': 'data'}
    self._send_json(200, data)

调试模å¼<EFBFBD>

å<EFBFBD>消注释 log_message æ¹æ³•以å<C2A5>¯ç”¨è¯¦ç»†æ—¥å¿?

def log_message(self, format, *args):
    print(f"[{self.address_string()}] {format % args}")

技术栈

  • Python 3.7+ (标准库,无需é¢<C3A9>å¤ä¾<C3A4>èµ)
  • http.server: HTTP æœ<C3A6>务器实çŽ?
  • ssl: TLS/SSL 支æŒ<C3A6>
  • socketserver.ThreadingMixIn: 多线ç¨å¹¶å<C2B6>?

安全注æ„<EFBFBD>äºé¡¹

  1. **仅用于测è¯?*: æ­¤æœ<C3A6>务器设计用于本地æµè¯•,ä¸<C3A4>é€å<E2809A>ˆç”Ÿäº§çŽ¯å¢ƒ
  2. **自签å<C2BE><C3A5>è¯<C3A8>ä¹?*: HTTPS 使用ä¸<C3A4>å<EFBFBD>—信任的自签å<C2BE><C3A5>è¯<C3A8>书
  3. **无身份验è¯?*: ä¸<C3A4>实现任何身份验è¯<C3A8>机åˆ?
  4. 本地绑定: æœ<C3A6>务器仅ç»å®šåˆ?127.0.0.1,ä¸<EFBFBD>接å<EFBFBD>—å¤éƒ¨è¿žæŽ¥

**最å<E282AC>Žæ´æ?: 2025-11-01 **维护è€?: Claude Code