http1.0(2)

2.    标志转换及通用语法(Notational Conventions and
Generic Grammar)
2.1    补充反馈方式(Augmented BNF)
与RFC822[7]很类似,本文对所有机制的说明都是以散文和补充反馈的方式来描述的。
对于实现者来说,要想理解这些约定,必须对这些符号很熟悉。补充反馈方式(augmented
BNF)包括下面的结构:

要解释的名词=名词解释(name = definition)
规则的名字(name)就是它本身(不带任何尖括号,“<”,“>”),后面跟个等号=,
然后就是该规则的定义。如果规则需要用多个行来描述,利用空格进行缩进格式排
版。某些基本的规则使用大写,如SP, LWS, HT, CRLF, DIGIT, ALPHA,等等。定义
中还可以使用尖括号来帮助理解规则名的使用。

字面意思("literal")
    文字的字面意思放在引号中间,除非特别指定,该段文字是大小写敏感的。

规则1|规则2(rule1 | rule2)
    “|”表示其分隔的元素是可选的,比如,“是|否”要选择‘是’或‘否’。

(规则1 规则2)((rule1 rule2))
在圆括号中的元素表明必选其一。如(元素1(元素2|元素3)元素4)可表明两
种意思,即“元素1 元素2 元素4”和“元素1 元素3 元素4”

*规则(*rule)
在元素前加星号“*”表示循环,其完整形式是“<n>*<m>元素”,表明元素最少产
生<n>次,最多<m>次。缺省值是0到无限,例如,“1*元素”意思是至少有一个,
而“1*2元素”表明允许有1个或2个。

[规则]([rule])
方括号内是可选元素。如“[元素1 元素2]”与“*1(元素1 元素2)”是一回
事。

N 规则(N rule)
表明循环的次数:“<n>(元素)”就是“<n>*<n>(元素)”,也就是精确指出<n>
取值。因而,2DIGIT 就是2位数字, 3ALPHA 就是由三个字母组成字符串。

#规则(#rule)
“#”与“*”类似,用于定义元素列表。

完整形式是“<n>#<m>元素”表示至少有<n>个至多有<m>个元素,中间用“,”或
任意数量的空格(LWS-linear whitespace)来分隔,这将使列表非常方便,如“(*LWS
元素 *( *LWS "," *LWS 元素 ))”就等同于“1#元素”。

空元素在结构中可被任意使用,但不参与元素个数的计数。也就是说,“(元素1),,
(元素2)”仅表示2个元素。但在结构中,应至少有一个非空的元素存在。缺省
值是0到无限,即“#(元素)”表示可取任何数值,包括0;而“1#元素”表示至
少有1个;而“1#2元素”表示有1个或2个。

;注释(; comment)
    分号后面是注释,仅在单行使用。

隐含*LWS(implied *LWS)
本文的语法描述是基于单词的。除非另有指定,线性空格(LWS)可以两个邻近符
号或分隔符(tspecials)之间任意使用,而不会对整句的意思造成影响。在两个符号之
间必须有至少一个分隔符,因为它们也要做为单独的符号来解释。实际上,应用程序在
产生HTTP结构时,应当试图遵照“通常方式”,因为现在的确有些实现方式在通常方
式下无法正常工作。

2.2    基本规则(Basic Rules)
下面的规则将用于本文后面对结构基本解析。
US-ASCII 编码字符集定义[17]。

OCTET     = <8-bit的顺序数据,即bytes>
CHAR     = < US-ASCII字符(取值为0 – 127的OCTET)>
UPALPHA    = < US-ASCII 大写字符"A"到"Z">
LOALPHA    = <US-ASCII 小写字符"a"到"z">

         ALPHA    = UPALPHA | LOALPHA
         DIGIT    = < US-ASCII 数字"0"到"9">
         CTL     = < US-ASCII 控制字符(取值0到31的octet )和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.0规定,除实体主体(Entity-Body,见附录B容错应用)外,所有协议元
素的行结束标志都是CRLF(按字节顺序)。在实体主体内部的行结束标志定义及
其对应的介质类型定义,见3.6节的描述。

CRLF    = CR LF

HTTP/1.0的头可以折成许多行,只要每个后续行以空格或水平制表符开头。所有
的线性空格(LWS),同空格(SP)有相同的语义。

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

实际上,有些应用并没有考虑处理这样多行的头,所以从兼容性上考虑,HTTP/1.0
应用最好不要产生折成多行的头。

