Skip to content
github-actions[bot] edited this page Jul 16, 2026 · 8 revisions

HTTP/1.1 协议指南

HTTP/1.1 是 wknet::http 在 TCP 上的基线协议。请求 framing 由库生成;响应解析 fail-closed;pipeline、Expect: 100-continue 与 TRACE 均为显式 opt-in。

公开入口见 HTTP 同步 / 请求与响应 / 会话配置

结论

主题 行为
请求体 Content-Length、库生成 chunked、流式 body source
请求 trailer chunked 路径;禁止字段与 CRLF 注入被拒
Expect: 100-continue SendFlagExpectContinue 显式开启
pipeline session 默认关;FIFO;默认仅 GET/HEAD/OPTIONS
代理 HTTPS → CONNECT;明文 HTTP → absolute-form(不建隧道)
redirect 见下;默认拒绝 HTTPS→HTTP 降级
close-delimited 无 CL/TE 且连接关闭时完成 body
手写 framing 头 Transfer-Encoding/TE 等由库控制,调用方写入被拒

请求体与 framing

  • 已知长度:发 Content-Length;可用内存体、文件体或 BodyCreateStream / RequestSetBodySource 按块提供。
  • 未知长度RequestBodyMode::Chunked,库生成 Transfer-Encoding: chunked 与 chunk framing。
  • 流式上传:回调按块读;不必整包驻留内存。
  • trailerBodyAddTrailer / RequestAddTrailer 只在 chunked 终止块之后发送;Content-Length/Transfer-Encoding/Host/Authorization/Proxy-Authorization/Cookie/Set-Cookie 等禁止字段被拒。
  • TRACE:需 SendFlagAllowTrace;带 body、trailer 或敏感头会被拒绝。

调用方不得手写 Host/Content-Length/Connection/Transfer-Encoding/TE;未走库选项时手写 Expect: 100-continue 亦拒。无 Accept-Encoding 时库注入默认协商列表(见 编码与密码学)。

Expect 100-continue

SendFlagExpectContinue 显式开启,且仅在有 body 时注入:

  1. 收到 100 → 再发 body
  2. 收到 final / 417 → 不发 body
  3. 等待超时(ExpectContinueTimeoutMs,默认 1000 ms)→ 按 RFC 时序发送 body

带 body 或 Expect 的请求不会参与 HTTP/1.1 pipeline。

Pipeline(默认关)

默认
SessionConfig.EnableHttp11Pipeline false
Http11PipelineMaxDepth 4(硬上限 64)
Http11PipelineMethodMask GET / HEAD / OPTIONS

开启后,同源 keep-alive 连接按发送顺序分配 sequence,并以 FIFO 绑定响应。解析或传输失败会关闭该 pipeline 连接,并传播给后续排队请求。

下列请求不参与 pipeline:带请求体、带 Expect: 100-continue、会触发 redirect 重放、NoPool / ForceNew,以及不在 method mask 中的方法。这样可避免响应重排与非幂等重放。

代理

目标 形态
https:// over proxy CONNECT 隧道,TLS 在隧道内
http:// over proxy absolute-form request-target,建 CONNECT
Proxy-Authorization 仅来自显式 SessionConfig.Proxy 配置

响应 body 框定

  • 无 body:HEAD,或状态 1xx / 204 / 205 / 304。
  • Content-Length:长度不足 → 继续读;多个 CL 或 TE+CL 冲突 → STATUS_INVALID_NETWORK_RESPONSE
  • chunked:块数 ≤8192;严格 chunk 扩展语法;终止块后 trailer(每行 ≤8 KiB、数 ≤256);禁止 trailer 字段同请求侧规则。
  • close-delimited:无 CL/TE 时,以连接关闭完成消息;此类响应不回连接池

头块须完整(\r\n\r\n),否则 STATUS_MORE_PROCESSING_REQUIRED;头块 >64 KiB、行 >8 KiB、≥200 个头、obs-fold → 失败。状态行仅接受 HTTP/1.0 与 1.1。中间 1xx(除 101)静默吞掉后重解析。

206 / Content-Range 为只读语义;绑定 RFC 9111 cache 后参与验证与 partial 合并,不改变 body 框定。

Redirect

状态 方法/body
301 / 302 仅 POST→GET
303 除 HEAD 外→GET
307 / 308 保留方法与 body
  • 跨源清理 Authorization / Cookie / Proxy-Authorization
  • 默认拒绝 HTTPS→HTTP 降级
  • 默认最多 10 跳(MaxRedirects);达到上限不报错,直接返回该 3xx
  • SendFlagDisableAutoRedirect 关闭自动跟随。

与上层的关系

  • 安全方法在连接关闭族 / STATUS_RETRY / 超时且 ReuseOrCreate 时,可以 ForceNew 恰好重试一次GET/HEAD/OPTIONS)。
  • Content-Encoding 解码、解压炸弹与 TE 规则见 编码与密码学
  • 支持范围见 能力边界

