协议支持

RelayCore 是 L7 代理,关注应用层协议的解析、检查与改写。底层传输一律走 TCP(HTTP/HTTPS/WebSocket),UDP 目前仅透明代理场景支持。

HTTP/1.1

完整支持。请求/响应头、chunked 编码、Transfer-Encoding、双向 keep-alive、流式 body 都可以被解析。规则与脚本可以无差别作用于头与体。

HTTP/2

客户端一侧可以是 HTTP/1.1 或 HTTP/2(取决于客户端与 ALPN)。出站只把 HTTP/1.x 的版本原样带给上游;HTTP/2 入站的上游协议由目标 URL 和 ALPN 决定,不会把客户端的 HTTP/2 版本硬套到一条 HTTP/1 连接上。HPACK 在内部完全展开,规则看到的是已解码的伪头(:method、:path、:scheme、:authority)。

同样支持 h2c(明文 HTTP/2)。不发 TLS 的 gRPC 客户端可以通过连接前导被识别,直连与走 CONNECT 隧道都行(后者正是 HTTP_PROXY 客户端的行为)。只支持 h2c 的上游也能到达: 代理按 prior knowledge 直接发 HTTP/2,上游拒绝时回退到 HTTP/1.1。由于 h2c 没有协商机制,这个回退会先等一小段时间, 因此对纯 h2c 上游建立新连接会有少量额外延迟。

HTTPS / TLS

对所有 HTTP-over-TLS 流量做 MITM 拦截,依赖动态签发的证书(见 证书与 HTTPS 拦截)。上游默认校验证书;可在 replay 场景中临时关闭(仅 POST /api/v1/flows/:id/replay?accept_invalid_certs=true,调试用)。

WebSocket

握手和明文帧可以检查、改写。基于 RFC 6455。RelayCore 解析握手、注册 Layer::WebSocket 流量,并对每条消息提供消息级检查与改写。permessage-deflate 既不协商剥离,也不解压,压缩帧会按原样穿过,内容不可读。

  • 每条消息记录 direction(incoming / outgoing)、opcode(text / binary / ping / pong / close / continuation)、content(含 encoding、size、base64 body)。
  • 规则可以 MockWebSocketMessage、DropWebSocketMessage。
  • 脚本 hook onWebSocketMessage 可读改每条消息。
  • TUI 的 Messages 详情页实时显示消息日志。
  • 超预算的 body 走 SSE 事件 body-budget-exceeded(带 direction),没有单独的 WebSocket 预算事件名。

QUIC / HTTP/3

QUIC 是 UDP 之上的传输层协议,现代浏览器会优先尝试。RelayCore 通过 ProxyPolicy.quic_mode 控制其行为:

模式说明
Downgrade(默认)从 HTTP 响应里去掉 Alt-Svc。只有 quic_downgrade_clear_cache=true(默认 false)时才额外写 Clear-Site-Data: "cache"。
Passthrough保留 Alt-Svc。客户端随后可能直连源站的 QUIC,这段流量不进代理,也没有 Flow。
ExperimentalMitm实验性 HTTP/3 MITM。需要 quic_mitm_experimental feature flag,且尚未生产可用。

QUIC 本身没有 Flow。Downgrade 只是改写已经捕获的 HTTP 响应:去掉 Alt-Svc 时会给这条流打上 quic-downgraded 标签。

TCP / UDP(透明代理场景)

RelayCore 不解析 TCP 原始字节,只解析 HTTP/WebSocket 等应用层协议。透明代理模式下:

  • TCP 流量:被重定向到代理端口后,RelayCore 尝试按 HTTP/1.1 解析;如果客户端发的不是 HTTP(例如裸 TCP),会被代理拒绝并记录 error。
  • UDP 流量:通过 --udp-tproxy-port(仅 Linux,需要 IP_TRANSPARENT)支持 UDP 透明代理,但仅做转发,不解析。

不支持的协议

  • 原始 TCP 上的自定义协议(非 HTTP):RelayCore 不解析;透明代理场景下会让连接失败。
  • gRPC 的消息载荷:分帧会被解析——gRPC body 按长度前缀读成一条条消息(条数、长度、 压缩标志,载荷是文本时给出文本预览),HTTP trailers 也会被记录,因此流上能看到 grpc-status 与 grpc-message。但 protobuf 字段本身的解码仍需要服务的 schema,引擎没有,所以载荷内容依然是不透明的。
  • SSE(Server-Sent Events):HTTP/1.1 长连接,RelayCore 在 GET /api/v1/events 端点上自用,外部站点 SSE 流量以 HTTP 形式被记录但事件边界不会被单独标注。