2 符号习惯和一般语法
2.1 扩充的BNF(扩充的 巴科斯-诺尔范式)
本文档规定的所有机制都用两种方法描述:散文体(prose)和类似于RFC 822的扩充Backus-Naur Form(BNF)。要理解本规范,使用者需熟悉符号表示法。扩充BNF结构如下:

名字(name)=定义(definition)

名字(name)就是代表规则的名字(译注:如:CRLF,DIGIT等等都是规则名),规则名里不能包含“<”和“>”,通过等于号 把规则名和规则定义(definiation)分离开。空白(white space)是有意义的,因为可以用缩进(indentation,译注:缩进就是空白,后面会讲到LWS) 把规则定义显示成多行。某些基本规则(basic rule,译注:2.2节说明基本规则的语法)使用大写字母包含在规则定义里, 你如SP,LWS,HT,CRLF,DIGIT,ALPHA,等等。尖括号可以包含在规则定义里,只要它们的存在有利于识别规则名(译注:LWS,HT等 都是规则名)。

“字面文本”(“literal”)

字面文本(literal text)两边用引号。除非声明,字面文本大小写不敏感(译注:如,HEX = "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT 里的A,B,C,D等等都是字面文本(literal text))。

规则1 | 规则2

由竖线(“|”)分开的元素是可选的,例如,“yes | no”表示yes或no都是可接受的。

(规则1 规则2)

围在括号里的多个元素视作一个元素。所以,“(elem (foo | bar) elem)”的符合的字符串是“elem foo elem”和“elem bar elem”。

*规则

前面的字符“*”表示重复。完整的形式是“<n>*<m>元素”,表示元素至少出现<n>次,至多出 现<m>次。默认值是0和无穷大,所以"*(元素)"允许任何数值,包括零;"1*元素"至少需要一次;"1*2element"允许一次或 两次。

[规则]

方括号里是任选元素;“[foo bar]”相当于“*1(foo bar)”。

N 规则

特殊的重复:“<n>(元素)”与“<n>*<n>(元素)”等价;就是说,(元素)正好出现了<n>次。这样2DIGIT是一个两位数字,3ALPHA是一个由三个字符组成的字符串。

#规则

类似于“*”,结构“#”是用来定义一系列元素的。完整的形式是<n>#<m>元素,表示至少<n>个元素, 至多<m>个元素,元素之间被一个或多个逗号(“,”)以及可选的线性空白(LWS)隔开了。这就使得表示列表这样的形式变得非常容易;像

( *LWS element) *( *LWS ","*LWS element ))

就可以表示为

1#element 

无论在哪里使用这个结构,空元素都是允许的,但是不计入元素出现的次数。换句话说 ,

“(element ), , (element)  ”是允许的,但是仅仅视为两个元素。因此,在至少需要一个元素的地方,必须存在至少一个非空元素。默认值是0和无穷大,这样,“#element”允许任 意零个或多个元素;“1# element”需要至少一个;“1#2element”允许一个或两个元素。

;注释(comment)

用分号引导注释。

隐含的(implied) *LWS

本说明书所描述的语法是基于字的。除非特别注明,线性空白可出现在任何两个相邻字之间(标记(token)或引用字符串(quoted- string)),以及相邻字和间隔符之间,这并没有改变一个域的解释。任何两个标记(token)之间必须有至少一个分割符,否则将会被理解为单一标 记。

 

2.2基本规则 (basic rule)
下面的规则贯穿于本规范的全文,此规则描述了基本的解析结构。US-ASCII(美国信息交换标准码)编码字符集是由ANSI X3.4-1986[21]定义的。

       OCTET(字节)    = <任意八比特的数据序列>

       CHAR           = <任意ASCII字符(ascii码值从 0到127的字节)>

       UPALPHA        = <任意大写字母"A"..."Z">

       LOALPHA        = <任意小写字母"a"..."z">

       ALPHA          = UPALPHA | LOALPHA

       DIGIT          = <任意数字0,1,...9>

       CTL          = <任意控制字符(ascii码值从0 到 31的字节)及删除键DEL(127>

       CR             = <US-ASCII CR, 回车(13)>

       LF             = <US-ASCII LF, 换行符(10)>

       SP             = <US-ASCII SP, 空格(32)>

       HT             = <US-ASCII HT, 水平制表 (9)>

       <">            = <US-ASCII 双引号(34)>

HTTP/1.1将 CR LF 的序列定义为任何协议元素的行尾标志,但这除了实体主体(endtity-body)外(要求比较松的应用见附录19.3)。实体主体(entity-body)的行尾标志是由它的关联媒体类型定义的,如3.7节所述。

       CRLF           = CR LF

HTTP/1.1 的消息头域值可以折叠成多行,但紧接着的折叠行由空格(SP)或水平制表(HT)折叠标记开始。所有的线性空白(LWS)包括折叠行的折叠标记(空格SP 或水平制表键HT),具有同SP一样的语义。接收者在解析域值或将消息转送到下游(downstream)之前可能会将任何线性空白(LWS)替换成单个 SP(空格)。

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

下面的TEXT规则仅仅适用于域内容和域值的描述,不会被消息解释器解析。TEXT里的字可以包含不仅仅是ISO-8859-1[22]里的字符集,也可以包含RFC 2047里规定的字符集。

       TEXT           = <除CTLs以外的任意OCTET,但包括LWS>

一个CRLF只有作为HTTP消息头域延续的一部分时才在TEXT定义里使用。

十六进制数字字符用在多个协议元素(protocol element)里。

       HEX            = "A" | "B" | "C" | "D" | "E" | "F"

                      | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT

许多HTTP/1.1的消息头域值是由LWS或特殊字符分隔的字构成的。这些特殊字符必须先被包含在引用字符串(quoted string)里之后才能用于参数值(如3.6节定义)里。

       token (标记)        = 1*<除CTLs与分割符以外的任意 CHAR >

       separators(分割符)    = "(" | ")" | "<" | ">" | "@"

                               | "," | ";" | ":" | """ | <">

                                      | "/" | "[" | "]" | "?" | "="

                                      | "{" | "}" | SP | HT

通过用圆括号括起来,注释(comment)可以包含在一些HTTP头域里。注释只可以作为域定义的一部分。在其他域里,圆括号被视作域值的一部分。

       comment (注释)= "(" *( ctext | quoted-pair | comment ) ")"

       ctext          = <除"(" 和 ")"以外的任意TEXT >

如果一个TEXT若被包含在双引号里,则当作一个字。

       quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )

qdtext       = <any TEXT except <">>

斜划线(""")可以被作为单个字符的引用机制,但是必须要在引号和注释区之内。

quoted-pair = """ CHAR