TEXT规则只是用于描述消息解释器不关心的域的内容及其取值。文本内容可包含
不同于US-ASCII的字符。

TEXT    = <除了控制字符(CTLs)之外的任何OCTET,包括LWS >
  
在标题域中的收件人域如包含US-ASCII字符集以外的字符,这些字符将按照
ISO-8859-1标准来解释。

十六进制数字型字符在几个协议元素中到。

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

许多HTTP/1.0头域的内容由被LWS分隔的单词或特殊字符组成,这些特殊字符
必须置于引号中间的字符串内,作为参数值使用。

Word    = 符号(token)| 被引号引起来的字符串

token    = 1*<除控制字符(CTLs)或tspecials之外的任意字符>

tspecials       = "(" | ")" | "<" | ">" | "@"
                        | "," | ";" | ":" | "\" | <">
                        | "/" | "[" | "]" | "?" | "="
                        | "{" | "}" | SP | HT
  
在HTTP头域中可用括号表示注释文字。注释只允许写在包含注释的域,做为域值
定义的一部分。在除此之外其它域中,括号将被视为域值。

comment    = "(" *( ctext | comment ) ")"
ctext     = <除圆括号外的任何TEXT>

被双引号圈中的文本字符串将被视为一个单词。

quoted-string = ( <"> *(qdtext) <"> )
qdtext    = <除了双引号及控制字符之外的任何字符,包括LWS >

    在HTTP/1.0中不允许使用后斜线“\”来引用单字符。

3.    协议参数(Protocol Parameters)
3.1    HTTP版本(HTTP Version)

HTTP采用主从(<major>.<minor>)数字形式来表示版本。协议的版本政策倾向于让发
送方表明其消息的格式及功能,而不仅仅为了获得通讯的特性,这样做的目的是为了与更高
版本的HTTP实现通讯。只增加扩展域的值或增加了不影响通讯行为的消息组件都不会导致
版本数据的变化。当协议消息的主要解析算法没变,而消息语法及发送方的隐含功能增加了,
将会导致从版本号(<minor>)增加;当协议中消息的格式变化了,主版本号(<major>)也
将发生改变。
HTTP消息的版本由消息第一行中的HTTP版本域来表示。如果消息中的协议版本没有
指定,接收方必须假定它是符合HTTP/0.9的简单标准。

HTTP-Version    = "HTTP" "/" 1*DIGIT "." 1*DIGIT
  
注意,主从版本应当被看作单独的整数,因为它们都有可能增加,从而超过一位整
数。因而,HTTP/2.4比HTTP/2.13版本低,而HTTP/2.13又比HTTP/12.3版本低。
版本号前面的0将被接收方忽略,而在发送方处也不应产生。
  
本文档定义了HTTP协议的0.9及1.0版本。发送完整请求(Full-Request)及完整
回应(Full-Response)消息的应用必须指明HTTP的版本为“HTTP/1.0”。

HTTP/1.0服务器必须:

o识别HTTP/0.9及HTTP/1.0请求命令中的请求队列(Request-Line)的格式。
o理解任何HTTP/0.9及HTTP/1.0中的合法请求格式。
o 使用与客户端相同版本的协议进行消息回应。

HTTP/1.0 客户端必须:

        o 识别HTTP/1.0回应中状态队列(Status-Line)的格式。
o 理解HTTP/0.9及HTTP/1.0中合法回应的格式。

当代理及网关收到与其自身版本不同的HTTP请求时,必须小心处理请求的推送,因为
协议版本表明发送方的能力,代理或网关不应发出高于自身版本的消息。如果收到高版本的
请求,代理或网关必须降低该请求的版本,并回应一个错误。而低版本的请求也应在被推送
前升级。
代理或网关回应请求时必须遵照前面列出的规定。

3.2    统一资源标识(Uniform Resource Identifiers)

URI有许多名字,如WWW地址、通用文件标识(Universal Document Identifiers)、通
用资源标识(Universal Resource Identifiers [2]),以及最终的统一资源定位符(Uniform
Resource Locators (URL) [4])和统一资源名(URN)。在涉及HTTP以前,URI用简单格式
的字符串描述-名字、位置、或其它特性,如网络资源。

