-
Notifications
You must be signed in to change notification settings - Fork 0
HTTP1
struct HttpText { const char* Data; SIZE_T Length; };
struct HttpHeader { HttpText Name; HttpText Value; };同处定义堆基元 HeapArray<T> / HeapObject<T> 与非分页池分配器(见 内存模型)。
序列化 METHOD SP target SP HTTP/1.1\r\n + 头 + \r\n + body。要点:
- 用测长
BufferWriter,目标缓冲不足返回STATUS_BUFFER_TOO_SMALL并写出所需长度。 -
Host 头总是首先发出(值来自
options.Host,不自动推导);随后按固定序 User-Agent、Content-Type、body 框定头、Connection、调用方额外头。 - 方法枚举包含 CONNECT 与 TRACE;TRACE 需
SendFlagAllowTrace显式开启,且 body、trailer 与敏感头会被拒绝。 - body:
ContentLength模式发Content-Length(IncludeContentLength可让 0 长 body 也发Content-Length: 0);Chunked模式发Transfer-Encoding: chunked并按hex\r\n data \r\n ... 0\r\n串行化,随后写出请求 trailer(若有)再以\r\n收尾。 -
请求 trailer:仅在
Chunked请求体路径可用;公共 API 为BodyAddTrailer/RequestAddTrailer,禁止字段和 CRLF 注入会被拒绝。 -
禁止的额外头:
Host/Content-Length/Connection→STATUS_INVALID_PARAMETER;Transfer-Encoding/TE→STATUS_NOT_SUPPORTED;Trailer头仅在 chunked 框定下允许(否则STATUS_NOT_SUPPORTED);调用方手写Expect: 100-continue且未通过库的 expect-continue 选项开启时 →STATUS_NOT_SUPPORTED。 - 引擎层在无
Accept-Encoding时注入默认gzip, deflate, br, zstd, identity(deflate 运行时不可用则br, identity)。typed preferences 可生成带 qvalue 的Accept-Encoding,并驱动响应Content-Encodingfail-closed 校验。
-
BodyCreateStream/RequestSetBodySource使用调用方读取回调按块提供请求体;已知长度发送Content-Length,未知长度配合RequestBodyMode::Chunked由库生成 chunked framing。 -
BodyAddTrailer/RequestAddTrailer只在 chunked 请求体结束后发送 trailer。 -
SendFlagExpectContinue显式开启Expect: 100-continue,只有请求有 body 时才注入;收到100后发送 body,收到 final/417 不发送 body,等待超时后按 RFC 时序发送 body。 -
SessionConfig.Proxy对 HTTPS 使用 CONNECT;对http://使用 absolute-form request target,不建立 CONNECT 隧道。
- 默认关闭:
SessionConfig.EnableHttp11Pipeline=false,普通 HTTP/1.1 连接仍按单请求独占租约使用。 - 开启方式:
SessionConfig.EnableHttp11Pipeline=true;Http11PipelineMaxDepth默认 4、硬上限 64,Http11PipelineMethodMask默认仅允许GET/HEAD/OPTIONS。 - 调度语义:连接池为同源 HTTP/1.1 连接建立 pipeline lease,按发送顺序分配 sequence,并按 FIFO 读取/绑定响应;解析或传输失败会关闭该 pipeline 连接并传播给后续排队请求。
- 安全边界:仅 HTTP/1.1 keep-alive 路径可进入 pipeline;带请求体、
Expect: 100-continue、禁用/触发 redirect 重放、NoPool/ForceNew等不进入 pipeline,避免响应重排和非幂等重放语义。
- 需完整头块(
\r\n\r\n),否则STATUS_MORE_PROCESSING_REQUIRED;头块 >64 KiB →STATUS_INVALID_NETWORK_RESPONSE。 - 状态行:必须
HTTP/、<major>.<minor>,仅接受 major==1 且 minor<=1;状态码恰 3 位、100..599。 - 头:每行 ≤8 KiB;拒绝 obs-fold(行首 SP/TAB);名须为 token;值拒绝 <0x20(除 TAB)与 0x7f(允许高位字节);头数 ≥200 →
STATUS_BUFFER_TOO_SMALL。 - body 框定:
-
无 body:
ResponseBodyForbidden(HEAD)或状态属 1xx/204/205/304。 - 多个
Content-Length或TE+CL冲突 →STATUS_INVALID_NETWORK_RESPONSE。 - chunked/TE 链 →
HttpTransferCoding::DecodeResponseBody。 - Content-Length 路径:不足 →
STATUS_MORE_PROCESSING_REQUIRED。 - close-delimited:仅当
MessageCompleteOnConnectionClose且无 CL/TE。
-
无 body:
- 请求侧提供
Range与条件请求 typed helper;绑定 RFC 9111 cache 后,这些头参与自动验证、304合并和206 Partial Content分片合并;HttpResponse::IsPartialContent与GetContentRange仍只读暴露响应语义,不改变 body 框定。
块数 ≤8192、chunk-size 行 ≤32;严格 chunk 扩展语法(;name[=value|quoted]);终止块后解析 trailer:每行 ≤8 KiB、trailer 数 ≤256;禁止 trailer 字段:Content-Length/Transfer-Encoding/Host/Authorization/Proxy-Authorization/Cookie/Set-Cookie → STATUS_INVALID_NETWORK_RESPONSE。
| coding | 实现要点 |
|---|---|
gzip |
RFC1952 头解析,校验头 CRC16、尾 CRC32、ISIZE |
deflate |
自动识别 zlib 包装并校验 Adler-32;裸 DEFLATE 用内核 RtlDecompressBufferEx,附运行时探测 DeflateRuntimeAvailable
|
br |
内置 Brotli 解码 |
compress |
完整 LZW(.Z,9–16 bit,block 模式) |
zstd |
内置 Zstandard 解码 |
dcz |
调用方提供 zstd 字典,缺字典 fail-closed |
aes128gcm |
RFC 8188 keying material 解密,缺 key 或认证失败 fail-closed |
exi |
W3C EXI 1.0 Second Edition 无外部 Schema 流;四种 alignment、Options、保真项、内建 XML Schema 类型、xsi:type/xsi:nil;输出 Infoset 等价 XML;外部 Schema/strict grammar → STATUS_NOT_SUPPORTED
|
pack200-gzip |
Java 5–8 格式 150.7/160.1/170.1/171.0;裸/gzip、多 segment、class/file/bytecode、自定义 attribute layout(class/field/method/code)、overflow index、常量池与 BCI relocation;输出语义等价 JAR |
identity |
跳过 |
- 链最多 2 级(>2 →
STATUS_NOT_SUPPORTED),按反序解码。 -
解压炸弹防护:decoded aggregate 跟随响应/调用方容量,单级膨胀比 ≤64(
MaxDecodeExpansionRatio),超限 →STATUS_INVALID_NETWORK_RESPONSE。 - 未知 coding →
STATUS_NOT_SUPPORTED。 - EXI 与 Pack200 专项测试使用离线真实语料,并校验
SHA256SUMS与 provenance。
- 识别
chunked/gzip/deflate/compress,最多 4 级;identity→STATUS_INVALID_NETWORK_RESPONSE;br→STATUS_NOT_SUPPORTED;带参数 token → 非法;重复chunked→ 非法。 - 反序解码,仅最外层 chunked 收 trailer;非最外 chunked 未吃完输入 → 非法。
Namespace wknet::http, grounded in src/wknetlib/http/.
Request building serializes the request line, headers, and body with measured output sizing. Host is emitted first. CONNECT and opt-in TRACE are supported. Bodies may use Content-Length, library-generated chunked framing, or streaming callbacks through BodyCreateStream / RequestSetBodySource; request trailers are available only on the chunked path. Caller-controlled framing headers remain rejected.
HTTP/1.1 pipelining is session opt-in through SessionConfig.EnableHttp11Pipeline=true. It is disabled by default, uses FIFO response binding, defaults to depth 4, and accepts only GET/HEAD/OPTIONS unless the method mask is changed.
Response parsing (HttpParser::ParseResponse): full header block required (else STATUS_MORE_PROCESSING_REQUIRED); >64 KiB header block rejected; status line accepts only HTTP major==1, minor<=1, 3-digit 100..599; per-line ≤8 KiB, obs-fold rejected, token names, value rejects <0x20 (except TAB) and 0x7f; ≥200 headers → STATUS_BUFFER_TOO_SMALL. No-body for HEAD/1xx/204/205/304; duplicate Content-Length or TE+CL conflict → STATUS_INVALID_NETWORK_RESPONSE; chunked ≤8192 chunks, strict extension grammar, forbidden trailers rejected; IsPartialContent / GetContentRange expose read-only 206 / Content-Range semantics.
Content-Encoding supports gzip (CRC16/CRC32/ISIZE verified), deflate (zlib autodetect + Adler-32, kernel RtlDecompressBufferEx with runtime probe), br (bundled Brotli), compress (full LZW), zstd, dcz with a caller-provided dictionary, aes128gcm with RFC 8188 keying material, exi, pack200-gzip, and identity. Chains contain at most 2 codings, are decoded in reverse order, and enforce a 64× per-step decompression-bomb guard.
-
EXI: W3C EXI 1.0 Second Edition streams without an external Schema; all four alignments, Options, fidelity features, built-in XML Schema datatypes,
xsi:type, andxsi:nil; emits Infoset-equivalent XML. External Schema/strict grammar streams returnSTATUS_NOT_SUPPORTED. -
Pack200: Java 5–8 formats
150.7/160.1/170.1/171.0; raw/gzip, multiple segments, class/file/bytecode reconstruction, custom attribute layouts in class/field/method/code contexts, overflow indexes, constant-pool and BCI relocation; emits a semantically equivalent JAR. - Dedicated EXI and Pack200 tests load offline real-world corpora and verify
SHA256SUMSplus provenance metadata.
Transfer-Encoding supports chunked/gzip/deflate/compress up to 4 codings (identity rejected, br → STATUS_NOT_SUPPORTED), reverse-decoded with trailers only on the outermost chunked layer.
-
开始使用 / Get Started
-
概念与行为 / Concepts
-
协议指南 / Protocols
-
API 参考 / API Reference
-
贡献与项目 / Contribute