3. Message Format (消息格式)
核心概念 (Core Concepts)
所有 HTTP/1.1 消息由起始行 (start-line) 后跟一系列八位字节组成,格式类似于 Internet 消息格式 [RFC5322]:零个或多个头部字段 (header fields)、指示头部部分结束的空行,以及可选的消息主体 (message body)。
ABNF 语法定义
HTTP-message = start-line
*( header-field CRLF )
CRLF
[ message-body ]
解析过程 (Parsing Process)
解析 HTTP 消息的标准过程:
- 将起始行读入结构
- 将每个头部字段按字段名读入哈希表,直到空行
- 使用解析的数据确定是否需要消息主体
- 如果指示了消息主体,则作为流读取,直到读取等于消息主体长度的八位字节数或连接关闭
安全要求 (Security Requirements)
- 接收方必须 (MUST) 将 HTTP 消息解析为 US-ASCII 的超集编码中的八位字节序列
- 禁止将 HTTP 消息解析为 Unicode 字符流,因为这会造成安全漏洞
- 发送方绝对不能 (MUST NOT) 在起始行和第一个头部字段之间发送空白字符
3.1. Start Line (起始行)
起始行有两种形式:
- 请求行 (request-line): 用于请求消息
- 状态行 (status-line): 用于响应消息
start-line = request-line / status-line
3.1.1. Request Line (请求行)
请求行由请求方法 (method)、请求目标 (request-target) 和协议版本组成,以 CRLF 结束。
request-line = method SP request-target SP HTTP-version CRLF
示例:
GET /hello.txt HTTP/1.1
组成部分:
- method: 请求方法 (如 GET, POST, PUT),区分大小写
- request-target: 标识应用请求的目标资源
- HTTP-version: 协议版本 (如 HTTP/1.1)
3.1.2. Status Line (状态行)
状态行由协议版本、状态码 (status-code) 和原因短语 (reason-phrase) 组成。
status-line = HTTP-version SP status-code SP reason-phrase CRLF
status-code = 3DIGIT
reason-phrase = *( HTAB / SP / VCHAR / obs-text )
示例:
HTTP/1.1 200 OK
HTTP/1.1 404 Not Found
3.2. Header Fields (头部字段)
头部字段允许在请求和响应消息中传递额外的信息。
基本格式
header-field = field-name ":" OWS field-value OWS
field-name = token
field-value = *( field-content / obs-fold )
field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
field-vchar = VCHAR / obs-text
OWS = *( SP / HTAB ) ; optional whitespace
3.2.1. Field Extensibility (字段可扩展性)
HTTP 头部字段是完全可扩展的:对于发送方和接收方共享的语义,字段名注册表没有预定义限制。新字段可以随时定义和使用。
3.2.2. Field Order (字段顺序)
具有相同字段名的多个头部字段的顺序可能具有意义。接收方可以 (MAY) 将具有相同字段名的多个头部字段合并为一个,方法是按照它们在消息中出现的顺序用逗号附加每个后续字段值。
注意: 某些字段(如 Set-Cookie)不遵循此规则,因为它们的值不是逗号分隔的列表。
3.2.3. Whitespace (空白字符)
字段值前后的可选空白 (OWS) 在解析时应该 (SHOULD) 被排除。
3.2.4. Field Parsing (字段解析)
接收方在处理消息头之前,通常会将每个头部字段提取到名称/值对的数据结构中。
关键规则:
- 无法解析为有效头部字段的行应该 (SHOULD) 被视为畸形消息
- 代理必须 (MUST) 转发无法识别的头部字段
- 头部字段解析不能失败,即使字段值无效
3.2.5. Field Limits (字段限制)
HTTP 对请求行长度或头部字段长度没有预定义限制。
实现建议:
- 服务器应该准备处理至少 8000 个八位字节的请求行
- 至少支持 8000 个八位字节的头部字段大小
- 超过限制时应返回
414 (URI Too Long)或431 (Request Header Fields Too Large)
3.2.6. Field Value Components (字段值组件)
大多数 HTTP 头部字段值使用常见的语法组件(token, quoted-string, comment),由空白或特定分隔字符分隔。
token = 1*tchar
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
/ "+" / "-" / "." / "0-9" / "A-Z" / "^-z"
quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
3.3. Message Body (消息主体)
请求或响应的消息主体 (如果有) 用于携带该请求或响应的有效载荷主体 (payload body)。
message-body = *OCTET
消息主体的存在性
消息主体的存在由 Transfer-Encoding 和 Content-Length 头部字段决定:
- 任何包含
Transfer-Encoding的响应都包含消息主体 - 包含
Content-Length的消息具有该长度的消息主体 - 其他情况根据消息类型和状态码确定
3.3.1. Transfer-Encoding (传输编码)
Transfer-Encoding 头部字段列出了应用于有效载荷主体的传输编码名称序列。
Transfer-Encoding = 1#transfer-coding
transfer-coding = "chunked" / "compress" / "deflate" / "gzip"
/ transfer-extension
transfer-extension = token *( OWS ";" OWS transfer-parameter )
最重要的传输编码: chunked (分块)
分块传输编码允许消息主体作为一系列块发送,每个块都有自己的大小指示符。
关键规则:
- 发送方绝对不能 (MUST NOT) 多次应用 chunked
- chunked 必须 (MUST) 是最后应用的编码
- 服务器接收到无效的
Transfer-Encoding必须 (MUST) 响应400 (Bad Request)
3.3.2. Content-Length (内容长度)
Content-Length 头部字段提供消息主体的预期大小(以八位字节为单位)。
Content-Length = 1*DIGIT
示例:
Content-Length: 51
Content-Length: 0
关键规则:
- 如果消息同时包含
Transfer-Encoding和Content-Length,则必须 (MUST) 忽略Content-Length - 发送方绝对不能 (MUST NOT) 在包含
Transfer-Encoding的消息中发送Content-Length
3.3.3. Message Body Length (消息主体长度)
消息主体长度按以下优先顺序确定:
- 对于响应 CONNECT 的 2xx,或对 HEAD 请求的任何响应:消息主体长度为零
- 任何 1xx (Informational), 204 (No Content), 304 (Not Modified) 响应:消息主体长度为零
- 如果存在
Transfer-Encoding且最后的编码是 chunked:使用分块机制确定长度 - 如果存在多个
Content-Length,且值不同:消息畸形 - 如果存在有效的
Content-Length:该值就是消息主体长度 - 对于请求:如果以上都不适用,消息主体长度为零
- 对于响应:由服务器在关闭连接时确定
3.4. Handling Incomplete Messages (处理不完整消息)
如果在接收完整消息之前连接关闭,接收方应该 (SHOULD) 视为不完整消息,除非通过检查内容编码可以确定消息完整。
3.5. Message Parsing Robustness (消息解析健壮性)
虽然请求行和状态行语法仅允许 SP 作为空白分隔符,但接收方可以 (MAY) 选择接受多个空白字符以实现互操作性。
安全考虑: 过于宽松的解析可能导致请求走私攻击,必须谨慎实施。
✅ Section 3 完成确认
📍 完成内容:
- ✅ 3.1 Start Line (起始行)
- ✅ 3.1.1 Request Line (请求行)
- ✅ 3.1.2 Status Line (状态行)
- ✅ 3.2 Header Fields (头部字段)
- ✅ 3.2.1-3.2.6 所有子章节
- ✅ 3.3 Message Body (消息主体)
- ✅ 3.3.1 Transfer-Encoding
- ✅ 3.3.2 Content-Length
- ✅ 3.3.3 Message Body Length
- ✅ 3.4 Handling Incomplete Messages
- ✅ 3.5 Message Parsing Robustness
📊 质量标准:
- ✅ 完整的 ABNF 语法定义
- ✅ 关键技术概念中文翻译
- ✅ 安全要求和限制说明
- ✅ 实际示例演示
⏭️ 下一步: Section 4 - Transfer Codings (传输编码)
请回复 "继续" 以处理 Section 4。