4 HTTP消息
4.1 消息类型(Message Types)
HTTP消息由从客户到服务器的请求和从服务器到客户的响应组成.

             

HTTP-message = Request|Response ;HTTP/1.1

请求(第5节)和响应(第6节)消息利用RFC 822[9]定义的常用消息的格式,这种消息格式是用于传输实体(消息的负载)。两种类型的消息由开始行(start-line),零个或更多个头域(经 常被称作“头”),一个指示头域结束的空行(也就是,一个以CRLF为前缀的什么也没有的行),一个可有可无的消息主体(message-body)。

generic-message = start-line

*(message-header CRLF)

CRLF

[ message-body ]

start-line = Request-Line | Status-Line

为了健壮性,服务器应该忽略任意请求行(Request-Line)前面的空行。换句话说,如果服务器开始读消息流的时候发现了一个CRLF,它应该忽略这个CRLF。

一般一个有问题的HTTP/1.0客户端会在POST请求消息之后产生额外的CRLF。为了重述什么是BNF明确禁止的,一个HTTP/1.1客户端不能在请求前和请求后加一些不必要的CRLF。

4.2 消息头 (Message Headers)
HTTP头域包括常用头(4.5节),请求头(5.3节),响应头(6.2节)和实体 头(7.1节)域。它们遵循RFC822[0]3.1节中给出的同一个常规的格式。每一个头域由一个名字(域名)跟随一个":"和域值构成。域名是大小写 不敏感的。域值前面可能有任意数量的LWS的。但SP(空格)是首选的。头域能被延升多行,通过在这些行前面加一些SP或HT。应用程本应该遵循“常用格 式”当产生HTTP消息时,因为可能存在一些应用程序,他们不能接收任何常用形式之外的形式。.

message-header = field-name ":" [ field-value ]

field-name = token

field-value = *( field-content | LWS )

field-content = <the OCTETs making up the field-value

and consisting of either *TEXT or combinations

of token, separators, and quoted-string>

filed-content不包括任何前导或后续的LWS(线性空白):线性空白出现在域值(filed-value)的第一个非空白字符之前或最 后一个非空白字符之后。前导或后续LWS可能会被移除而不会改变域值的语意。任何出现在filed-content之间的LWS可能会被一个SP代替在解 析域值之前或把这个消息往下流传递时。.

不同域名的头域被接收的顺序是不重要的。然而,首先发送常用头域,然后紧接着是请求头域或者是响应头域,然后是以实体头域结束,这样做是一个好的的方法。

多个消息头域使用同一个域名(filed-name)可能会出现在一些消息中,如果一个头域的域值被定义成一个以逗号隔开的列表。把相同名的多个头 域结合成一个“域名:域值”对的形式而不改变消息的语意,可以通过把每一个后续的域值加到第一个里,每一个域值用逗号隔开。同名的头域的接收顺序对合并的 域值的解释有重要意义,所以代理(proxy)不能改变域值的顺序,当它把此消息再次转发时。

4.3 消息主体 (Message Body)
HTTP消息的消息主体用来承载请求和响应的实体主体(entity-body)。这些消 息主体(message-body)仅仅当传输编码(transfer-coding)应用于传输译码(Transfer-Encoding)头域时才和 实体主体(entity-body)不同,其它情况消息主体和实体主体相同。传输译码头域在14.41节阐述。

     message-body=entity-body|<entity-body encoded as per Transfer-Encoding>

传输译码头域被用来指明应用程序的传输编码,它是为了保证安全和适合的消息传输。传输译码(Transfer-Encoding)头域是消息的属性,而不是实体的属性,并且沿着请求/响应链能被添加或删除。(然而,3.6节描述了一些限制当使用某个传输编码时)

什么时候消息主体(message-body)允许出现在消息中,这根据不同请求和响应来决定的。

请求中消息主体(message-body)的存在是被请求中消息头域中是否存在内容长度(Content-Length)或传输译码 (Transfer-Encoding)头域来暗示的。一个消息主体(message-body)不能被包含在请求里如果请求方法(见5.1.1节)不允 许请求里包含实体主体(entity-body)。一个服务器应该能阅读或再次转发请求里的消息主体;如果请求方法不允许包含一个实体主体 (entity-body),那么消息主体应该被忽略当服务器处理这个请求时。