3.2.1 一般语法(General Syntax)
在HTTP中URI可以用绝对形式表示,也可用相对于某一基本URI[9]的形式表示,具
体取决于它们的使用方式。这两种形式的不同在于绝对URI总是以方法名称后跟“:”开头。

         URI     = ( absoluteURI | relativeURI ) [ "#" fragment ]

         absoluteURI = scheme ":" *( uchar | reserved )

         relativeURI = net_path | abs_path | rel_path

         net_path         = "//" net_loc [ abs_path ]
         abs_path         = "/" rel_path
         rel_path         = [ path ] [ ";" params ] [ "?" query ]

         path             = fsegment *( "/" segment )
         fsegment         = 1*pchar
         segment          = *pchar

         params           = param *( ";" param )
         param            = *( pchar | "/" )

         scheme           = 1*( ALPHA | DIGIT | "+" | "-" | "." )
         net_loc          = *( pchar | ";" | "?" )
         query            = *( uchar | reserved )
         fragment         = *( uchar | reserved )

         pchar            = uchar | ":" | "@" | "&" | "=" | "+"
         uchar            = unreserved | escape
         unreserved       = ALPHA | DIGIT | safe | extra | national

         escape           = "%" HEX HEX
         reserved         = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
         extra            = "!" | "*" | "'" | "(" | ")" | ","
         safe             = "$" | "-" | "_" | "."
         unsafe           = CTL | SP | <"> | "#" | "%" | "<" | ">"
         national         = <any OCTET excluding ALPHA, DIGIT,


                          reserved, extra, safe, and unsafe>
权威的URL语法及语义信息请参见RFC1738[4]和RFC1808[9]。上面所提到的BNF中
包括了合法URL中不允许出现的符号(RFC1738),因为HTTP服务器并没有限制为只能用
非保留字符集中的字符来表示地址路径,而且HTTP代理也可能接收到RFC1738没有定义
的URI请求。

3.2.2 http URL

“http”表示要通过HTTP协议来定位网络资源。本节定义了HTTP URL的语法和语义。

         http_URL         = "http:" "//" host [ ":" port ] [ abs_path ]

host             = <合法的Internet主机域名或IP地址(用十进制数及点组成)
,见RFC1123,2.1节定义>

         port             = *DIGIT

如是端口为空或没指定,则缺省为80端口。对于绝对路径的URI来说,拥有被请求的
资源的服务器主机通过侦听该端口的TCP连接来接收该URI请求。如果URL中没有给出
绝对路径,要作为请求URI(参见5.1.2节)使用,必须以“/”形式给出。

注意:虽然HTTP协议独立于传输层协议,http URL只是标识资源的TCP位置,而对
于非TCP资源来说,必须用其它的URI形式来标识。

规范的HTTP URL形式可通过将主机中的大写字符转换成小写(主机名是大小写敏感
的)来获得。如果端口是80,去掉冒号及端口号,并将空路径替换成“/”。

3.3    Date/Time 格式(Date/Time Formats)

出于历史原因,HTTP/1.0应用允许三种格式来表示时间戳:

         Sun, 06 Nov 1994 08:49:37 GMT      ; RFC 822, updated by RFC 1123
         Sunday, 06-Nov-94 08:49:37 GMT     ; RFC 850, obsoleted by RFC 1036
         Sun Nov    6 08:49:37 1994           ; ANSI C's asctime() format

第一种格式是首选的Internet标准格式,表示方法长度固定(RFC1123[6])。第二种格
式在普通情况下使用,但是它是基于已经废弃的RFC850[10]中的日期格式,而且年不是用
四位数字表示的。HTTP/1.0 客户端及服务器端在解析日期时可识别全部三种格式,但是它
们不可以产生第三种时间格式(asctime) 。
注意:对于接收到由非HTTP应用产生的日期数据时,提倡对接收到的日期值进行填充。
这样做是因为,在某些时候,代理或网关可能通过SMTP或NNTP来获取或发送消息。
所有的HTTP/1.0 date/timp时间戳必须用世界时间(Universal Time,UT),即格林威治
时间来表示(Greenwich Mean Time,GMT),没有任何修改的余地。前面的两种格式用了
“GMT”表示时区,在读ASC表示的时间时,也应假定是这个时区。

HTTP-date = rfc1123-date | rfc850-date | asctime-date

rfc1123-date = wkday "," SP date1 SP time SP "GMT"
rfc850-date = weekday "," SP date2 SP time SP "GMT"
asctime-date = wkday SP date3 SP time SP 4DIGIT
date1    = 2DIGIT SP month SP 4DIGIT
                       ; day month year (e.g., 02 Jun 1982)
date2    = 2DIGIT "-" month "-" 2DIGIT
                        ; day-month-year (e.g., 02-Jun-82)
date3    = month SP ( 2DIGIT | ( SP 1DIGIT ))
                        ; month day (e.g., Jun    2)
