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

谷歌不支持HEADERS与CONTINUATION帧交错,求兼容该特性的HTTP/2服务器

关于HTTP/2服务器支持HEADERS与CONTINUATION帧交错特性的疑问

根据RFC 9113第6.10节规定:“只要前一帧属于同一流且是未设置END_HEADERS标记的HEADERS、PUSH_PROMISE或CONTINUATION帧,就可以发送任意数量的CONTINUATION帧。”这意味着允许在某一流的HEADERS与CONTINUATION帧之间插入其他流的帧。

但通过代码测试发现,www.google.com并不支持该规范:启用帧交错时请求会被拒绝,不启用时则返回两个404页面。请问还有哪些HTTP/2服务器支持HEADERS与CONTINUATION帧的交错特性?

测试代码

import hpack
import sys
import pdb
import h2.connection

def get_header_frame(sid=1, path="/", es=True):
    initial_headers = [
        (':method', 'GET'),
        (':path', path),
        (':scheme', 'https'),
        (':authority', 'www.google.com')
    ]
    encoder = hpack.Encoder()
    initial_headers_encoded = encoder.encode(initial_headers)
    res = b'\x00' + len(initial_headers_encoded).to_bytes(2, 'big') + b'\x01'
    res += b'\x05' if es else b'\x00'
    res += sid.to_bytes(length=4, byteorder="big")+initial_headers_encoded
    return res

def get_cont_frame(sid=1, c=1, eh=True):
    custom_headers = [
        ('x-%s' % (c), 'A'*1)
    ]
    encoder = hpack.Encoder()
    initial_headers_encoded = encoder.encode(custom_headers)
    res = b'\x00' + len(initial_headers_encoded).to_bytes(2, 'big') + b'\x09'
    res += b'\x04' if eh else b'\x00'
    res += sid.to_bytes(length=4, byteorder="big")+initial_headers_encoded
    return res

def get_data_frame(sid=1, es=True):
    data = b''
    res = b'\x00' + len(data).to_bytes(2, 'big') + b'\x00'
    res += b'\x01' if res else b'\x00'
    res += sid.to_bytes(length=4, byteorder="big")+data
    return res


def create_http2_request(interleave=False):
    conn = h2.connection.H2Connection()
    conn.initiate_connection()
    sys.stdout.buffer.write(conn.data_to_send())
    settings_frame = conn.data_to_send()
    sys.stdout.buffer.write(settings_frame)

    f1_1 = get_header_frame(1, "/1", False)
    f1_2 = get_cont_frame(1)
    f1_3 = get_data_frame(1)
    f3_1 = get_header_frame(3, "/3", False)
    f3_2 = get_cont_frame(3)
    f3_3 = get_data_frame(3)

    if interleave:
        frames = [f1_1, f3_1, f3_2, f1_2, f1_3, f3_3]
    else:
        frames = [f1_1, f1_2, f3_1, f3_2, f3_3, f1_3] 
    for x in frames:
        sys.stdout.buffer.write(x)
    sys.stdout.flush()
    

def main():
    '''
    Usage: 
      interleave: python3 good_h2_client.py 1 | openssl s_client -connect www.google.com:443 -alpn h2 -ign_eof
      non-interl: python3 good_h2_client.py 0 | openssl s_client -connect www.google.com:443 -alpn h2 -ign_eof
    '''
    if len(sys.argv) > 1 and int(sys.argv[1]) == 1:
        create_http2_request(True)
    else:
        create_http2_request(False)


if __name__ == '__main__':
    main()

内容的提问来源于stack exchange,提问作者lidaobing

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:35:00