2.1 增强型 BNF

本文档中指定的所有机制都以散文和类似于 RFC822 [9] 所用的增强型 Backus-Naur 形式 (BNF) 进行描述。实施者需要熟悉这个符号,以便理解本规范。扩充的 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
一个元素前面的字符 ““ 表示重复。完整的形式是 “element”,表示元素至少 ,最多 的出现次数。默认值是 0 和无穷大,因此 “(element)” 允许任何个元素,包括零;”1element” 要求至少有一个元素;”1*2element” 允许有一个或两个元素。

[rule]
方括号内是可选元素;”[foo bar]” 等同于 “*1(foo bar)”。

N rule
具体的重复。”(element)” 等同于 “*(element)”;也就是说,正好是 个(元素) 的出现次数。因此,2DIGIT 是一个 2 位数,3ALPHA 是一串三个字母的字符。

#rule
定义了一个结构 “#”,类似于 “*”,用于定义元素的列表。完整的形式是 “#element”,表示至少 和最多 个元素,每个元素由一个或多个逗号(”,”)和可选的线性空白(LWS)分开。这使得列表的通常形式变得非常容易;一个规则,如:

  1. ( *LWS element *( *LWS "," *LWS element ))

可以显示为

  1. 1#element

无论在哪里使用这个结构,都允许使用空元素,但不对存在的元素进行计数。也就是说,”(element), , (element)” 是允许的,但只算作两个元素。因此,在需要至少一个元素的情况下,必须有至少一个非空元素存在。默认值是 0 和无穷大,所以 “#element” 允许任何数字,包括零;”1#element” 要求至少一个;”1#2element” 允许一个或两个。

; comment
一个分号,在规则文本的右边有一段距离,开始一个注释,一直持续到行尾。这是一种简单的方法,可以将有用的注释与规范并行。

隐含的 *LWS
本规范所描述的语法是基于字的。除非另有说明,线性留白(LWS)可以包含在任何两个相邻的词(token 或 quoted-string)之间,以及相邻的词和分隔符之间,而不改变字段的解释。任何两个 token 之间必须至少有一个分隔符(LWS 和/或 分隔符)(关于下面 “标记 “的定义),否则它们将被解释为一个 token。

2.2 基本规则

以下规则在本规范中被用来描述基本的解析结构。US-ASCII 编码字符集是由 ANSI X3.4-1986 [21] 定义的。

  1. OCTET = <any 8-bit sequence of data>
  2. CHAR = <any US-ASCII character (octets 0 - 127)>
  3. UPALPHA = <any US-ASCII uppercase letter "A".."Z">
  4. LOALPHA = <any US-ASCII lowercase letter "a".."z">
  5. ALPHA = UPALPHA | LOALPHA
  6. DIGIT = <any US-ASCII digit "0".."9">
  7. CTL = <any US-ASCII control character
  8. (octets 0 - 31) and DEL (127)>
  9. CR = <US-ASCII CR, carriage return (13)>
  10. LF = <US-ASCII LF, linefeed (10)>
  11. SP = <US-ASCII SP, space (32)>
  12. HT = <US-ASCII HT, horizontal-tab (9)>
  13. <"> = <US-ASCII double-quote mark (34)>

HTTP/1.1 定义了 CR LF 序列作为所有协议元素的行结束标记,但实体主体除外(见附录 19.3中的宽容应用)。如第 3.7 节所述,实体主体中的行结束标记是由其相关的媒体类型定义的。

  1. CRLF = CR LF

如果延续行以空格或水平制表符开始,HTTP/1.1 头字段值可以被折叠到多行。所有线性留白,包括折叠,都具有与 SP 相同的语义。在解释字段值或向下游转发消息之前,收件人可以用单个 SP 替换任何线性留白。

  1. LWS = [CRLF] 1*( SP | HT )

TEXT 规则仅用于描述性字段内容和不打算由消息分析器解释的值。只有在根据 RFC 2047 [14] 的规则进行编码时,*TEXT 的字才可能包含 ISO- 8859-1 [22] 以外的字符集的字符。

  1. TEXT = <any OCTET except CTLs,
  2. but including LWS>

TEXT 的定义中只允许将 CRLF 作为头字段延续的一部分。 预计在解释 TEXT 值之前,折叠 LWS 将被替换为单个 SP。

在几个协议元素中使用了十六进制数字字符。

  1. HEX = "A" | "B" | "C" | "D" | "E" | "F"
  2. | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT

许多 HTTP/1.1 头字段的值是由 LWS 或特殊字符分隔的单词组成的。这些特殊字符必须在一个带引号的字符串中,以便在参数值中使用(如 3.6 节所定义)。

  1. token = 1*<any CHAR except CTLs or separators>
  2. separators = "(" | ")" | "<" | ">" | "@"
  3. | "," | ";" | ":" | "\" | <">
  4. | "/" | "[" | "]" | "?" | "="
  5. | "{" | "}" | SP | HT

通过用括号将注释文本括起来,可以将注释包含在某些 HTTP 标头字段中。仅在包含 “comment” 作为其字段值定义的一部分的字段中才允许使用注释。在所有其他字段中,括号被视为字段值的一部分。

  1. comment = "(" *( ctext | quoted-pair | comment ) ")"
  2. ctext = <any TEXT excluding "(" and ")">

如果使用双引号引用文本字符串,则将其解析为单个单词。

  1. quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
  2. qdtext = <any TEXT except <">>

反斜杠字符 (“\”) 可以仅在带引号的字符串和注释结构中用作单字符引用机制。

  1. quoted-pair = "\" CHAR