English

HTTP/1.1 Protocol Guide

HTTP/1.1 is the TCP baseline for wknet::http. Request framing is library-owned; response parsing is fail-closed; pipelining, Expect: 100-continue, and TRACE are explicit opt-ins.

Public entry points: HTTP sync / Request & response / Session config.

Summary

Topic Behavior
Request body Content-Length, library-generated chunked, streaming body source
Request trailers Chunked path only; forbidden fields and CRLF injection rejected
Expect: 100-continue Explicit SendFlagExpectContinue
Pipelining Session default off; FIFO; default methods GET/HEAD/OPTIONS
Proxy HTTPS → CONNECT; plaintext HTTP → absolute-form (no tunnel)
Redirect See below; HTTPS→HTTP downgrade refused by default
Close-delimited Body completes on connection close when no CL/TE
Caller framing headers Transfer-Encoding/TE etc. are library-controlled

Request body and framing

  • Known length: emit Content-Length; body may be in-memory, file-backed, or streamed via BodyCreateStream / RequestSetBodySource.
  • Unknown length: RequestBodyMode::Chunked; the library generates Transfer-Encoding: chunked and chunk framing.
  • Streaming upload: callback supplies chunks; the full body need not reside in memory.
  • Trailers: BodyAddTrailer / RequestAddTrailer are sent only after the final chunk; forbidden fields include Content-Length, Transfer-Encoding, Host, Authorization, Proxy-Authorization, Cookie, Set-Cookie.
  • TRACE: requires SendFlagAllowTrace; body, trailers, or sensitive headers are rejected.

Callers must not hand-write Host/Content-Length/Connection/Transfer-Encoding/TE. A hand-written Expect: 100-continue without the library flag is also rejected. When no Accept-Encoding is supplied, the library injects the default negotiation list (see Encoding & crypto).

Expect 100-continue

SendFlagExpectContinue is opt-in and injects only when a body is present:

  1. Receive 100 → then send the body
  2. Receive final / 417 → do not send the body
  3. Wait timeout (ExpectContinueTimeoutMs, default 1000 ms) → send the body per RFC timing

Requests with a body or Expect do not participate in HTTP/1.1 pipelining.

Pipelining (off by default)

Item Default
SessionConfig.EnableHttp11Pipeline false
Http11PipelineMaxDepth 4 (hard cap 64)
Http11PipelineMethodMask GET / HEAD / OPTIONS

When enabled, same-origin keep-alive connections assign sequences in send order and bind responses FIFO. Parse or transport failure closes that pipeline connection and propagates to queued requests.

These requests do not participate in the pipeline: request body, Expect: 100-continue, redirect replay, NoPool / ForceNew, and methods outside the mask. That avoids response reordering and non-idempotent replay.

Proxy

Target Form
https:// over proxy CONNECT tunnel; TLS inside the tunnel
http:// over proxy absolute-form request-target; no CONNECT
Proxy-Authorization Only from explicit SessionConfig.Proxy

Response body framing

  • No body: HEAD, or status 1xx / 204 / 205 / 304.
  • Content-Length: incomplete length continues reading; duplicate CL or TE+CL conflict → STATUS_INVALID_NETWORK_RESPONSE.
  • chunked: ≤8192 chunks; strict chunk-extension grammar; trailers after the terminal chunk (line ≤8 KiB, count ≤256); forbidden trailer fields match the request rules.
  • Close-delimited: with neither CL nor TE, the message completes on connection close; such responses are not returned to the pool.

A full header block (\r\n\r\n) is required, else STATUS_MORE_PROCESSING_REQUIRED. Header block >64 KiB, line >8 KiB, ≥200 headers, or obs-fold fails. Status lines accept only HTTP/1.0 and 1.1. Interim 1xx (except 101) is silently consumed and the final response is re-parsed.

206 / Content-Range are read-only semantics; with an RFC 9111 cache they participate in validation and partial combining without changing body framing.

Redirect

Status Method / body
301 / 302 POST→GET only
303 →GET except HEAD
307 / 308 Preserve method and body
  • Cross-origin strips Authorization / Cookie / Proxy-Authorization.
  • HTTPS→HTTP downgrade is refused by default.
  • Default max 10 hops (MaxRedirects); hitting the cap returns that 3xx without error.
  • SendFlagDisableAutoRedirect disables automatic following.

Relation to upper layers

  • Safe methods may retry exactly once with ForceNew on connection-close families / STATUS_RETRY / timeout under ReuseOrCreate (GET/HEAD/OPTIONS).
  • Content-Encoding decode, bomb guards, and TE rules: Encoding & crypto.
  • See the capability matrix for support scope.

Clone this wiki locally