2. Notational Conventions and Generic Grammar (符号约定和通用语法)
2.1 Augmented BNF (增强BNF)
本文档中指定的所有机制都以散文和增强的巴科斯-诺尔范式 (Backus-Naur Form, BNF) 进行描述,类似于 RFC 822 [9] 使用的形式。实现者需要熟悉这种符号才能理解本规范。增强的 BNF 包括以下构造:
name = definition
规则的名称就是名称本身(没有任何封闭的 < 和 >),并通过等号 = 字符与其定义分隔。空格仅在延续行的缩进用于指示跨越多行的规则定义时才有意义。某些基本规则使用大写字母,例如 SP、LWS、HT、CRLF、DIGIT、ALPHA 等。每当角括号的存在有助于辨别规则名称的使用时,就会在定义中使用角括号。
"literal" 引号包围字面文本。除非另有说明,否则文本不区分大小写。
rule1 | rule2 由竖线 ("|") 分隔的元素是替代项,例如,"yes | no" 将接受 yes 或 no。
(rule1 rule2) 括号中的元素被视为单个元素。因此,"(elem (foo | bar) elem)" 允许标记序列 "elem foo elem" 和 "elem bar elem"。
*rule
元素前面的字符 "*" 表示重复。完整形式是 "<n>*<m>element",表示至少 <n> 次且至多 <m> 次出现的元素。默认值为 0 和无穷大,因此 "*(element)" 允许任意数量,包括零;"1*element" 至少需要一个;"1*2element" 允许一个或两个。
[rule] 方括号包含可选元素;"[foo bar]" 等同于 "*1(foo bar)"。
N rule
特定重复:"<n>(element)" 等同于 "<n>*<n>(element)";即,恰好 <n> 次出现 (element)。因此 2DIGIT 是一个 2 位数字,3ALPHA 是一个由三个字母字符组成的字符串。
#rule
定义了一个类似于 "*" 的构造 "#",用于定义元素列表。完整形式是 "<n>#<m>element",表示至少 <n> 个且至多 <m> 个元素,每个元素由一个或多个逗号 (",") 和可选的线性空白 (Linear White Space, LWS) 分隔。这使得列表的通常形式非常简单;诸如以下的规则:
( *LWS element *( *LWS "," *LWS element ))
可以显示为:
1#element
无论在何处使用此构造,都允许空元素,但不计入存在的元素数量。也就是说,允许 "(element), , (element)",但仅计为两个元素。因此,在至少需要一个元素的情况下,必须 (MUST) 存在至少一个非空元素。默认值为 0 和无穷大,因此 "#element" 允许任意数量,包括零;"1#element" 至少需要一个;"1#2element" 允许一个或两个。
; comment 分号,在一行的任何位置,开始一个注释,该注释一直延续到该行的末尾。这是包含在规范中的简单方法,不会正式成为增强 BNF 的一部分。
implied *LWS 除非另有说明,否则语法中的线性空白 (LWS) 可以包含在任意两个相邻标记(token、分隔符)之间,并且在某些规则中(例如 "*"、"|" 或 "#")的分隔符之间。这种隐含的 *LWS 规则不应在 HTTP 构造中产生额外的空白,因为许多实现使用空白作为请求行和通用头字段的分隔符,以便能够快速解析消息。
2.2 Basic Rules (基本规则)
以下规则用于整个规范以描述基本解析构造。US-ASCII 编码字符集由 ANSI X3.4-1986 [21] 定义。
OCTET = <any 8-bit sequence of data>
CHAR = <any US-ASCII character (octets 0 - 127)>
UPALPHA = <any US-ASCII uppercase letter "A".."Z">
LOALPHA = <any US-ASCII lowercase letter "a".."z">
ALPHA = UPALPHA | LOALPHA
DIGIT = <any US-ASCII digit "0".."9">
CTL = <any US-ASCII control character
(octets 0 - 31) and DEL (127)>
CR = <US-ASCII CR, carriage return (13)>
LF = <US-ASCII LF, linefeed (10)>
SP = <US-ASCII SP, space (32)>
HT = <US-ASCII HT, horizontal-tab (9)>
<"> = <US-ASCII double-quote mark (34)>
HTTP/1.1 将八位字节序列定义为协议元素的基本解析单元。协议参数的语法规则以 ABNF 的形式给出,如第 2.1 节所述,使用以下核心规则。
CRLF = CR LF
LWS = [CRLF] 1*( SP | HT )
TEXT = <any OCTET except CTLs,
but including LWS>
LWS 规则定义了线性空白 (Linear White Space),它可能出现在字段内容和分隔符之间;它用于在不破坏字段语义的情况下跨越多行。所有 HTTP/1.1 头字段值都可以通过在任何 LWS 之前放置至少一个 SP 或 HT 来折叠到多行上。
许多 HTTP/1.1 头字段值由单词(tokens)、分隔符和引用字符串组成。这些元素由 SP 或 HT 字符分隔。
token = 1*<any CHAR except CTLs or separators>
separators = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "\" | <">
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
注释可以包含在某些 HTTP 头字段中。注释中允许的文本由 comment 规则定义。
comment = "(" *( ctext | quoted-pair | comment ) ")"
ctext = <any TEXT excluding "(" and ")">
带引号的字符串 (quoted-string) 被视为单个单词。带引号的字符串中允许的文本由 qdtext 规则定义。
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
qdtext = <any TEXT except <">>
单个字符引用机制允许在带引号的字符串和注释构造中包含任何 CHAR。
quoted-pair = "\" CHAR