对于响应消息,消息里是否包含消息主体依赖相应的请求方法和响应状态码。所有HEAD请求方法的请求的响应消息不能包含消息主体,即使实体头域出现 在请求里。所有1XX(信息的),204(无内容的)和304(没有修改的)的响应都不能包括一个消息主体(message-body)。所有其他的响应 必须包括消息主体,虽然它可能长度为零.

4.4 消息的长度(Message Length)
一条消息的传输长度(transfer-length)是消息主体(message- body)的长度,当消息主体出现在消息中时;那就是说在实体主体被应用了传输编码(transfer-coding)后。当消息中出现消息主体时,消息 主体的传输长度(transfer-length)由下面(以优先权的顺序)决定::

1。任何不能包含消息主体(message-body)的消息(这种消息如1xx,204和304响应和任何HEAD请求的响应)总是被头域后的第一个空行(译注:CRLF)终止,不管消息里是否有实体头域(entity-header fields)。

2。如果Transfer-Encoding头域(见14.41节)出现,并且它的域值不是”identity”,那么传输长度(transfer-length)被“块”传输编码定义,除非消息因为关闭连接而被终结了。

3。如果Content-Length头域(属于实体头域)(见14.13节)出现,那么它的十进制值(以字节表示)就代表实体主体长度 (entity-length,译注:实体长度其实就是实体主体的长度,以后把entity-length翻译成实体主体的长度)也代表传输长度 (transfer-length)。Content-Length头域不能包含在消息中,如果实体主体长度(entity-length)和传输长度 (transfer-length)两者不相等(也就是说,消息里应用了传输译码(Transfer-Encoding)头域)。如果一个消息即有传输译 码(Transfer-Encoding)头域并且也Content-Length头域,后者会被忽略。

4。如果消息用到媒体类型“multipart/byteranges”,并且传输长度(transfer-length)另外也没有指定,那么这 种自我定界的媒体类型定义了传输长度(transfer-length)。这种媒体类型不能被利用除非发送者知道接收者能怎样去解析它; HTTP1.1客户端请求里如果出现Range头域并且带有多个字节范围(byte-range)指示符,这就意味着客户端能解析 multipart/byteranges响应。

一个Range请求头域可能会被一个不能理解multipart/byteranges的HTTP1.0代理(proxy)再次转发;在这种情况下,服务器必须能定界此消息利用这节的1,3或5项里定义的方法。

5。通过服务器关闭连接能确定消息的传输长度。(关闭连接并不能用来指明请求消息体的结束,因为这样可以让服务器没有机会继续给予响应)。

为了与HTTP/1.0应用程序兼容,包含HTTP/1.1消息主体的请求必须包括一个有效的内容长度(Content-Length)的头域,除 非服务器是和HTTP/1.1遵循的。如果一个请求包含一个消息主体并且没有给出内容长度(Content-Length),那么服务器应该以400响应 (错误的请求)如果他不能判断消息长度的话,或者以411响应(要求长度)如果它坚持想要收到一个有效内容长度(Content-length)。

所有的能接收实体的HTTP/1.1应用程序必须能接受"chunked"的传输编码(3.6节),因此可以允许这种机制来处理消息当消息的长度不能被提前决定时。

消息不能同时都包括内容长度(Content-Length)头域和非identity传输编码。如果消息包括了一个非identity的传输编码,内容长度(Content-Length)头域必须被忽略.

当内容长度(Content-Length)头域出现一个具有消息主体(message-body)的消息里,它的域值必须精确匹配消息主体里字节数量。HTTP/1.1用户代理必须通知用户当一个无效的长度接收了。

 

4.5 常用头域(General Header Fields)
有一些头域即适用于请求也适用于响应消息,但是这些头域并不适合被传输的实体。这些头域只能应用与被传输的消息。

general-header = Cache-Control ; Section 14.9

| Connection ; Section 14.10

| Date ; Section 14.18

| Pragma ; Section 14.32

| Trailer ; Section 14.40

| Transfer-Encoding ; Section 14.41

| Upgrade ; Section 14.42

| Via ; Section 14.45

| Warning ; Section 14.46

常用头域的名能被扩展,但这要和协议版本的变化相结合。然而,新的或实验性的头域可能被赋予常用头域的语意,如果通信里的所有参与者都认为他们是常用头域。不被识别的头域会被作为实体头(entity-header)头域来看待。