https://github.com/78/quic-h3-client
A pure python implemented QUIC HTTP/3 Client
https://github.com/78/quic-h3-client
Last synced: 5 months ago
JSON representation
A pure python implemented QUIC HTTP/3 Client
- Host: GitHub
- URL: https://github.com/78/quic-h3-client
- Owner: 78
- Created: 2025-11-28T11:40:24.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-11-28T11:53:17.000Z (7 months ago)
- Last Synced: 2025-11-30T19:09:17.988Z (6 months ago)
- Language: Python
- Size: 159 KB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# HTTP/3 Client Pure Python Implementation
一个从零实现的 QUIC/HTTP/3 轻型客户端(仅进行 API HTTP 请求),学习研究用。
## 📋 目录
- [项目简介](#项目简介)
- [已实现功能](#已实现功能)
- [未实现功能](#未实现功能)
- [快速开始](#快速开始)
- [项目结构](#项目结构)
- [注意事项](#注意事项)
---
## 项目简介
这是一个完全从零实现的 HTTP/3 客户端,遵循以下标准:
- **RFC 9000**: QUIC: A UDP-Based Multiplexed and Secure Transport
- **RFC 9001**: Using TLS to Secure QUIC
- **RFC 9002**: QUIC Loss Detection and Congestion Control
- **RFC 9114**: HTTP/3
- **RFC 9204**: QPACK: Header Compression for HTTP/3
### 设计目标
- ✅ 轻量级实现,适合嵌入式设备
- ✅ 支持 TLS 1.3 加密和 0-RTT 会话恢复
- ✅ 完整的丢包检测和重传机制
- ✅ QPACK 头部压缩(静态表 + 动态表解码)
- ✅ 多流并发请求
### 适用场景
- 需要快速连接建立的场景(0-RTT)
- 学习和研究 QUIC/HTTP/3 协议
---
## ✅ 已实现功能
### QUIC 协议层
#### 连接管理
- ✅ **连接建立**: Initial → Handshake → 1-RTT 完整流程
- ✅ **TLS 1.3 加密**:
- AEAD-GCM-128/256 加密
- X25519 密钥交换
- 证书验证
- ✅ **0-RTT 会话恢复**: Session Ticket 支持,加速后续连接
- ✅ **Key Update**: RFC 9001 Section 6,支持 1-RTT 密钥轮换
- 主动发起密钥更新(`initiate_key_update()`)
- 处理对端发起的密钥更新
- Key Phase bit 正确设置和检测
- 过渡期密钥管理(支持新旧密钥并存)
- ✅ **优雅关闭**: CONNECTION_CLOSE 帧处理
- ✅ **Stateless Reset**: 检测和处理无状态重置包
- ✅ **Connection ID 管理**:
- NEW_CONNECTION_ID 帧发送和接收
- RETIRE_CONNECTION_ID 帧处理(自动和手动)
- 根据 `retire_prior_to` 自动退休旧连接 ID
- ✅ **路径验证**:
- PATH_CHALLENGE (0x1a) 帧发送和接收
- PATH_RESPONSE (0x1b) 帧自动响应
- 主动路径验证 API (`send_path_challenge()`, `validate_path_async()`)
- 支持网络切换场景的路径探测
#### 流控制
- ✅ **连接级流控**: MAX_DATA 帧
- ✅ **流级流控**: MAX_STREAM_DATA 帧
- ✅ **流限制**: MAX_STREAMS_BIDI/UNI 帧
#### 丢包检测与恢复
- ✅ **RTT 估算**: 基于 RFC 9002 的 RTT 平滑算法
- ✅ **丢包检测**:
- 时间阈值检测(9/8 × RTT)
- 包数阈值检测(3 个包)
- ✅ **PTO 探测**: Probe Timeout 机制,防止连接卡死
- ✅ **ACK 处理**: 发送和接收 ACK 帧
- ✅ **帧重传**: CRYPTO 和 STREAM 帧自动重传
#### 拥塞控制
- ✅ **CWND 窗口管理**: 基于 RFC 9002 的拥塞窗口控制
- ✅ **Slow Start**: 慢启动算法,初始窗口 14720 字节(10 × MTU)
- ✅ **Congestion Avoidance**: 拥塞避免阶段线性增长
- ✅ **AIMD**: 加性增乘性减算法(NewReno 风格)
- ✅ **Recovery 状态**: 丢包时的拥塞恢复机制
- ✅ **Persistent Congestion**: 持续拥塞检测和窗口重置
#### 帧类型支持
- ✅ PADDING (0x00)
- ✅ PING (0x01)
- ✅ ACK (0x02)
- ✅ CRYPTO (0x06)
- ✅ NEW_TOKEN (0x07)
- ✅ STREAM (0x08-0x0f)
- ✅ MAX_DATA (0x10)
- ✅ MAX_STREAM_DATA (0x11)
- ✅ MAX_STREAMS_BIDI (0x12)
- ✅ MAX_STREAMS_UNI (0x13)
- ✅ NEW_CONNECTION_ID (0x18)
- ✅ RETIRE_CONNECTION_ID (0x19)
- ✅ PATH_CHALLENGE (0x1a)
- ✅ PATH_RESPONSE (0x1b)
- ✅ CONNECTION_CLOSE (0x1c)
- ✅ CONNECTION_CLOSE_APP (0x1d)
- ✅ HANDSHAKE_DONE (0x1e)
- ✅ DATAGRAM (0x30/0x31) - RFC 9221 扩展
#### DATAGRAM 扩展 (RFC 9221)
- ✅ **max_datagram_frame_size**: Transport Parameter 协商
- ✅ **DATAGRAM 帧**: 发送和接收不可靠数据报
- ✅ **可配置支持**: 通过 `enable_datagram` 参数启用
- ✅ **异步接收**: `recv_datagram()` 异步 API
### HTTP/3 协议层
#### 流管理
- ✅ **Control Stream**: 初始化和 SETTINGS 交换
- ✅ **QPACK Encoder Stream**: 接收服务器动态表更新
- ✅ **QPACK Decoder Stream**: 发送解码指令
- ✅ **请求流**: 双向流,支持并发请求
#### QPACK 头部压缩
- ✅ **静态表编码**: 发送请求时使用静态表索引
- ✅ **静态表解码**: 解码响应头中的静态表引用
- ✅ **动态表解码**: 完整支持服务器动态表更新和解码
- ✅ **Huffman 解码**: 响应头中的 Huffman 编码解码
- ✅ **Section Acknowledgment**: 发送解码确认
#### HTTP/3 帧
- ✅ **HEADERS (0x01)**: 请求/响应头
- ✅ **DATA (0x00)**: 请求/响应体
- ✅ **SETTINGS (0x04)**: 协议设置
- ✅ **GOAWAY (0x07)**: 优雅关闭流程(RFC 9114 Section 5.2)
- ✅ **MAX_PUSH_ID (0x0d)**: 推送 ID 限制
#### 功能特性
- ✅ **并发请求**: 单连接多流并发
- ✅ **流重组**: 处理乱序到达的数据
- ✅ **优雅关闭**: GOAWAY 帧支持,完整的 graceful shutdown API
- ✅ **Wireshark 支持**: SSLKEYLOGFILE 格式密钥日志
---
## ❌ 未实现功能
### 高优先级(建议实现)
---
### 中优先级(可选实现)
#### 🟡 高级拥塞控制算法
- ❌ **Cubic**: 基于立方函数的拥塞控制算法
- ❌ **BBR**: Google 的基于带宽和 RTT 的拥塞控制算法
**当前状态**: 已实现基于 RFC 9002 的 NewReno 风格拥塞控制(Slow Start + AIMD)
**影响**: 在某些网络环境下,高级算法可能提供更好的性能
---
### 低优先级(可选实现)
#### 🟢 Server Push
- ❌ **PUSH_PROMISE (0x05)**: 推送承诺帧处理
- ❌ **Push Stream**: 推送流处理
**当前状态**: 仅定义常量,无实际处理逻辑。MAX_PUSH_ID 设置为 0,明确禁用 Server Push。
**说明**: 虽然 HTTP/3 (RFC 9114) 协议层面仍然支持 Server Push,但在实际应用中已经很少使用:
- 服务器难以准确判断客户端需要哪些资源,容易浪费带宽
- 主流浏览器和客户端实现已经很少支持或默认禁用此功能
- 现代 Web 开发更倾向于使用其他优化技术(如预加载、预连接等)
**影响**: 无法接收服务器推送资源(实际应用中通常不需要)
#### 🟢 QPACK 动态表编码
- ❌ **客户端动态表**: 使用动态表压缩请求头
- ❌ **动态表管理**: 插入、复制、容量设置
**当前状态**: 只用静态表 + 字面量
**影响**: 请求头压缩率不够高(但对嵌入式设备影响小)
#### 🟢 Huffman 编码
- ❌ **请求头 Huffman 编码**: 发送请求时压缩字符串
**当前状态**: 只有解码,编码用原始字符串
**影响**: 对嵌入式设备影响很小
- API 请求头通常很短,Huffman 压缩收益有限(可能只节省几个字节)
- 编码需要额外的 CPU 和内存开销,收益不明显
- 2Mbps 带宽对 API 请求已足够
- 解码已实现,不影响接收服务器响应
#### 🟢 ECN 支持
- ❌ **ACK_ECN (0x03)**: 显式拥塞通知
**影响**: 无法利用 ECN 信号优化传输
---
### 扩展功能(可选)
#### ✅ DATAGRAM 帧 (已实现)
- ✅ **RFC 9221**: DATAGRAM 扩展支持
- ✅ `max_datagram_frame_size` Transport Parameter 协商
- ✅ 发送和接收 DATAGRAM 帧 (0x30/0x31)
- ✅ 异步接收 API (`recv_datagram()`, `recv_datagram_nowait()`)
**用途**: WebRTC、实时游戏等低延迟场景
**用法**:
```python
# 创建连接时启用 DATAGRAM
client = QuicConnection("example.com", 443, enable_datagram=True)
# 检查是否可用
if client.datagram_available:
# 发送数据报
client.send_datagram(b"Hello!")
# 异步接收数据报
data = await client.recv_datagram(timeout=5.0)
```
#### ⚪ WebTransport
- ❌ **WebTransport over HTTP/3**: 双向流传输
**当前状态**: EXTENDED_CONNECT 设置已改为 0(嵌入式设备不需要)
---
## 🚀 快速开始
### 安装依赖
```bash
pip install -r requirements.txt
```
### 基本使用
```bash
# 单个请求
python main.py api.tenclass.net
# 指定路径和端口
python main.py cloudflare-quic.com -p 443 --path /
# 并发请求
python main.py -c api.tenclass.net --paths /health /api/status
# 0-RTT 模式(首次连接保存会话)
python main.py api.tenclass.net -s session.json
# 使用保存的会话(0-RTT)
python main.py api.tenclass.net -s session.json
```
### 运行示例
以下是一个完整的运行示例,展示访问 www.taobao.com 的 HTTP/3 请求:
```bash
$ python main.py www.taobao.com --path / -q
HTTP/3 Client - Keys will be written to quic_keys.log (Wireshark SSLKEYLOGFILE format)
Mode: SINGLE REQUEST
Target: https://www.taobao.com:443/
Press Ctrl+C to exit
============================================================
HTTP/3 Client
============================================================
Key log file: quic_keys.log
[1] Connecting to www.taobao.com:443...
[2] Starting QUIC handshake...
[3] Handshake result: SUCCESS ✅
=== Handshake Summary ===
Initial packets received: 1
Handshake packets received: 5
Initial CRYPTO: 90 bytes
Handshake CRYPTO: 5566 bytes
[4] Sending HTTP/3 GET request to /...
----------------------------------------
[5] HTTP/3 Response:
----------------------------------------
=== Response for / ===
Status: 200
Headers:
:status: 200
timing-allow-origin: Tengine
content-type: text/html; charset=utf-8
vary: accept-encoding
date: Fri, 01 Jan 2025 12:00:00 GMT
vary: Accept-Encoding
x-server-id: xxx...
x-air-hostname: xxx...
x-air-trace-id: xxx...
cache-control: max-age=0, s-maxage=139
x-node: xxx...
x-eagleeye-id: xxx...
x-wh-action: crossEngineRewrite
x-retmsg: ok
x-content-type: text/html; charset=utf-8
vary: Ali-Detector-Type, X-Host, x-accept-terminal, x-document-bundle, Accept-Encoding, Origin
streaming-parser: open
x-retcode: SUCCESS
etag: W/"xxx..."
x-readtime: 367
x-via: xxx...
x-air-source: proxy
x-xss-protection: 1; mode=block
ups-target-key: xxx...
x-protocol: HTTP/1.1
eagleeye-traceid: xxx...
strict-transport-security: max-age=31536000
s-brt: 368
s-rt: 370
via: xxx...
age: 77
ali-swift-global-savetime: xxx...
x-cache: HIT TCP_MEM_HIT dirn:-2:-2
x-swift-savetime: Fri, 01 Jan 2025 12:00:00 GMT
x-swift-cachetime: 139
x-air-pt: pt0
timing-allow-origin: *
eagleid: xxx...
Body (90674 bytes):
淘宝