如何使用Python Socket构造并发送HTTP/2请求头?
HTTP/2 请求头与 Socket 实现说明
一、HTTP/2 请求头的核心特点
- HTTP/2 是二进制协议,完全不同于 HTTP/1.1 的文本格式,请求头会先经过 HPACK 压缩算法处理,再封装到 HEADERS 帧中传输。
- 没有明文的请求行(如
GET / HTTP/1.1),而是通过伪头字段(以:开头)传递请求核心信息,常用伪头包括::method:请求方法(如 GET、POST):path:请求路径:scheme:请求协议(如 https):authority:对应 HTTP/1.1 的 Host 字段
二、用 Socket 实现 HTTP/2 请求的关键步骤
HTTP/2 几乎都基于 TLS 加密传输(裸 TCP 的 h2c 模式极少被支持),所以示例需先完成 TLS 握手并协商 HTTP/2 协议:
1. 建立 TLS 连接并确认 HTTP/2 协商
import socket import ssl host = "example.com" path = "/" # 创建基础 Socket 并包装 TLS 层,指定 ALPN 协议为 h2 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) context = ssl.create_default_context() context.set_alpn_protocols(['h2']) s = context.wrap_socket(s, server_hostname=host) s.connect((host, 443)) # 确认协商成功的是 HTTP/2 assert s.selected_alpn_protocol() == 'h2'
2. 发送连接初始化的 SETTINGS 帧
HTTP/2 连接建立后,客户端需先发送 SETTINGS 帧做初始化配置,再接收服务器的 SETTINGS 帧并回复 ACK:
# 构造空负载的 SETTINGS 帧(帧头:长度3字节+类型1字节+标志1字节+流ID4字节) # SETTINGS 帧类型为 0x04,流ID为0(属于连接级帧) settings_frame = b'\x00\x00\x00\x04\x00\x00\x00\x00\x00' s.sendall(settings_frame) # 接收服务器返回的 SETTINGS 帧,再发送 ACK 帧(标志位设为 0x01) server_settings = s.recv(65535) settings_ack_frame = b'\x00\x00\x00\x04\x01\x00\x00\x00\x00' s.sendall(settings_ack_frame)
3. 构造并发送 HEADERS 帧(含压缩后的请求头)
手动实现 HPACK 压缩复杂度高,推荐使用 hpack 库处理:
from hpack import Encoder encoder = Encoder() # 组装伪头字段和普通请求头 headers = [ (b':method', b'GET'), (b':path', path.encode()), (b':scheme', b'https'), (b':authority', host.encode()), (b'Accept-Encoding', b'gzip, deflate') ] # 压缩请求头 compressed_headers = encoder.encode(headers) # 构造 HEADERS 帧:帧头 + 压缩后的头数据 # HEADERS 帧类型为 0x01,流ID设为1(第一个请求流) frame_length = len(compressed_headers).to_bytes(3, byteorder='big') headers_frame = frame_length + b'\x01\x00\x00\x00\x00\x01' + compressed_headers s.sendall(headers_frame)
4. 接收并解析响应
HTTP/2 响应以 HEADERS 帧(响应头)+ DATA 帧(响应体)的形式返回,需解析二进制帧结构(示例仅做简单接收):
response = s.recv(65535) print("收到的响应帧数据:", response)
三、实用建议
- 手动实现 HTTP/2 的二进制帧解析和 HPACK 压缩极易出错,实际开发优先使用成熟库(如
hyper、支持 HTTP/2 的aiohttp)。 - HPACK 压缩依赖动态字典维护,手动处理难以覆盖所有边界场景。
内容的提问来源于stack exchange,提问作者Yin Lei
相关产品推荐
相关产品推荐

