You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 16:45:33