time     = 2DIGIT ":" 2DIGIT ":" 2DIGIT
                        ; 00:00:00 - 23:59:59
wkday    = "Mon" | "Tue" | "Wed"
                        | "Thu" | "Fri" | "Sat" | "Sun"
weekday    = "Monday" | "Tuesday" | "Wednesday"
                        | "Thursday" | "Friday" | "Saturday" | "Sunday"
month    = "Jan" | "Feb" | "Mar" | "Apr"
                        | "May" | "Jun" | "Jul" | "Aug"
                        | "Sep" | "Oct" | "Nov" | "Dec"
注意:HTTP要求只能在协议流中使用data/time时间戳格式,不要求客户端及服务
器端在用户描述、请求登录等情况下使用这类格式。
3.4    字符集(Character Sets)

HTTP所使用的字符集定义和描述MIME时用的相同:
本文档用字符集(character set)来指明利用一个或多个表将顺序字节转换成顺序字
符的方法。注意,不需要其它方向的无条件转换,因为不是所有的字符都可以用给
定字符集来表示,同时,一个字符集也可能提供一种以上的字节顺序来表示一种特
殊的字符。这种定义倾向于允许不同类型的字符编码通过简单的单表映射来实现,
如,从表US-ASCII切换到复杂表如ISO2202。实际上,与MIME字符集名相关的
定义必须完整指定从字节到字符的映射,特别是不允许通过利用外部配置信息来确
定精确的映射。

注意:术语字符集(character set)归于字符编码(character encoding)。事实上,
由于HTTP与MIME共同使用同样的注册,所以其术语也应一致。
  
HTTP字符集由大小写敏感的符号组成。全部的符号定义参见IANA字符集注册
[15]。因为注册处不会为每个字符集单独定义一套符号,所以我们在这看到的字符
集名大多是与HTTP实体使用相关的。这些在RFC 1521 [5] 中注册的字符集,即
US-ASCII [17] 及ISO-8859 [18]字符集,还有一些其它字符集被强烈建议在MIME
字符集参数内部使用。

charset = "US-ASCII"
               | "ISO-8859-1" | "ISO-8859-2" | "ISO-8859-3"
               | "ISO-8859-4" | "ISO-8859-5" | "ISO-8859-6"
               | "ISO-8859-7" | "ISO-8859-8" | "ISO-8859-9"
               | "ISO-2022-JP" | "ISO-2022-JP-2" | "ISO-2022-KR"
               | "UNICODE-1-1" | "UNICODE-1-1-UTF-7" | "UNICODE-1-1-UTF-8"
               | token
  
虽然HTTP允许使用专用符号做为字符集值,但是任何在IANA字符集注册表[15]
中有预定义值的符号都必须表明其所属的字符集。应用应当将其对字符集的使用限
制在IANA注册表规定的范围之内。

实体主体的字符集如果属于US-ASCII 或ISO-8859-1字符集,则勿需标记,否则,
应当用主体字符编码方式中的最基本命名来标记。

3.5    内容译码(Content Codings)
内容译码值用于指示对资源进行的编码转换。内容译码主要用于将经过压缩、加密等操
作的文件进行还原,使其保持其原来的介质类型。典型情况下,经过编码保存的资源只能经
过解码或类似的操作才能还原。
content-coding = "x-gzip" | "x-compress" | token
注意:出于对未来兼容性的考虑,HTTP/1.0应用应将"gzip" 和"compress" 分别与
"x-gzip"和"x-compress"对应起来。
所有的内容译码值都是大小写敏感的。HTTP/1.0在内容编码(10.3节)头域中使用内
容译码值。虽然该值描述的是内容译码,但更为重要的是,它指明了应当用什么机制来进行
解码。注意,单独的程序可能有能力实现对多种格式编码的解码。
在这段文字中,提到了两个值:
x-gzip
文件压缩程序"gzip" (GNU zip,由Jean-loup Gailly开发)的编码格式。该格式属于
典型的带有32位CRC 校验的Lempel-Ziv译码 (LZ77)。
x-compress
文件压缩程序"compress"的编码格式,该格式适用于LZW(Lempel-Ziv-Welch)译
码。
注意:用程序名来标识编码格式的做法不是很理想,在将来可能不会继续这样做。现在
之所以这样做是出于历史的原因,并非良好的设计。

3.6    介质类型(Media Types)

HTTP在Content-Type header域(10.5节)中使用Internet介质类型[13],用以提供开放
的可扩展的数据类型。
media-type    = type "/" subtype *( ";" parameter )
type      = token
subtype     = token

参数可参照属性/值对的方式,用类型/子类型的格式来写。

Parameter    = attribute "=" value
Attribute     = token
Value     = token | quoted-string

其中,类型、子类型、参数属性名是大小写敏感的。而参数值不一定是大小写敏感的,
这得看参数名的语法而定。在类型和子类型、属性名和属性值之间不能有LWS(空格)。当
接收到不能识别的介质类型的参数时,用户代理应当忽略它们。
一些老的HTTP应用不能识别介质类型参数,所以HTTP/1.0的应用程序只能在定义消
息内容时使用介质参数。
介质参数(Media-type)值用Internet授权分配数字(Internet Assigned Number   
Authority ,IANA [15])注册。介质类型注册过程请参见RFC1590[13]。不鼓励使用未注册
的介质类型。

3.6.1标准及文本缺省(Canonicalization and Text Defaults)
Internet介质类型是用规范形式注册的。一般来说,在通过HTTP协议传输实体主体
(Entity-Body)之前,必须先将其表示成适当的规范格式。如果主体用使用了一种
Content-Encoding进行编码,下面的数据在编码前必须转换成规范形式:
"text"类型的介质子类型在规范形式中使用CRLF做为文本行中断。实际上,为和实体
主体(Entity body)内的使用方式保持一致,HTTP允许传输纯以CR或LF单独表示行中断
的文本介质。HTTP应用程序必须将其通过HTTP方式接收到的文本介质中的CRLF、CR、
LF看做是行中断符。

另外,如果文本介质的字符集没有使用字节13和10做为CR和LF,象一些多字节字
符集,HTTP允许使用该字符集指定的任何顺序的字节替代CR和LF做为行中断,这种行
中断的灵活运用方式仅可于实体主体(Entity-Body)中。一个纯CR或LF不应在任何HTTP
控制结构(如标题域-header field和多块分界线-multipart boundaries)中替代CRLF。
参数"charset"在定义数据的字符集(3.4节)时,与一些介质类型一起使用。当发送方
没有显式给出字符参数时,HTTP在接收时将"text"的介质子类型定义为缺省
值"ISO-8859-1"。"ISO-8859-1"字符集或其子集以外的数据必须要标记其相应的字符集值,
这样可以保证接收方能正确地对其进行解析。
注意:许多当前HTTP服务器提供的数据使用"ISO-8859-1"以外的其它字符集,而且也
没有正确的进行标记,这种工作方式限制了互操作性,建议不要采用。做为一种补救方法,
一些HTTP用户代理提供了配置选项,使用户可以在字符集参数没指定的情况下,自行更改
缺省的介质类型解释方式。

3.6.2 多部分类型(Multipart Types)


MIME提供了多部分("multipart")类型的数字――在一个单独的消息实体主体
(Entity-Body)内可以封装几个实体(entities)。虽然用户代理可能需要了解每种类型,从
而可以正确解释每部分主体的意图,但是在IANA[15]的多部分类型(multipart types)注册
中却找不到专为HTTP/1.0所指定的内容。HTTP用户代理只得自己来做接收多部分类型的
工作,其过程和行为与MIME用户代理是相同或相似的。HTTP服务器不应假定HTTP客户
端都有能力处理多部分类型。

所有的多部分类型都使用通用的语法,而且必须在介质类型值部分包括边界参数
(boundary parameter)。消息的主体是其自身,做为协议元素,它必须只使用CRLF做为段
间(body-parts)的行中断符。多段主体(Multipart body-parts)中可能包括对各段有重要意
义的HTTP标题域。

3.7    产品标识(Product Tokens)
是通讯应用程序用来标识其自身的一个简单符号,常和任意字母及版本描述一起使用。
大多数产品标识也将其产品的重要组成部分的版本号一起列出,中间用空格分隔。

按惯例,在标识应用程序时,组件以其重要性顺序排列。
Product     = token ["/" product-version]
product-version    = token
例如:
         User-Agent: CERN-LineMode/2.15 libwww/2.17b3
         Server: Apache/0.8.4
产品标识应当短小,因而禁止利用该域填写广告或其它无关信息。虽然任何符号字符都
可能出现在产品版本中,该符号应当只用于做版本定义,也就是说,同一个产品的连续版本
之间只能通过产品版本值进行区分。

相关文章

随机推荐:

相关链接

helloajax.com
专注Ajax、Asp.Net、JavaScript技术