您的位置:首页 > 理论基础 > 计算机网络

HTTP1.1 协议 第十四章定义 头域定义

2018-01-04 17:45 211 查看
14 头域定义

本节定义了所有HTTP/1.1种标准头域的语法和语义。对于实体头域,发送者和接收者指的是客户端和服务器,取决于谁发送和谁接收此实体。

14.1  Accept

Accept请求头域被用于指定服务器返回给客户端可接受的响应媒体类型。Accept头域能被用于指明请求是期望服务器返回某些期望的媒体类型的响应,例如请求一个内嵌的图像。

 Accept         = "Accept" ":"

                        #( media-range [ accept-params ] )

 media-range    = ( "*/*"

                        | ( type "/" "*" )

                        | ( type "/" subtype )

                        ) *( ";" parameter )

 accept-params = ";" "q" "=" qvalue *( accept-extension )

 accept-extension = ";" token [ "=" ( token | quoted-string ) ]

星号”*”字符用于把媒体类型组合成一个范围,”*/*”指明了所有的媒体类型而”type/*”指明了type类型的所有子类型。Media-range可能包含一个媒体类型参数。

每一个media-range可能会跟随一个或多个accept-params,以“q”参数指明一个相对的喜爱程度的质量因子。第一个“q”参数(如果有的话)把accept-params和media-range参数分离了。喜爱程度质量因子允许用户或用户代理去指明对那个media-range的相对喜爱程度,qvalue的范围是从0到1(见3.9节)。缺省是q=1。

注意:利用“q”参数名字将媒体类型参数(译注:media-range里的parameter)和accept-extension分离开来是基于历史的实践。虽然这防止里任何媒体类型参数以“q”命名并使用于media-range里,但在一个media-range里使用“q”被认为是不可能发生的,这是因为在IANA的媒体类型注册表里是没有“q”参数的并且在Accept头域里利用任何媒体类型参数也是很少的。将来的媒体类型不鼓励任何以“q”命名的参数注册。

例子::

 Accept :audio/*;q=0.2,audio/basic

该例应该被解释成“我喜欢audio/basic,但是可以给我发送任何最容易得的audio类型,但在喜爱程度质量要下降80%”。

如果没有Accept头域出现,那么会假设客户端能接受所有媒体类型。如果Accept头域在请求消息里出现,并且如果服务器根据联合的Accept头域值判定它不能发送可接受的(acceptable)的响应,那么服务器应该发送406(不可接受的)响应。

一个更加详尽的例子如下:

   Accept: text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c

这可能被口头地解释成“text/html 和 text/x-c是更喜爱的媒体类型,但是如果他们不存在,那么发送text/x-dvi实体,但如果text/x-dvi也不存在,那么发送text/plain实体。”

Media-range能被更具特指的media-range或媒体类型覆盖。如果多个media-range应用了一个特指的类型,那么最特指的引用应该优先。例如:

   Accept: text/*, text/html, text/html; level=1, */*

拥有下面的优先顺序:

text/html; level=1

text/html

text/*

*/*

一个媒体类型的喜爱程度质量因子是和一个给定的媒体类型联系在一起的,它是由查找能最高优先匹配那个媒体类型的media-range决定的。例如:

 Accept:: text/*; q=0.3, text/html; q=0.7, text/html; level=1,

text/html; level=2; q=0.4, */*; q=0.5

可能会引起下面值被联系:

 text/html;level=1         = 1

 text/html                 = 0.7

 text/plain                = 0.3

 image/jpeg                = 0.5

 text/html;level=2         = 0.4

 text/html;level=3         = 0.7

注意:一个用户代理可能会为一个特定的media-range提供一个缺省的质量值的集合。然而,除非用户代理是一个不能和其他的呈现代理交互的封闭的系统,否则这个缺省的集合应该是被用户可设置的。

14.2  Accept-Charset

Accept-Charset请求头域可以用来指出请求客户端能接受什么样的字符集响应。这个头域允许客户端能通知服务器指定何种此客户端更能理解的或更具特殊目的的字符集的响应。

Accept-Charset = "Accept-Charset" ":"

              1#( ( charset | "*" )[ "
1c140
;" "q" "=" qvalue ] )

字符集值在3.4节里描述。每一个字符集可能被给于一个想联系的质量值用来表示用户对那个字符集的喜爱程度。缺省值是q=1.例如:

Accept-Charset: iso-8859-5, unicode-1-1;q=0.8

特殊的“*”值如果出现在Accept-Charset头域里,那么将匹配任何字符集(character set)(包含ISO-8859-1)。如果没有“*”出现在Accept-Charset头域里,那么所有出现的字符集的质量值为0,除了ISO-8859-1,它的质量值为1如果没有出现在Accept-Charset头域里。

如果Accept-Charset头域没有出现,那么缺省情况是任何字符集会接受。如果Accept头域出现在请求消息里并且服务器不能发送客户端想要的Accept-Charset里指定的字符集的响应,那么服务器将发送一个406(不能接受的)错误响应,然而发送一个不能不能让客户端接受的字符集的响应也是允许的。

14.3  Accept-Encoding

Accept-Encoding请求头域和Accept头域相似,但Accept-Encoding是限定服务器返回给客户端可以接受的内容编码(content-coding,见3.5节)。

        Accept-Encoding = "Accept-Encoding" ":"

                      1#( codings [ ";" "q" "=" qvalue ] )

       codings          = ( content-coding | "*" )

使用的例子如下:

       Accept-Encoding: compress, gzip

       Accept-Encoding:

       Accept-Encoding: *

       Accept-Encoding: compress;q=0.5, gzip;q=1.0

       Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0

服务器测试一个内容编码(content-coding)是否是可接受的,是根据Accept-Encoding头域,并利用下面的规则来决定:

如果一个内容编码(content-coding)在Accept-Encoding头域里出现,那么它是可以接受的(acceptable),除非它的qvalue为0。(这在3.9节里定义,一个qvalue为0说明是“不可接受的”)

如果“*”字符出现在Accept-Encoding头域里,那么它匹配任何没有出现在Accept-Encoding头域的可得的内容编码。

如果多个内容编码是可接受的,那么qvalue为最高的且非0的内容编码是最喜欢的。

“identity”内容编码总是可接受的,除非qvalue为0,或者Accept-Encoding头域包含“*;q=0”并且同时没有包含“identity”内容编码。如果Accept-Encoding头域值为空,那么只有“identity”编码是可接受的。

如果Accept-Encoding头域在请求里出现,并且如果服务器不能发送一个Accept-Encoding头域里指定的编码响应,那么服务器应该发送一个406(不接受的)错误的响应。

如果没有Accept-Encdong头域出现在请求消息里,服务器应该假设客户端将接受任何内容编码。在这种情况下,如果“identity”是这些可得的内容编码中的一个,那么服务器将利用“identity”内容编码,除非服务器有另外的信息指明其他的内容编码对客户端是有意义的。

注意:如果请求不能包含一个Accept-Encoding头域,并且如果“identity”内容编码是不能接受的,那么通常不能被HTTP/1.0客户端理解的内容编码(也就是说,“gzip”和“compress”)通常是最喜爱的;一些老的客户端有时候会不合适的显示以其他内容编码的消息。服务器应该照样能基于特定的用户代理或服务器的信息做除决定用何种内容编码响应。

注意:大多数HTTP/1.0应用程序不能识别或遵循一个内容编码跟随一个qvalue。这意味着qvalue将不能工作并且在x-gzip或x-compress里不能被允许。

14.4  Accept-Language

Accept-Language请求头域和Accept请求头域类似,但是它是限定服务器返回给客户端喜爱的自然语言。

       Accept-Language = "Accept-Language" ":"

                         1#( language-range [ ";" "q" "=" qvalue ] )

       language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )

每个language-range均被赋以一个质量值,它代表用户对此language-range里涵盖语言的喜爱程度。质量值缺省为1,例如:

       Accept-Language: da, en-gb;q=0.8, en;q=0.7

好像在说:“我更喜欢Danish,但是也可以接收British English和其他的English的类型的语言。”一个language-range匹配一个语言标签(译注:如上面例子的da,en-gb,en)如果它能精确和此语言标签相等,或者它能精确匹配此标签的前缀(在“-”以前的部分)。特殊的“*”,如果出现在Accept-Language头域里,表明能匹配任何不在此头域里的任何标签。

注意:前缀匹配规则意味着用户能理解匹配此前缀的所有语言。

一个语言标签的质量因子是Accept-Language头域里最能匹配此语言标签的language-range的质量值。如果Accept-Language头域里没有language-range匹配此语言标签,那么此语言的质量因子被赋予0。如果没有Accept-Language头域出现在请求里,那么服务器应该假设所有语言将是可接受的。如果一个Accept-Language头域出现在请求里,那么所有质量因子大于0的语言是可接受的。

如果发送一个和用户喜爱的语言相反,这将在15.1.4里讨论。

由于个别的用户的理解程度不一样,建议客户端应用程序让用户对语言的偏好进行选择。如果客户不能进行选择,那么Accept-Language头域不能在请求里给出。

注意:当让用户作出选择时,我们要实现者一个事实那就是客户不熟悉语言的细节,并且不会提供一个合适的指导。例如,用户可能会认为当选择了“en-gb”会提供任何类型的英语文档即使British English是不可得的。一个用户代理应该能建议去增加一个“en”去得到最合适的匹配行为。

14.5  Accept-Range

Accept-Range响应头域允许服务器指明它对客户的范围请求(range request,译注:当在请求消息里出现Range头域时表明此请求是范围请求)的接受程度。

     Accept-Ranges     = "Accept-Ranges" ":" acceptable-ranges

     acceptable-ranges = 1#range-unit | "none"

源服务器如果接受字节范围请求(byte-range request)那么可以发送

      Accept-Ranges: bytes

但是没有必要这样做。客户端在没有接收此头域时也可以产生字节范围请求(byte-range request)。范围单位(range units)被定义在3.12节。

服务器如果不能接受任何类型的范围请求(range request),将会发送

Accept-Ranges:none

去告诉客户不要尝试范围请求(range request)。

14.6  Age

Age响应头域表示发送者(译注:一般是缓存)对响应产生(或重验证)时刻后经过时间的估计。一个缓存的响应是保鲜的(fresh)如果此响应的年龄没有超过它的保鲜寿命(freshness response)。Age值怎样计算在13.2.3节里描述了。

                 Age = "Age" ":" age-value

                 age-value = delta-seconds

Age值是十进制非负整数,并且以秒为单位.。

如果缓存接收到一个Age值大于它所能表示的上限,或它的年龄计算出现溢出,那么它必须传送Age头域的值为2147483648 (2^31)。一个HTTP/1.1服务器如果包含一个缓存,那么它必须包含一个Age头域在它拥有缓存产生的任何响应里。缓存应该利用一个至少31位的运算类型。

14.7  Allow

Allow实体头域中列出了请求URI(Request-URI)指定资源所支持的几种方法。此头域的目的是严格地让接收端知道资源所适合的方法。Allow头域必须出现在405(方法不被允许)响应中。

     Allow = "Allow" ":"  #Method

使用示例:

     Allow: GET, HEAD, PUT

这一头域不能阻止客户端使用其他方法。然而只有在Allow头域域中给出的方法才应该被执行。Allow头域里指定的方法被源服务器定义,并且在每次请求的响应里都应该出现这些方法。

Allow头域里可以被提供在一个PUT请求里,这是为了说明新的或改变的资源支持这些方法。服务器不需要去支持这些方法,而且应该包含一个Allow头域在响应里并且给出实际支持的方法。

代理服务器不能改变Allow头域即便不理解此头域里指明的所有方法,因为用户代理可能和源服务器通信有其他的目的。

14.8 Authorization (授权)

用户代理往往希望通过服务器给自己授权,用户代理这样做是通过在请求里包含一个Authorization请求头域,但是通常在接收了一个401响应后就没有必要让服务器给自己授权了。Authorization头域由包含用户代理对那个请求资源域的授权信息的证书(credentials)组成。

Authorization = "Authorization" ":" credentials

HTTP访问授权在“HTTP Authenticatiion:Basic and Digest Access Authentication”[43]中描述。如果一个请求被授权并且一个域(realm)被指定,那么这个证书应该对此域里所有的其他请求是有效的(假设在此授权模式下,证书不会根据一个激发值或利用一个同步的时钟而变化)。

当一个共享缓存(shared cache)(见13.7节)接收一个请求,并且此请求包含一个Authorization头域时,那么它不能返回此请求相应的响应来回复任何其他的请求,除非下面指定的异常发生:

如果此响应包含“s-maxage”缓存控制指令,那么此缓存可能会利用那个响应来响应一个后续的请求。但是(如果指定的age过期了)一个代理缓存必须首先通过源服务器来重验证此响应,利用新请求里的Authorization请求头域去让源服务器授权此新请求。(这是为“s-maxage=0”定义的行为。)如果响应包含“s-maxmax=0”,那么代理必须总是重验证此响应在重利用它之前。

如果此响应包含“must-revalidate”缓存控制指令,那么缓存可能会利用那个响应来响应一个后续的请求。但是如果此响应是陈旧的,那么所有缓存必须首先通过源服务器重验证那个响应,利用新请求里的Authorization请求头域去让源服务器去授权此新请求。

如果响应包含共有缓存指令,那么它可能会响应任何后续的请求。

14.9  Cache-Control

Cache-Control常用头域被用于指定指令,此指令必须被在请求/响应链上的所有缓存机制遵守。这些指令指定防止缓存干涉请求或响应的行为。这些指令经常覆盖缺省的缓存算法。缓存指令是单方向的,因为请求中指令的存在并不意味着响应中也会有同样的指令。

请注意HTTP/1.0缓存可能并不实现Cache-Control,而是只实现Pragma: no-cache(参见14.31节)。

代理或网关应用程序必须让缓存指令通过不管这些指令对自己的影响,因为这些指令可能对请求/响应链上的所有接收者都适用。不可能为一个特定的缓存指定一个缓存指令。

Cache-Control = "Cache-Control" ":" 1#cache-directive

cache-directive = cache-request-directive

| cache-response-directive

cache-request-directive =

"no-cache" ; Section 14.9.1

| "no-store" ; Section 14.9.2

| "max-age" "=" delta-seconds ; Section 14.9.3, 14.9.4

| "max-stale" [ "=" delta-seconds ] ; Section 14.9.3

| "min-fresh" "=" delta-seconds ; Section 14.9.3

| "no-transform" ; Section 14.9.5

| "only-if-cached" ; Section 14.9.4

| cache-extension ; Section 14.9.6

cache-response-directive =

"public" ; Section 14.9.1

| "private" [ "=" <"> 1#field-name <"> ] ; Section 14.9.1

| "no-cache" [ "=" <"> 1#field-name <"> ]; Section 14.9.1

| "no-store" ; Section 14.9.2

| "no-transform" ; Section 14.9.5

| "must-revalidate" ; Section 14.9.4

| "proxy-revalidate" ; Section 14.9.4

| "max-age" "=" delta-seconds ; Section 14.9.3

| "s-maxage" "=" delta-seconds ; Section 14.9.3

| cache-extension ; Section 14.9.6

cache-extension = token [ "=" ( token | quoted-string ) ]

当指令不伴有1#field-name参数出现时,该指令适用于整个请求或响应。当这样一个指令伴有一个1#field-name参数时,它仅应用于被命名的头域,而不能应用于请求或响应的其他部分。这一机制支持可扩展性;HTTP协议将来的版本的实现可以通过将指令应用于HTTP/1.1中未定义的头域。

缓存控制指令可分为如下几类:

-          对什么是可缓存的限制;这可能只由源服务器指定。

-          对什么能被缓存保存的限制;这可由源服务器或用户代理指定。

-          对基本过期机制的改进;这可能由源服务器或用户代理指定。

-          对缓存重验证及重载的控制;这可能仅由用户代理指定。

-          对实体传输的控制

-          缓存系统的扩展。

 

14.9.1什么是可缓存的

缺省情况下,若请求方法、请求头域和响应状态码指明了响应为可缓存的,则此响应就是可以缓存的。13.4节总结了可缓存性的这些缺省情况。下列缓存控制响应指令(Cache-Control response deirctives)允许源服务器覆盖缺省的响应可缓存性:

public

  指明响应响应可以被任何缓存保存,即便该响应通常是不可缓存的或该响应只被一个非共享缓存保存的情况下。(参见14.8节,关于Authorization头域的更多详述。)

private

表明响应消息的部分或所有部分是为一个用户准备的并且不得被共享缓存保存。这使源服务器可以申明响应的特定部分是针对一个用户,并且对其他用户的请求而言不是有效的响应。一个私有(非共享)缓存可以缓存此响应。

注:单词private的使用仅用来控制响应在何处可被缓存,而不能保证消息内容的私有性。

no-cache

   如果no-cache缓存控制指令没有指定一个field-name,那么一个缓存不能利用此响应在没有通过源服务器对它进行成功的重验证的情况下去满足后续的请求。这允许源服务器去防止响应被缓存保存,即使此缓存已经被设置能返回给客户端请求一个陈旧的响应。

若no-cache缓存控制指令指定一个或多个field-name,那么一个缓存可以利用此响应去满足后续的请求,但这要受限于对缓存的任何其它限制。然而,指定的filed-name必须不能在后续请求的响应里被发送如果此响应没有在源服务器那里得到成功重验证的情况下。这允许源服务器能防止缓存重利用响应里的某些头域,但仍然可以允许缓存响应的剩余部分。

注意:大多数HTTP/1.0缓存将不能识别或遵循这个指令。

14.9.2什么能被缓存保存

no-store

no-store缓存控制指令的目的在于防止无意的泄露或保留了敏感信息(比如存放在备份磁带的信息)。 no-store缓存控制指令应用于整个消息,并且可以在响应里或在请求里被发送。如果在请求里被发送,一个缓存不能保存此请求或此请求响应的任何部分。如果在响应里被发送,一个缓存不能保存此响应或引起此响应请求的任何部分。此缓存控制指令能应用于非共享缓存和共享缓存。“不能保存”在这个上下文里(context,译注:也可以叫背景)的意思是指缓存不能有意的把信息保存在非易失性存储里,而且必须尽力去删除易失性存储上的信息当它转发完毕后。

即使当此指令在一个响应里时,用户也可能会显示地在缓存系统之外保存这个响应(例如,利用一个“另存为”对话框)的地方。历史缓存(译注:见13.13节)可能保存这个响应作为它们正常操作的一个部分。

此指令的目的是为了满足某些用户声明的需求,还有就是给那些对偶然信息发布(这通过未预料地对缓存数据组织的访问)比较在意的作者也提供方便。在一些情况下,利用此缓存控制指令可能会增强隐私,但是我们注意到它并不是在任何情况下都是可信任的或都是能充分地保护隐私。特别是,恶毒得或者有损害的缓存可能不能识别到或遵循此指令,并且网络通信随时也容易受到窃听。

14.9.3对基本过期机制的改进

实体的过期时间(译注:这里的过期时间也就是“显示过期时间”,见13.3.1里关于“显示过期时间”的说明)可由源服务器利用“Expires”头域(参见14.21节)指定。 或者,它也可以在响应里利用max-age缓存控制指令指定。当max-age缓存控制指令出现在一个缓存的响应里的时候,如果此缓存的响应当前年龄(current age,译注:见13.2.3节关于current age的定义)比假如一个新的请求此时去请求那个资源而得到响应里的age值(以秒为单位)要大,那么此缓存的响应就是陈旧的(stale)。对在一个响应里应用max-age缓存控制指令意味着此响应是可缓存的(也就是说“公有的”)除非更多其他的具有限制性的缓存控制指令出现在响应里。

若响应同时含有Expires头域和max-age缓存控制指令,那么max-age缓存控制指令应该覆盖Expires头域,即使Expires头域更具限制性。此规则允许源服务器对一个给定的响应提供一个更长的过期时间给HTTP/1.1缓存(或以后的版本),这对比HTTP/1.0缓存来说。这个规则可能会很有用,如果某个HTTP/1.0缓存不合适地计算了年龄或过期时间由于不同步的时钟。

许多HTTP/1.0缓存实现可能会把响应里小于或等于该响应里Date头域值的Expires头域值看成与“no-cache”缓存响应控制指令(Cache-Control response directive)等效。如果一个HTTP/1.1缓存接收到这样一个响应,并且此响应没有包含一个Cache-Control头域,它应该把此响应看成一个不能缓存的,这是为了保持和HTTP/1.0服务器兼容。 

注意:一个源服务器可能希望把一个相对新的HTTP缓存控制特性,例如“private”缓存控制指令,用在一个存有旧版本缓存的网络上,而且此旧版本缓存不能理解此特性。源服务器应该需要把新特性和响应里值小于或等于Date值的Expires头域联合起来,这样以便防止旧版本的缓存不合适的保存此响应。

s-maxage

   如果一个响应包含一个s-maxage缓存控制指令,那么对于一个共享缓存(不能对私有缓存)来说,s-maxage指定的值将会覆盖max-age缓存控制指令或Expires头域。s-maxage缓存控制指令照样意指proxy-revalidate缓存控制指令(见14.9.4节)的语义,也就是说,此共享缓存不能利用此缓存项在它变旧后,在没有通过源服务器首先重验证它的情况下,去响应后续的请求。s-maxage缓存控制指令总是被私有缓存忽略。

注:大多数不遵循此规范的老版本缓存没有实现任何缓存控制指令。 一个源服务器如果希望利用一个缓存控制指令去限制(但不能阻止)遵循HTTP/1.1的缓存去进行缓存处理,那么它可能会采用max-age控制指令去覆盖Expires头域,并且它会承认HTTP/1.1以前版本的缓存不会去观察max-age缓存控制指令。

其它缓存控制指令允许一个用户代理(user agent)去改变基本的过期机制。这些指令可能会被指定在请求里:

max-age

  表明客户端愿接受一个这样一个响应,此响应的年龄不大于客户端请求里max-age指定时间(以秒为单位)(译注:如果大于的话,表明此响应是陈旧的)。除非max-stale缓存控制指令也包含在响应里,否则客户端是不能接收一个陈旧响应的。

min-fresh

表明客户端愿接受一个这样的响应,其保鲜寿命不小于其响应当前年龄(译注:current age,见13.2.3节关于current_age的定义)与客户端请求里的min-fresh指定时间之和(以秒为单位)。也就是说,客户端想要一个响应至少在min-fresh指定的时间内是保鲜的。

max-stale

  表明客户端愿接受已经过期的响应。 若客户端请求里为max-age指定了一个值,则表明客户端愿接受过期时间不超过它在max-stale里指定秒数的响应。若max-age未指定一个值,则客户端愿接受任意年龄的陈旧响应。

如果缓存返回了一个陈旧响应,这是由于max-stale缓存控制指令出现在请求里,或由于此缓存被设置成能覆盖响应的过期时间,那么此缓存必须把一个Warning头域放进这个陈旧响应里,此Warning头域里应该是110警告码(响应是陈旧的)。

一个缓存可以被设置为可以不需要验证就可以返回陈旧的响应,但这不应与任何“必须”等级关于缓存验证(例如,一个“must-revalidate”缓存控制指令)的要求冲突。

若新请求与缓存项都包含一个“max-age”缓存控制指令,那么取两个值的小者去为此请求决定缓存项的保鲜程度。

14.9.4缓存重验证和加载控制(Cache Revalidation and Reload Controls)

有时,用户代理可能希望或出于需要,坚持想让一个缓存通过源服务器去重验证它的缓存项,或者从源服务器那里重新加载它的缓存项。end-to-end重验证可能会有必要的,如果缓存或源服务器已经估计了缓存响应(cached response)的过期时间。end-to-end重载可能是有必要的,如果缓存项由于某原因已经变得陈旧了。

end-to-end重验证可能被请求:当客户端没有本地缓存副本,在这种情况下,我们称它为“没指定的end-to-end重验证(unspecified end-to-end revalidation)”;当客户端有本地缓存副本,在这种情况下,我们称它为“指定的end-to-end重验证(specific end-to-end revalidation)”。

客户端能指定下面三种动作,利用缓存控制请求指令(Cache-Control request directives):

end-to-end reload

请求包括“no-cache”缓存控制指令,或为了与HTTP/1.0客户端兼容的“Pragma: no-cache”缓存控制指令。头域名不能被包含在no-cache缓存控制指令里。服务器不能利用一个缓存副本来响应这样一个请求。

specific end-to-end revalidation

这样的请求包含一个“max-age=0”缓存控制指令,它强制每个途径源服务器的缓存去通过下一个缓存或服务器来重验证它所拥有的缓存项(如果有的话)。此初始请求包含一个带有客户端当前验证器的缓存验证条件。

unspecified end-to-end revalidation

这样的请求包含一个“max-age=0”缓存控制指令,它强制每个途径源服务器的缓存去通过下一个缓存或服务器来重验证它所拥有的缓存项(如果有的话)。此初始请求不包含一个缓存验证条件;沿着路径上的第一个缓存(如果有的话),如果它拥有那个资源的一个缓存项,那么此缓存会包含一个带有缓存当前验证器的缓存验证条件。

max-age

当一个中间缓存被一个max-age=0的缓存控制指令强迫去重验证它的缓存项,并且客户端已经在请求里包含了它拥有的验证器,此验证器可能不同于当前缓存项里保存的验证器。在这种情况下,缓存应该在不影响语义透明性的情况下利用两个验证器中的一个去执行请求。

然而,验证器的选择可能会影响性能。最好的办法对中间缓存来说,就是当执行请求时利用它自己的验证器。如果服务器以303(没有改变)回复,那么此缓存能返回一个它自己的当前已经验证了的副本给客户端同时以一个200(OK)状态码。如果服务器以一个新实体和一个新的缓存验证器来回复请求,那么此中间缓存能把返回的验证器同客户端请求里的验证器作比较,这通过利用一个强比较方法。如果客户端的验证器和源服务器的相等,那么此中间缓存器只是简单的返回304(没有改变)响应。否则,它返回一个新的实体并且状态码是200的响应。

如果一个请求包含一个no-cache缓存控制指令,那么它不应该min-fresh,max-stale,或max-age缓存控制指令。

only-if-cache

   在一些情况下,例如糟糕的网络连接,一个客户端可能希望一个缓存只返回它当前保存的响应,并且不需要通过源服务器对其进行重新加载或重验证。如果这样作客户端可能会包含一个only-if-cached缓存控制指令在请求里。如果缓存接收了这样的指令,那么它应该利用一个与请求所要求的缓存项去响应,或者以504(网关超时)状态码响应。然而,如果一组缓存作为一个统一的系统来操作,并且有非常好的内部连接,那么这个请求可能会转发到缓存组的内部。

must-revalidate

   由于一个缓存可能被设置去忽略服务器指定的过期时间,并且又由于一个客户端请求可能包含一个max-stale缓存控制指令(它只有一个小影响),所以此协议照样包含一个让源服务器强迫缓存项被重验证的机制。当must-revalidate缓存控制指令出现在响应里并被一个缓存接收后,此缓存不能利用此缓存项,如果在它变得陈旧并且没有通过源服务器对它进行重验证的情况下,去响应一个后续的请求。(也就是说,如果(基于源服务器的Expires或max-age值)缓存响应是陈旧的,那么,此缓存每次必须进行end-to-end重验证)

   must-revalidate缓存控制指令对某个协议特性的可信赖性操作要有必要支持。在所有情况下,一个HTTP/1.1缓存必须遵循must-revalidate缓存控制指令;特别地,如果此缓存不能直接和源服务器通信,那么它必须产生一个504(网关超时)响应。

   服务器应该发送must-revalidate缓存控制指令,只有在客户端或缓存对那个实体的重验证请求的操作失败的时候,例如一个不动声息的没有执行的金融事务。接收端不能采取任何违反此缓存控制指令的自动的行为,并且不能自动地提供一个被验证无效的实体副本如果此副本通过源服务器重验证失败(译注:验证失败说明缓存里保存的副本通过源服务器验证是无效的;验证成功说明缓存里保存的副本通过源服务器验证是有效的,它可以用来响应后续的请求)。

   尽管这不被推荐,用户代理(user agent)如果在糟糕的网络连接限制下,可能会违反此缓存控制指令,但是,如果这样的话,它必须显示地去警告用户这是一个没有验证的响应,而且用户户代理还应该需要用户的确认信息。

proxy-revalidate

   proxy-revalidate缓存控制指令和must-revalidate缓存控制指令有相同的语义,除了它并不能应用于非共享的用户代理的缓存。它能被用于一个已经被授权请求的响应,去允许用户的缓存能保存或者过后能返回此响应而不需要去重验证它(因为它已经被那个用户授权了一次),但是服务于多个用户的代理仍然需要每次去重验证它(这是为了保证每个用户已经被授权)。注意这样的授权响应照样需要public缓存控制指令,这是为了允许他们完全能被缓存。

14.9.5 No-Transform缓存控制指令

no-ransform

中间缓存(代理)的实现者们已经发现转换某个实体主体的媒体类型转是很有用的。一个非透明代理可能,例如,会在不同图像格式之间进行转换,这是为了节约空间或在低速的连接上减少通信流量。

然而,当这些转换应用于某些应用的实体主体时,会引发严重的运作方面的问题。比如,医学图象应用,科学数据分析和端到端认证都依赖于接收到的实体主体与原实体主体一比一的关系。

所以,如果消息包括了no-ransform缓存控制指令, 那么中间缓存或代理就不应该改变13.5.2节中列出的头域。这意味着缓存或代理不得改变由这些报头定义的实体主体的任何方面,包括实体主体本身的值。

14.9.6缓存控制扩展(Cache control Extendions)

Cache-Control头域可通过一个或多个cache-extension标记的使用来实现其扩展。其中每一标记都赋予一可选的值。 信息扩展(那些无须改变缓存机行为的)可以不经改变其它缓存控制指令的语义而添加。行为扩展是通过修改现有缓存控制指令的基本行为来实现的。 新缓存控制指令与标准缓存控制指令都被提供,以至于不理解新缓存控制指令的应用程序会缺省地采用标准缓存控制指令规定的行为,而那些理解新指令的应用程序则将其看做修改了标准缓存控制指令的要求。这样,缓存控制指令的扩展可以在无须改变基本协议的情况下就能够实现。

这一扩展机制依赖于这样一个HTTP缓存,此缓存遵从所有缓存控制指令的缓存,遵从某些扩展,而且会忽略所有它不能理解的缓存控制指令。

例如,考虑一个假想的名为“community”的新的缓存响应控制指令,此指令被看成是对private缓存控制指令的修饰。我们定义这个新的缓存控制指令以表明:除了非共享缓存能保存此响应之外,还有在community里以它值命名的社区,只有在此社区里的成员所共享的任何缓存才能保存此响应。例如,如果一个源服务器希望允许UCI社区里的成员在他们共享缓存里可以使用一个私有响应,那么此源服务器应该包含:

Cache-Control: private, commuity="UCI"

一个见到此头域的缓存将会正确的操作,即使此缓存不能理解这个community缓存扩展,因为缓存照样能看到并且能理解private缓存控制指令所以这样能导致缺省的安全行为。

14.10 Connection

Connection常用头域允许发送者指定某一特定连接中的选项,这些选项不得由代理(proxy)在以后的连接中传送。

Connection头域遵循如下语法:

   Connection = “Connection” “:” 1#(connection-token)

   connection-token = token

HTTP/1.1代理必须在转发报文之前解析Connection头域,然后针对此头域中每一个connection-token,从报文中移开所有与connection-token里同名的头域。 连接选项是由Connect头域中的connection-token指明的,而非任何对应的附加的头域,因为这些附加头域在缺少与连接选项相关的参数时可能无法被传送。

Connect头域里列出的消息头域不得包含end-to-end头域,例如Cache-Control头域。

HTTP/1.1定义了"close"连接选项,这是为了让发送者表明在完成响应后连接将被关闭。

例如

Connection:close

表明无论是出现在请求或响应的头域中,都表明连接不应被视为在完成现有请求/响应后是“持续的(persistent)”(参见8.1节)。

不支持持续连接的HTTP/1.1应用程序必须在每一消息中都加上"close"连接选项。

接收到含有Connect头域的HTTP/1.0(或更低版本)消息的系统必须要为每一个connection-token去删除或忽略消息中与之同名的头域。这样做避免了早于HTTP/1.1版本的代理错误地转发这些头域。

14.11 Content-Encoding

“Content-Encoding”实体头域是对媒体类型的修饰。当此头域出现时,其值表明对实体主体采用了何种的内容编码,从而可以知道采用何种解码机制以获取Content-Type头域中指出的媒体类型。Content-Encoding头域主要目的是可以在不丢失下层媒体类型的身份下对文档进行压缩。

Content-Encoding = "Content - Encoding" ":" 1#content-coding

内容编码在3.5节里定义。下面是一个应用的例子:

Content-Encoding:gzip

内容编码(content-coding)是请求URI指定实体的特性。通常,实体主体以内容编码(content-coding)的方式存储,然而只有在此实体主体被呈现给用户之前才能被解码。然而,非透明代理可能会把实体主体的内容编码(content-coding)改成接收端能理解的内容编码(content-coding),除非“no-transform”缓存控制指令出现在消息里。

如果实体的内容编码不是“identity”,那么此响应必须包含一个Content-Encoding实体头域(见14.11节),此头域必须列出不是identity的内容编码。

若实体的内容编码(content-coding)是一个不被源服务器接受的请求消息,则响应必须以415状态码响应(不支持的媒体类型)。

若实体采用多种编码,则内容编码必须在Content-Encdoing头域里列出,而且还必须按他们被编码的顺序列出。额外的关于编码参数的信息可能会在其它的实体头域里提供,这在此规范里没有定义。

14.12 Content-Language

Content-Language实体头域描述了实体面向用户的自然语言。请注意,这不一定等同于实体主体中用到的所有语言。

 Content-Language = “Content-Language” “:” 1#language-tag

语言标签由3.10节定义。Content-Language头域的主要目的在于让用户根据自己喜爱的语言来识别和区分实体。这样,如果实体主体的内容是面向丹麦语言的用户,那么下面的头域是适合的:

Content-Language: da

若未指明Content-Language头域,那么缺省是内容是支持所有不同语言的用户。这既可能意味着发送者认为实体主体的内容与任意自然语言无关,也可能发送者不知此内容该面向何种语言。

要面向多种听众,在Content-Language头域里可列出多种语言。例如,同时用毛里土语和英语发行“Treaty of Waitangi”就可以用下面表示:

Content-Language: mi,en

然而,在实体中有多种语言并不代表此实体一定是为多个国家语言的用户准备的。比如《初学拉丁文》之类的语言启蒙教程,显然是针对英语用户的。这里,合适的Content-Language头域里应只包括“en”。

Content-Language可应用于任意媒体类型 -- 它不限于文本式的文档。

14.13 Content-Length

Content-Length实体头域按十进制或八位字节数指明了发给给接收者的实体主体的大小,或是在使用HEAD方法的情况下,指明若请求为GET方法时应该发送的实体主体的大小。

   Content-Length = “Content-Length” “:” 1*DIGIT

示例:

Content-Length: 3495

除非被4.4节里规定的规则禁止,否则应用程序应该利用此头域指明消息主体(message-body)的传输长度。

任何大于或等于0的Content-Length均为有效值。 4.4节描述了如何判断消息主体的长度,如果一个Content-Length没有在消息里给定。

请注意此头域的含义与MIME中的关于此头域的定义有很大的不同,MIME中,它在content-type类型为“message/external-body”的消息里是可选的。在HTTP中,除非被4.4节里定义的规则被禁用,否则一旦消息的长度要在传送前被确定,就应发送此头域。

14.14 Content-Location

Content-Location实体头域可用来为消息里的实体提供对应资源的位置,当此实体的访问位置和请求URI不是同一位置时。一个服务器应该为响应实体的变量(variant,译注:见1.3节 术语)提供一个Content-Location头域;尤其是在资源有多个对应的实体时,并且这些实体会有各自的位置,可以通过这些位置单独地访问到各个实体,这时服务器应该为一个特定的变量(variant)提供一个Content-Location头域。

   Content – Location = “Content-Location” “:” (absoluteURI | relativeURI)

Content-Location的值同样为实体定义了基URI(base URI)。

Content-Location的值并不能作为源请求URI的替代物;它只能是陈述了请求时对应的特定实体资源的位置。将来的请求也许会用Content-Location里的URI作为请求URI,如果请求期望指定那个特定实体资源的话。

一如果一个实体含有一个Content-Location头域,并且此头域里的URI不同于获得此实体URI,那么缓存不会利用此实体去响应使用了Content-Locaton里URI的后续请求。然而,Content-Location能被用于区分同一个请求资源的多个实体,这在13.6节里描述了。

若Content-Location拥有的是相对URI(relative URI),则此相对URI(relative URI)是相对于请求URI来解析的。

PUT或POST请求中含有Content-Location头域是没有给出定义的;服务器可自由忽略它。

14.15 Content-MD5

如RFC 1864[23]中所定义的,Content-MD5实体头域含有的是实体主体的MD5摘要,这是为了给一个end-to-end消息的实体主体的提供完整性检测。(注:MIC有利于检测实体主体传送中的偶发性的改动,但不一定能防范恶意袭击。)

Content-MD5 = "Content-MD5" ":" md5-digest

MD5-digest=< 由RFC 1864 定义的base64的128位MD5摘要>

Content-MD5头域可由源服务器或客户端生成,用作实体主体的完整性检验。只有源服务器或客户端可生成Content-MD5头域;不得由代理服务器和网关生成,否则会有悖于其作为端到端完整性检验的价值。任何实体正主体的接收者,包括代理和网关,都可检查此头域里的摘要值与接收到的实体主体的摘要值是否相符。

MD5摘要的计算基于实体主体的内容,包括任何应用的内容编码(content-coding),但不包括应用于消息主体的任何传输编码。若接收到的消息具有传输编码,那么传输编码必须在检验Content-MD5值与接收到的实体之前被解除。

这样造成的后果是:摘要完全按照实体主体(entity-body)若未经传输编码(transfer encoding)编码而被以发出的顺序进行逐字节计算得到的。

HTTP 将RFC 1864拓宽到允许对MIME复合媒体类型(如multipart/*,message/rfc822)计算摘要,但这并不改变如前所述的摘要计算方法。

由此产生了一系列影响。复合媒体类型的实体主体可能包含许多body-part,每一个body-part都有它自己的MIME和HTTP头域(包括Content-MD5,Content-Transfer-Encoding,和Content-Encoding头域),如果一个body-part有一个Content-Transfer-Encoding或Content-Encoding头域,那么应该认为此body-part的内容已经应用了此编码,并且认为此body-part被包含在Content-MD5的摘要里是在应用了此编码之后。Transfer-Encoding头域不需要出现在body-part里。



不可在计算或核对摘要之前就将任何其它换行转换为CRLF:实际传输的文本中使用的换行必须原封不动的参与摘要计算。

注:虽然HTTP的Content-MD5的定义和RFC 1864中关于MIME实体主体的完全一样, 但HTTP 实体主体在对Content-MD5的应用上仍然有几处与MIME实体主体有所区别。首先,HTTP不象MIME会用Content-Transfer-Encoding头域,而是会使用Transfer-Encoding和与Content-Encoding头域。 其次,HTTP比MIME更多地使用二进制内容类型,在此种情况下,用于计算摘要的字节顺序也即由类型定义的传输字节的顺序。最后,HTTP允许文本类传输时采用数种换行,而不只是规范的使用CRLF的的标准形式。

14.16 Content-Range

Content-Range实体头域与部分实体主体一起发送,用于指明部分实体主体在完整实体主体里那一部分被采用。 范围的单位(Range unit)在3.12节中定义。

Content-Range = "Content-Range" ":" content-range-spec

content-range-spec = byte-content-range-spec

byte-content-range-spec = bytes-unit SP

byte-range-resp-spec "/"

( instance-length | "*" )

byte-range-resp-spec = (first-byte-pos "-" last-byte-pos)

| "*"

instance-length = 1*DIGIT

除非无法或很难判断,此头域应指明完整实体主体的总长度。星号“*”表示生成响应时的instance-length未知。

与byte-ranges-specifier值(参见14.35.1节)不同的是,byte-range-resp-spec必须只能指明一个范围,并且必须包含首字节和尾字节的绝对位置。

一个带有byte-range-resp-spec的byte-content-range-spec,如果它的last-byte-pos值小于first-byte-pos值,或它的instance-length值小于或等于它的last-byte-pos值,那么就说明是无效的。收到无效的byte-content-range-spec将被忽略,并且任何随其传输的内容都将被忽略。

响应时发送状态码416(请求的范围无法满足)的服务器应该包含一个Content-Range头域,且里面的byte-range-resp-spec的值为“*”。instance-length指明了选定资源的长度。状态码为206(部分内容)的响应不应该包含一个byte-range-resp-sepc为“*”的Content-Range头域。

假定实体共含1234字节,byte-content-range-spec值的例子如下:

. The first 500 bytes:

bytes 0-499/1234

. The second 500 bytes:

bytes 500-999/1234

. All except for the first 500 bytes:

bytes 500-1233/1234

. The last 500 bytes:

bytes 734-1233/1234

当HTTP消息里包含单一范围时,(比如,对单一范围请求的响应,或对一组能无缝相连的范围请求的响应),那么此内容必须跟随一个Content-Range头域,并且还应该包含一个Content-Length头域来表明实际需要被传输字节的长度。例如,

HTTP/1.1 206 Partial content

Date: Wed, 15 Nov 1995 06:25:24 GMT

Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT

Content-Range: bytes 21010-47021/47022

Content-Length: 26012

Content-Type: image/gif

当HTTP报文包含多个范围时(比如,对多个未重叠范围请求的响应),它们会被当作多部分类型的消息来传送。为此目的多部分媒体类型为“multipart/byteranges”,它在附录19.2里介绍了。见19.6.3里关于兼容性的问题描述。

对单一范围请求的响应不得使用multipart/byteranges媒体类型。若对多个范围请求的响应结果为一个单一范围,那么可以以一个multipart/byteranges媒体类型发送并且此媒体类型里只有一个部分(part)。一个客户端无法对multipart/byteranges消息解码,那么它不能在一个请求中请求多个字节范围。

当客户端在一个请求中申请多个字节范围时,服务器应按他们在请求中出现的顺序范围返回他们所指定的范围。

若服务器出于句法无效的原因忽略了字byte-range-spec,它应把请求里的无效范围看成不存在。(正常情况下,这意味着返回一个包含完整实体的200响应。)

如果服务器接收到一个请求,此请求包含一个无法满足的Range请求头域(也即,所有byte-range-spec里的first-byte-pos值大于当前选择资源的长度),那么它将返回一个416响应(请求的范围无法满足)(参见10.4.17节)。

注: 客户端对无法满足Range请求头域不能指望服务器一定返回416(请求的范围无法满足)响应而非200(OK)的响应,因为不是所有服务器都能处理Range请求头域。

14.17 Content-Type

Content-Type实体头域指明发给接收者的实体主体的媒体类型,或在HEAD方法中指明若请求为GET时将发送的媒体类型。

Content-Type = "Content-Type" ":" media-type

媒体类型有3.7节定义。 此头域的示例如下:

Content-Type: text/html; charset=ISO-8859-4

7.2.1节提供了关于确定实体媒体类型方法的进一步论述。

14.18 Date

Date常用头域表明产生消息的日期和时间,它和RFC822中的orig-date语义一样。此头域值是一个在3.3.1里描述的HTTP-date;它必须用RFC1123[8]里的date格式发送。

      Date="Date"":"HTTP-date

举个例子

         Date:Tue,15 Nov 1994 08:12:31GMT

源服务器在所有的响应中必须包括一个日期头域,除了下面这些情况:

如果响应的状态代码是100(继续)或101(转换协议),那么响应根据服务器的需要可以包含一个Date头域。

如果响应状态代码表达了服务器的错误,如500(内部服务器错误)或503(难以获得的服务),那么源服务器就不适合或不能去产生一个有效的日期。

如果服务器没有时钟,不能提供合理的当前时间的近似值,这个响应没必要包括Date头域,但在这种情况下必须遵照 14.18.1节中的规则。

一个收到的消息如果没有Date头域的话就会被接收者加上一个,如果这条消息要被这个接收者缓存或者这条消息需要穿过一个需要日期的协议网关。一个没有时钟的HTTP实现不能在没有重验证响应时去缓存(保存)此响应。一个HTTP缓存,特别是一个共享缓存,应该使用一种机制使,例如NTP[28],去让它的时钟与外界可靠的时钟保持同步。

客户端在包括实体主体(entity-body)的消息中应该包含一个Date头域,例如在PUT和POST请求里,即时这样做是可选的。一个没有时钟的客户端不能在请求中发送Date头域。

一个Date头域中的HTTP-date不应该是一个消息产生时刻之后的日期和时间。它应该表示与消息产生时的日期和时间的最近似值,除非没有办法产生一个合理的精确日期和时间。一个恰当的相当精确的日期和时间。理论上说,日期应该是在实体(entity)产生之前的那一刻,实际上,日期是在不影响其语义值的情况下消息产生期间的任意时刻。

14.18.1没有时钟的源服务器运作

一些源服务器实现可能没有可得时钟。一个没有可得时钟的源服务器不能给一个响应指定Expires或Last-Modified头域值,除非通过一个具有可信赖时钟的系统或用户,把此值与此资源联系在一起。可以给Expires赋予一个过去值,此值为服务器设置时间或此设置时间之前的值。(这允许响应的“pre-expiration”不需要为每个资源保存分离的Expires值)。

14.19 ETag

Etag响应头域提供了请求对应变量(variant)的当前实体标签。与实体标签一起使用的头域由14.24,14.26和14.44。实体标签可用于比较来自同一资源的不同实体。(参见13.3.3节)

Etag =  "Etag" ":" entity-tag

例:

      ETag: "xyzzy"

      ETag: W/"xyzzy"

      ETag: ""

14.20 Expect

Expect请求头域用于指明客户端需要的特定服务器行为。

Expect = "Expect" ":" 1#expectation

expectation = "100-continue" | expectation-extension

expectation-extension = token [ "=" ( token | quoted-string )

*expect-params ]

expect-params = ";" token [ "=" ( token | quoted-string ) ]

一个服务器如果不能理解或遵循一个请求里Expect头域的任何expectation值,那么它必须以合适的错误状态码响应。如果服务器不能满足任何expection,服务器必须以417(期望失败)状态码响应,或者如果服务器对请求遇到其它问题,服务器必须发送4xx状态码。

本头域为将来的扩展被定义成一个扩展的语法。若服务器接收到的请求含有它不支持的expectation-extension,那么它必须以417(期望失败)状态响应。

expectation值的比较对于未引用标记(unquoted token)(包括“100-contine”标记)是而言是不区分大小写的,对引用字符串(quoted-string)的expectation-extension而言是区分大小写的。

Expect机制是hop-by-hop的:即HTTP/1.1代理(proxy)必须返回417(期望失败)响应如果它接收了一个它不能满足的expectation。 然而,Expect请求头域本身是end-to-end头域;它必须要随请求一起转发。

许多旧版的HTTP/1.0和HTTP/1.1应用程序并不理解Expect头域。

参见8.2.3节中100(继续)状态的使用。

14.21 Expires

Expires实体头域(entity-header)给出了在何日何时之后响应即被视为陈旧的。一个陈旧的缓存项不能被缓存(一个代理缓存或一个用户代理的缓存)返回给客户端,除非此缓存项被源服务器验证(或者被一个拥有实体的保鲜副本的中间缓存)。见13.2节关于过期模型的进一步的讨论。

Expires头域的出现并不意味着源资源(译注:存放于源服务器的资源)在Expire指定时间时、之前或之后将会改变或将会不存在。

Expires头域里日期格式是绝对日期(absolute date)和时间,由3.3.1节中HTTP-date定义;它必须是RFC1123里的日期格式:

Expires="Expires " ":"  HTTP-date

使用示例为:

Expires: Thu, 01 Dec 1994 16:00:00 GMT

注:若响应包含一个Cache-Control头域,并且含有max-age缓存控制指令(参见14.9.3节),则此指令覆盖Expires头域。

HTTP/1.1客户端和缓存必须把其他无效的日期格式,特别是包含“0”的日期格式看成是过去的时间(也就是说,“已经过期”)。

为了将响应标为“已经过期”,源服务器必须把Expires头域里的日期设为与Date头域值相等。(参见13.2.4节里关于过期计算的规则。)

为标记响应为“永不过期”,源服务器必须把Expires头域里的日期设为晚于响应发送时间一年左右。HTTP/1.1服务器不应发送超过将来一年的过期日期。

对于缺省不可被缓存的响应而言,除非被Cache-Control头域(见14.9节)指明,否则如果Expires头域里日期值为响应将来的时间,那么就表明此响应是可缓存的。

14.22 From

From请求报头域,如果有的话,应该包含用户代理当前操作用户的email地址。这个地址应该是机器可用的地址,这被RFC 822 [9]里的“mailbox”定义同时也在RFC 1123 [8]里修订了:

    From   = "From" ":" mailbox

    例如:

        From: webmaster@w3.org

头域可以被用于记录日志和作为识别无效或多余请求的资源。他不应该用作不安全形式的访问保护。这个头域的解释是:请求是代表所指定的人执行的,此人应该承担这个方法执行的责任。特别的,机器人代理程序应该包含这个头域,这样此人应该对运行此机器人代理程序负责,并且应该能被联系上如果在接收端出现问题的话。

此头域里的网络email地址是可以和发出请求的网络主机(host)分离的。例如,当一个请求通过一个代理(proxy)时,初始请求发送者的地址应该被使用。

客户端在没有用户的允许是不应该发出From头域的,因为它可能和用户的个人利益或者他们站点的安全政策相冲突。强烈建议在任何一次请求之前用户能取消,授权,和修改这个头域的值。

14.23 Host

Host请求头域说明了正在请求资源的网络主机和端口号,这可以从源URI或引用资源(通常是一个HTTP URL,这在3.3.3节里描述)。Host头域值必须代表源服务器或网关(被源URL指定)的命名授权(naming authority)。这允许源服务器或网关去区分有内在歧义的URLS,例如,拥有一个IP地址的服务器,它的根“/”URL对应有多个主机名。

    Host = "Host" ":" host [ ":" port ] ; 3.2.2节

一个“host”如果没有跟随的端口信息,那么就采用是请求服务的的默认端口(例如,对一个HTTP URL来说,就是80端口)。例如,一个对源服务器http://www.w3.org/pub/WWW/的请求,可以用下面来表示:

   GET /pub/WWW/HTTP/1.1

   Host: www.w3.org

一个客户端必须在所有HTTP/1.1请求消息里包含一个Host头域。如果请求URI没有包含请求服务的网络主机名,那么Host头域必须给一个空值。一个HTTP/1.1代理必须确保任何它转发的请求消息里必须包含一个合适的Host头域,此头域指定了代理请求的服务地址。所有基于网络的HTTP/1.1服务器必须响应400(坏请求)状态码,如果请求消息里缺少Host头域。

见5.2和19.6.1.1节里有针对Host头域的其他要求。

14.24 If-Match

If-Match请求头域是用来让方法成为条件方法。如果一个客户端已经从一个资源里获得一个或多个实体(entity),那么他可以通过在If-Match头域里包含相应的实体标签(entity tag)来验证这些实体的一个或多个是否就是服务器当前实体。实体标签(entity tag)在3.11节里定义。这个特性使更新缓存信息只需要一个很小的事务开销。它照样被用于防止通过更新请求对一个资源其它版本的不经意修改。作为一种特殊情况,“*”匹配资源的当前任何实体。

     If-Match = "If-Match" ":" ( "*" | 1#entity-tag )

如果If-Match头域里任何一个实体标签假设与相似的GET请求(没有If-Match头域)返回实体的实体标签相匹配,或者如果给出“*”并且请求资源的当前实体存在,那么服务器可以执行请求方法就好像If-Match头域不存在一样。

服务器必须用强比较方法(见13.3.3)来比较If-Match里的实体标签(entity tag)。

如果没有一个实体标签匹配,或者给出了“*”但服务器上没有当前的实体,那么服务器不能执行此请求的方法,并且返回412响应(先决条件失败)。这种行为是很有用的,特别是在当客户端希望防止一个更新方法(updating method)(例如PUT方法)去修改一个客户端上次请求的但现在已经改变了的资源时,

如果请求在假设在没有If-Match头域的情况下导致了除2XX或412以外的其他状态码响应,那么If-Match头域必须被忽略。

“If-Match: *” 的含义是:此方法将被执行,如果源服务器(或缓存,很可能使用Vary机制,见14.44节)选择的表现形式(representation)存在的话,但是如果此表现形式不存在,那么此方法不能被执行。

如果一个请求想要更新一个资源(例如PUT)那么它可以包含一个If-Match头域来指明:当相应于If-Match值(一个实体标签)的实体不再是那个资源的表现形式时,此请求方法不能被采用。这允许用户表明:如果那个资源已经改变了而他们不知道的话,他们不希望请求成功。

例如:

       If-Match: "xyzzy"

       If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"

       If-Match: *

既有If-Match头域又有If-None-Match或If-Modified-Since头域的请求的结果在本规范没有定义。

14.25 If-Modified-Since

If-Modified-Since请求头域被用来让方法成为条件方法:如果请求变量(variant)自从此头域里指定的时间之后没有改变,那么服务器不应该返回实体;而是应该以304(没有改变)状态码进行响应,同时返回消息不需要消息主体(message-body)。

     If-Modified-Since = "If-Modified-Since" ":" HTTP-date

一个例子是:

       If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT

如果一个GET请求方法含有If-Modified-Since头域但没有Range头域,那么此方法请求的实体只有请求里If-Modified-Since头域中指定日期之后被改变后才能被服务器返回。决定这个算法包括下列情况:

   a)如果请求假设会导致除状态200之外的任何其它状态态码,或者如果If-Modified-Since日期是无效的,那么响应就和正常的GET请求的响应完全一样。比服务器当前时间晚的日期是无效的。

   b)如果自从一个有效的If-Modified-Since日期以来,变量已经被修改了,那么服务器应该返回一个响应同正常GET请求一样。

  c)如果自从一个有效的If-Modified-Since日期以来,变量没有被修改,那么服务器应该返回一个304(没有改变)响应。

这种特征的目的是以一个最小的事务开销来更新缓存信息。

     注释:Range请求头域修改了If-Modified-Since的含义;详细信息见14.35。

     注释:If-Modified-Since的时间是由服务器解析的,它的时钟可能和客户端的不同步。

     注释:当处理一个If-Modified-Since头域的时候,一些服务器使用精确的日期比较方法,而不是稍差的比较方法,来决定是否发送响应304(没有改变)响应。当为缓存验证而发送一个If-Modified-Since头域的时候,为了得到最好的结果,客户端被建议去利用精确的日期字符串,此字符串是以前的Last-Modified头域里被接收的。

     注释:如果客户端,对同一请求,在If-Modified-Since头域中使用任意日期代替Last-Modified头域里得到的日期,那么客户端应该知道这个日期是由服务器通过对时间的理解来解释的。由于客户端和服务器之间时间编码的不同,客户端应该考虑时钟不同步和舍入的问题。如果在客户端第一次请求时刻与后来请求里头域If-Modified-Since指定的日期之间,文档已经改变,这就可能会出现竞争条件,还有,如果If-Modified-Since从客户端得到的日期没有得到服务器时钟的矫正,就有可能出现时钟偏差等问题的。客户端和服务器时间的偏差最有可能是由于网络的延迟造成的。

既有If-Modified-Since头域又有If-Match或If-Unmodified-Since头域的请求的结果在本规范没有定义。

14.26 If-None-Match

If-None-Match头域被用于一个方法使之成为条件的。一个客户端如果有一个或多个从某资源获得的实体,那么他能验证在这些实体中有不存在于服务器当前实体中的实体,这通过在If-None-Match头域里包含这些实体相关的实体标签(entity tag)来达到此目的。这个特性允许通过一个最小事务开销来更新缓存信息。它同样被用于防止一个方法(如,PUT)不经意的改变一个已经存在的资源,而客户端还相信那个资源并不存在时。

作为特殊情况,头域值“*”匹配资源的任何当前实体。

    If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )

如果If-None-Match头域里的任何实体标签(entity tag)假设与一个相似的GET请求(假设没有If-None-Match头域)返回实体的实体标签相匹配,或者,如果“*”被给出并且服务器关于那个资源的任何当前实体存在,那么服务器不能执行此请求方法,除非资源的修改日期不能匹配此请求里If-Modified-Since头域(假设有的话)里提供的日期 。换言之,如果请求方法是GET或HEAD,那么服务器应以304(没有改变)来响应,并且包含匹配实体的相关缓存头域(特别是Etag) 。对于所有其它方法,服务器必须以412(先决条件失败)状态码响应。

13.3节说明了如何判断两实体标签是否匹配。弱比较方法只能用于GET或HEAD请求。

如果If-None-Match头域里没有实体标签匹配,那么服务器可以执行此请求方法就像If-None-Match头域不存在一样,但是必须忽略请求里的任何If-Modified-Since头域。那就是说,如果没有实体标签匹配 ,那么服务器不能返回304(没有改变)响应。

如果假设在没有If-None-Match头域存在的情况下,请求会导致除2xx及304状态码之外响应,那么If-None-Match头域必须被忽略。(见13.3.4节关于假如同时存在If-Modified-Since和If-None-Match头域时服务器的行为的讨论)

“If-None-Match: *”的意思是:如果被源服务器(或被缓存,可能利用Vary机制,见14.44节)选择的表现形式(representation)存在的话,请求方法不能被执行,然而,如果表现形式不存在的话,请求方法是能被执行的。这个特性可以防止在多个PUT操作中的竞争。

     例:

       If-None-Match: "xyzzy"

       If-None-Match: W/"xyzzy"

       If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"

       If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"

       If-None-Match: *

如果一个请求含有If-None-Match头域,还含有一个If-Match或If-Unmodified-Since头域的话,此请求的指向结果在此规范里没有定义。

14.27 If-Range

如果客户端在其所指的缓存中有一个实体的部分副本,并希望其缓存中有此实体的完整副本,那么此客户端应该在一个条件GET(conditional GET)(在GET请求消息里利用了If-Unmodified-Since和If-Match头域,或利用了其中一个)请求里利用Range请求头域(request-header)。然而,如果由于实体被改变而使条件失败,那么此客户端可能会发出第二次请求从而去获得整个当前实体主体(entity-body)。

If-Range头域允许客户端短路(short-circuit)第二次请求。说的通俗一点,这意味着:如果实体没有改变,发送我想要的部分(译注:发送range指明的实体范围);如果实体改变了,那就把整个新的实体发过来。

       If-Range = “if-Range” “:”( entity-tag | HTTP-date)

若客户端没有一个实体的实体标签(entity tag),但有一个最后修改日期(Last-Modified date),它可以在If-Range头域里利用此日期。(服务器通过检查一两个字符即可区分合法HTTP-date与任意形式的entity-tag。)If-Range头域应该只能与一个Range头域一起使用,并且必须被忽略如果请求不包含一个Range头域或者如果服务器不支持子范围(sub-range)操作。

如果If-Range头域里给定的实体标签匹配服务器上当前实体的实体标签(entity tag),那么服务器应该提供此实体的指定范围,并利用206(部分内容)响应。如果实体标签(entity tag)不匹配,那么服务器应该返回整个实体,并利用200(ok)响应。

14.28 If-Unmodified-Since

If-Unmodified-Since请求头域被用于一个方法使之成为条件方法。如果请求资源自从此头域指定时间开始之后没有改变,那么服务器应该执行此请求就像If-Unmodified-Since头域不存在一样。

如果请求变量(variant,译注:见术语)在此头域指定时间后以后已经改变,那么服务器不能执行此请求,并且必须返回412(前提条件失败)状态码。

      If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-日期

   此域的应用实例:

       If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT

如果请求正常情况下(即假设在没有If-Unmodified-Since头域的情况下)导致任何非2xx或412状态码,那么If-Unmodified-Since头域将会忽略。

如果此头域中指定的日期无效,那么此头域会被忽略。

在请求里有If-Unmodified-Since头域并且有If-None-Match或者If-Modified-Since头域中的一个,这种请求的处理结果在此规范中没有被定义。

14.29 Last-Modified

Last-Modified实体头域(entity-header)指明了变量(variant)被源服务器所确信的最后修改的日期和时间。

       Last-Modified = “Last-Modified” “:” HTTP-date

应用示例如下:

Last-Modified : Tue, 15 Nov 1994 12:45:26 GMT

此头域的确切含义取决于源服务器的实现和源资源(original resource)的性质。 对文件而言,它可能仅仅指示文件上次修改的时间。对于包含动态部分的实体而言,它可能是组成其各个部分中最后修改时间最近的那个部分。对数据库网关而言,它可能是记录的最新修改时间戳。对虚拟对象来说,它可能是最后内部状态改变的时间。

源服务器不得发送一个迟于消息产生时间的Last-Modified日期。假如资源最后修改日期可能指示将来的某个时间,此服务器应该用消息产生的时间替换那个日期。

源服务器获得实体的Last-Modified值应该尽量靠近服务器产生响应的Date值。这允许接收者对实体修改时间作出准确的估计,特别是如果实体的改变时间接近响应产生的时间。

HTTP/1.1服务器应该发生Last-Modified头域无能何时。

14.30 Location

Location响应头域被用于为了完成请求或识别一个新资源,使接收者能重定向于Location指示的URI而不是请求URI。对于201(Created)响应而言,Location是请求建立新资源的位置。对于3xx响应而言,Location应该指明了服务器自动重定向资源喜爱的URI。Location头域值由一个绝对URI组成。

       Location = “Location” “:” absoluteURI

一个例子如下:

 Location : http://www.w3.org/pub/WWW/People.html

注: Content-Location头域(14.14节)不同于Location头域,Content-Location头域指定了请求里封装实体的源位置。有可能一个响应即包含location也包含Content-Location头域。在13.10节里有关于一些方法的要求。

14.31 Max-Forwards

Max-Forwards请求头域提供一种机制,那就是利用TRACE(9.8节)和OPTIONS(9.2节)方法去限制代理或网关的数量,这些代理或网关能传递请求到下一个入流(inbound)服务器。这是非常有帮助的,当客户端尝试去跟踪一个好像陷入失败或陷入循环的请求链时。

       Max-Forwards = “Max – Forwards” “:” 1*DIGIT

Max-Forwards值是十进制的整数,它指定了请求消息剩余重定向的次数。

对于一个TRACE或OPTIONS请求,如果包含一个Max-Forwards头域,那么接收此请求的代理或网关必须能在转发(forwarding)此请求之前检查和更新Max-Forwards头域值。如果接收的值为0,那么接收者不能转发此请求;而是,它必须作为最后的接收者响应。如果接收的Max-Forwards值比0大,那么此转发的消息必须包含一个更新了的Max-Forwards头域,更新的值是在接收时的值上减去1。

对本规范定义的所有其它方法以及任何没有明确作为方法定义部分的扩展方法的请求里,Max-Forwards头域可能会被忽略。

14.32 Pragma

Pragma常用头域被用于包含特定执行指令,这些指令可能被应用于请求/响应链中任何接收者。从协议的观点来看,pragma指令指定的行为是可选的;然而,一些系统可能要求行为必须满足指令的要求。

       Pragma               = “Pragma” “:” 1#pragma-directive

       pragma-directive =”no-cache” | extension-pragma

       extension-pragma       =token [ “=” ( token | quoted-string) ]

当no-cache指令出现在请求消息中,应用程序应该转发(forward)此请求到源服务器,即使它拥有此请求响应的缓存副本。pragma指令和no-cache缓存控制指令(见14.9)用相同的语义,并且它为了同HTTP/1.0向后兼容而定义的。当一个no-cache请求发送给一个不遵循HTTP/1.1的服务器时,客户端应该即包含pragma指令,也应该包含no-cache缓存控制指令。

pragma指令必须能穿过代理和网关应用程序,不管对于那些应用程序有没有意义。因为这些指令可能对请求/响应链上的所有接受者有用。不可能为一个特定的接收者定义一个pragma;然而,任何对接收者不相关的pragma指令都应该被接收者忽略。

HTTP/1.1缓存应该把"Pragma:no_cache"当作好像客户端发送了"cache_control:no-cache"。在http中不会有新的pragma指令会被定义。

14.33 Proxy-Authenticate

Proxy-Authenticate响应头域必须被包含在407响应(代理授权)里。此头域值由一个challenge和parameters组成,challenge指明了授权方案,而parameters应用于此请求URI的代理。

       Proxy-Authenticate = "Proxy-Authenticate" ":" 1#challenge

关于HTTP访问授权过程的描述在“HTTP Authentication:Basic and Digest Access Authentication”[43]中介绍了。不像WWW-Authenticate头域,Proxy-Authenticate头域只能应用于当前连接,并且不应该传递给下行(downstrem)客户端。然而,一个中间代理可能需要从请求下行客户端而获得它自己的证书(credentials),这在一些情况下就好像代理正在转发Proxy-Authenticate头域一样。

14.34 Proxy-Authorization

Proxy-Authorization请求头域允许客户端让一个需要授权的代理能给自己(或客户端的用户)授权。Proxy-Authorization头域值由包含用户代理授权信息的证书组成,此授权信息是关于对代理和/或请求资源域来说的。

       Proxy-Authorization = “Proxy-Authorization” “:” credentials

HTTP访问授权过程在“HTTP Authentication: Basic and Digest Access Authentication”[43]中描述。不像Authorization头域,Proxy-Authorization头域只能应用于下一个利用Proxy-Authenticate头域进行授权的输出代理。

14.35 Range

14.35.1字节范围 (Byte Ranges)

既然所有的HTTP实体都以字节序列形式的HTTP消息表示,那么字节范围的概念对任何HTTP实体都是有意义的.(不过并不是所有的客户和服务器都需要支持字节范围操作.。)

HTTP里的字节范围应用于实体主体的字节序列(不必和消息主体一样)。

字节范围操作可能会在一个实体里指定一个字节范围或多个字节范围。

       ranges-specifier = byte-ranges-specifier

       byte-ranges-specifier = bytes-unit "=" byte-range-set

       byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec )

       byte-range-spec = first-byte-pos "-" [last-byte-pos]

       first-byte-pos = 1*DIGIT

       last-byte-pos   = 1*DIGIT

byte-range-spec里的first-byte-pos值给出了一个范围里第一个字节的偏移量.。last-byte-pos值给出了这个范围里最后一个字节的偏移量;也就是说,确定的字节位置必须在实体的范围之内。字节偏移是以0为基准(译注:0代表第一个字节,1代表第二个字节)。

如果存在last-byte-pos值,那么它一定大于或等于那个byte-range-spec里的first-byte-pos,否则byte-range-spec在句法上是非法的。接收者接收到包括一个或多个无效的byte-range-spec值的byte-range-set时,它必须忽略包含那个byte-range-set的头域.。

如果last-byte-pos值不存在,或者大于或等于实体主体的当前长度,则认为last-byte-pos等于当前实体主体长度减一。

通过选择last-byte-pos,客户能够限制获得实体的字节数量而不需要知道实体的大小。

       suffix-byte-range-spec = “-“ suffix-length

       suffix-length = 1*DIGIT

suffix-byte-range-spec用来表示实体主体的后缀,其长度由suffix-length值给出.。(也就是说,这种形式规定了实体正文的最后N个字节。)如果实体短于指定的suffix-length,则使用整个实体主体。

如果一个句法正确的byte-range-set至少包括一个这样的byte-range-spec,它的first-byte-pos比实体主体的当前长度要小,或至少包括一个suffix-length非零的 suffix-byte-range-spec,那么byte-range-set是可以满足的,否则是不可满足的。如果byte-range-set不能满足,那么服务器应该返回一个416响应(请求范围不能满足)。否则,服务器应该返回一个206响应(部分内容)

byte-ranges-specifier(字节-范围-说明符)值的例子(假定实体主体的长度为10000):

-- 第一个500字节(字节偏移量0-499,包括0和499): bytes=0-499

-- 第二个500字节(字节偏移量500-999,包括500和999): bytes=500-999

-- 最后500字节(字节偏移量9500-9999,包括9500和9999): bytes=-500 或 bytes=9500-

-- 仅仅第一个和最后一个字节(字节0和9999): bytes=0-0,-1  

-- 关于第二个500字节(字节偏移量500-999,包括500和999)的几种合法但不规范的叙述:

         bytes=500-600,601-999

         bytes=500-700,601-999

14.35.2范围请求(Range Retrieval Requests)

使用条件或无条件GET方法可以请求一个或多个实体的字节范围,而不是整个实体,这利用Range请求头域,请求返回的结果就是Range头域指示的请求资源实体的范围。

     Range = "Range" ":" ranges-specifier

服务器可以忽略Range头域。然而,.HTTP/1.1源服务器和中间缓存本应该尽可能支持字节范围,因为Range高效地支持从部分传输失败的恢复,并且支持高效地从大的实体中获取部分内容。

如果服务器支持Range头域,并且指定的范围或多个范围对实体来说是适合的:

1.        如果在无条件GET请求里出现Range头域,那么这将会改变返回结果(译注:本来是返回整个实体,但出现Range头域后,就返回了一部分)如果GET请求假设在没有Range头域时被服务器成功处理。换句话说,返回的状态码不是200(ok)而是206(部分响应)。

2.        如果在条件GET(请求里利用了If-Modified-Since和If-None-Match中任意一个或他们两个,或者利用了If-Unmodified-Since和If-Match中的任意一个或他们两个)请求里出现Range头域,那么这将改变返回的结果,如果GET请求假设在没有Range头域时被服务器成功成功并且条件为真。但它不会影响304(没有改变)响应的返回如果条件为假。

某些情形下,除了使用Range头域外,使用If-Range头域(见14.27节)可能更合适。

如果支持范围请求的代理接收了一个范围请求,它会转发(forward)此请求到入流(inbound)服务器,并且接收整个返回实体,但它只是返回给客户的请求的范围。代理将接收的整个响应存储到它的缓存里如果此响应满足缓存分配策略。

14.36 Referer

Referer请求头域,为了对服务器有用,允许客户指定某资源的URI,客户端从此资源获得的请求URI的地址(Referer头域的Referer本应该写成Referrer,出现了笔误)。Referer请求头域允许服务器产生返回到资源的URI链接的列表。它照样允许服务器为维护而跟踪过时或写错的链接。Referer头域不能被发送如果请求URI从一个本身没有URI的资源获得,例如用户从键盘输入。

获得请求URI的资源地址(URI)-为了服务器的利益.Referer请求头允许服务器生成关于到资源的反向连接(back-link)的列表,为了兴趣,记录,优化的高速缓存等等.它也允许追踪过时的或错误类型的连接(link)以便维护.如果请求URI是从一个没有自己的URI的源获得的,如从使用者键盘的输入,那么一定不要发送Referer域.

       Referer   = "Referer" ":" ( absoluteURI | relativeURI )

 例如:

       Referer: http://www.w3.org/hypertext/DataSources/Overview.html
如果Referer头域的域值是相对URI,那么它将被解析为相对于请求URI。URI不能包含一个片段。见15.1.3关于安全的考虑。

14.37 Retry-After

Retry-After响应头域能被用于一个503(服务不可得)响应,服务器用它来向请求端指明服务不可得的时长。此头域可能被用于3xx(重定向)响应,服务器用它来(如web浏览器)指明用户代理再次提交已重定向请求之前的最小等待时间。Retry-After头域值可能是HTTP-date或者也可能是一个响应时间后的十进制整数秒。

       Retry-After = “Retry-After” “:” ( HTTP-date | delta-seconds )

下面是它的两个例子

       Retry-After: Fri,31 Dec 1999 23:59:59 GMT

       Retry-After:120

在后一例子中,延迟时间是2分钟。

14.38 Server

Server响应头域包含了源服务器用于处理请求的软件信息。 此域可包含多个产品标记(3.8节),以及鉴别服务器与其他重要子产品的注释。产品标记按它们的重要性来排列,并鉴别应用程序。

       Server = “Server”

例:

服务器:CERN/3.0 libwww/2.17

若响应是通过代理服务器转发的,则代理程序不得修改服务器响应头域。作为替代,它应该包含一个Via头域(在14.45节里描述)。

注:揭示特定的软件版本可能会使服务器易于受到那些针对已知安全漏洞的软件的攻击。 建议服务器实现者将此域作为可设置项。

14.39 TE

TE请求头域指明客户端可以接受哪些传输编码(transfer-coding)的响应,和是否愿意接收块(chunked)传输编码响应的尾部(trailer)(译注:TE头域和Accept-Encoding头域与Content-Encoding头域很相似,但TE应用于传输编码(transfer coding),而Content-Encoding应用于内容编码(content coding,见3.5节))。 TE请求头域的值可能由包含关键字“trailers” 和/或用逗号分隔的扩展传输编码名(扩展传输编码名可能会携带可选的接受参数的列表)(在3.6节描述)组成。

 TE        = "TE" ":" #( t-codings )

 t-codings = "trailers" | ( transfer-extension [ accept-params ] )

如果出现关键字“trailers”,那么它指明客户端愿意接受(chunked)传输编码响应的尾部(trailer)。 此关键字为传输编码(transfer-coding)值而保留,但它本身不代表一种传输编码。

举例:

       TE: deflate

       TE:

       TE: trailers, deflate;q=0.5

TE请求头域仅适用于立即连接。所以无论何时,只要在HTTP/1.1消息中存在TE头域,连接头域(Connection header filed)(参见14.10节)中就必须指明。

通过TE头域,服务器能利用下述规则来测试传输编码(transfer-coding)是否是可被客户端接受的:

块(chunked)传输编码总是可以接受的(译注:所以不需要在TE头域里指定块(chunked)传输编码,因为请求端总是可以接收块传输编码)。如果在TE头域里出现关键字“trailers”,那么客户端指明它愿意接受块(chunked)传输编码响应里的尾部(trailer)。这意味着客户端或者正在声明所有的下游客户端愿意接收块(chunked)传输编码响应里的尾部(trailer),或者声明它愿意代表下游接收端去尝试缓存响应。

注意:HTTP/1.1并没有定义任何方法去限制块传输编码响应的大小,这是为了方便客户端能缓存整个响应。

只要是出现在TE头域里的传输编码都是可被请求端接受的,除非此传输编码跟随的qvalue值为0(根据3.9节中定义,qvalue为0表明是“不可接受的”(not acceptable)))

如果在TE头域里有指明多个传输编码是可接受的,那么传输编码(transfer-coding)的qvalue值最大的是最容易被被接受的。块传输编码的qvalue值为1。

如果TE头域值是空的或者TE头域没有出现在消息里,那么服务器只能认为块(chunked)传输编码的响应是请求端可以接受的。没有传输编码的消息总是可接受的。

14.40 Trailer

Trailer常用头域值指明了在以块(chunked)传输编码消息里的尾部(trailer)里用到的头域。

                  Trailer = "Trailer" ":" 1#field-name

一个http/1.1消息会包含一个Trailer头域,如果它利用了块(chunked)传输编码并且编码里的尾部(trailer)不为空。这样做是为了使接收端知道块(chunked)传输编码响应消息尾部(trailer)有哪些头域。

如果具有块传输编码的消息,没有Trailer头域存在,则此消息的尾部(trailer)将不能包括任何头域。3.6.1节展示了块传输编码的尾部(trailer)的利用限制。

Trailer头域中指示的消息头域不能包括下面的头域:

.Transfer-Encoding

.Content-Length

.Trailer

 

14.41 Transfer-Encoding

传输译码(Transfer-Encoding)常用头域指示了消息主体(message body)的编码转换,这是为了实现在接收端和发送端之间的安全数据传输。它不同于内容编码(content-coding),传输代码是消息的属性,而不是实体(entity)的属性。

       Transfer-Encoding       = "Transfer-Encoding" ":" 1#transfer-coding

 传输编码(transfer-coding)在3.6节中被定义了。一个例子是:

         Transfer-Encoding: chunked

如果一个实体应用了多种传输编码,传输编码(transfer-coding)必须以应用的顺序列出。传输编码(transfer-coding)可能会提供编码参数(译注:看传输编码的定义,3.6节),这些编码参数额外的信息可能会被其它实体头域(entity-header)提供,但这并没有在规范里定义。

 

许多老的HTTP/1.1应用程序不能理解传输译码(Transfer-Encoding)头域。

14.42 Upgrade

Upgrade常用头域允许客户端指定它支持什么样的附加传输协议,如果服务器会切换到Upgrade指定的协议如果它觉得合适的话。服务器必须利用Upgrade头域于一个101(切换协议)响应里,用来指明将哪个协议被切换了。

       Upgrade = “Upgrade” “:” 1#product

例如,

       Upgrade: HTTP/2.0,SHTTP/1.3, IRC/6.9, RTA/x11

Upgrade头域的目的是为了提供一个从HTTP/1.1到其它不兼容协议的简单迁移机制。这样做是通过允许客户端通知自己期望使用另一种协议来实现的,例如更新版本的HTTP协议,即使当前请求仍然使用HTTP/1.1。使不兼容协议的迁移变得简单,这只需要客户端去发起一个都被支持的协议的请求,并且向服务器指明自己想要使用更好的协议如果可行的话。

Upgrade头域只能应用于切换应用程序层(application –layer)协议,应用程序层协议在传输层(transport-layer)连接之上。Upgrade头域并不意味着协议一定要改变;服务器可以接受并且可以选择。在协议改变后应用程序层(apllication-layer)通信的能力和本质,完全依赖于新协议的选择,尽管在改变协议后的第一次动作必须是对初始HTTP请求(包含Upgrade头域)的响应。

Upgrade头域只能应用于立即连接(immediate connection)。因此,upgrade关键字必须被提供在Connection头域里(见14.10节),只要Upgrade头域呈现在HTTP/1.1消息里。

Upgrade头域不能被用来指定切换到一个不同连接的协议。为这个目的,使用301,302,303重定向响应更合适。

这个规范定义了本协议的名字为“HTTP”,它在3.1节的HTTP版本规则中定义的超文本传输协议家族中被使用。任何一个标记都可被用来做协议名字,然而,只有当客户端和服务器用在同一协议里使用此名字才有用。

14.43 User-Agent

User-Agent请求头域包含关于发起请求的用户代理的信息。这是为了统计,跟踪协议违反的情况,和为了识别用户代理从而为特定用户代理自动定制响应。用户代理应该包含User-Agent头域在请求中。此头域包含多个识别代理和子产品的产品标记(见3.8节)和解释。通常,产品标记按重要程度的顺序排列从而去指定应用程序。

      User-Agent     = "User-Agent" ":" 1*( product | comment )

例子:

       User-Agent: CERN-LineMode/2.15 libwww/2.17b3

14.44 Vary

Vary头域值指定了一些请求头域,这些请求头域用来决定当缓存中存在一个响应是保鲜时缓存是否被允许去利用此响应去回复后续请求而不需要重验证(revalidation)。对于一个不能被缓存或陈旧的响应,Vary头域值用于告诉用户代理选择表现形式(reprentation)的标准。一个Vary头域值是“*”意味着缓存不能从后续请求的请求头域来决定合适表现形式的响应。见13.6节关于缓存如何利用Vary头域。

   Vary = "Vary" ":" ( "*" | 1#field-name )

一个HTTP/1.1的服务器应该包含一个Vary头域于任何可缓存的受限于服务器驱动协商的响应里。这样做是允许缓存合适地解析关于那个资源的将来请求,并通知用户代理那个资源导向地址的出现。一个服务器可能包含一个Vary头域于一个不可缓存的受限于服务器驱动协商的响应里,因为这样做可能为用户代理提供有用的并且响应据此而变化的维度信息。

一个Vary头域值由域名(filed-name)组成,响应的表现形式是基于Vary头域里列举的请求头域来选择的。一个缓存可能会假设为将来请求进行相同的选择,如果Vary头域例举了相同的域名,但必须是此响应在此期间是保鲜的。

Vary头域里的域名并不是局限于本规范里定义的标准请求头域。域名是大小写不敏感的。

Vary域值为”*”意味着不受限于请求头域的非特定参数在选择响应表现形式中起作用 。”*”值不能被代理服务器产生;它可能只能被源服务器产生。

14.45 Via

Via常用头域必须被网关和代理使用,用来指明用户代理和服务器之间关于请求的中间协议和接收者,和源服务器和客户端之间关于响应的中间协议和接收者。它和RFC822[9]里的“Received”头域相似,并且它用于跟踪消息的转发,避免请求循环,和指定沿着请求/响应链的所有发送者的协议能力。

      Via = "Via" ":" 1#( received-protocol received-by [ comment ] )

      received-protocol = [ protocol-name "/" ] protocol-version

      protocol-name     = token

      protocol-version = token

      received-by       = ( host [ ":" port ] ) | pseudonym

      pseudonym         = token

received-protocol指出沿着请求/响应链每一段的服务器或客户端所接收消息的协议版本。protocol-version被追加于Via头域值后面,当消息被转发时。

只要协议是HTTP,那么protocol-name是可有可无的。received-by头域通常是接收的转发服务器的host(主机)和可选的port(端口)号,或接收的转发客户端的host(主机)和可选的port(端口)号。然而,如果真实host(主机)被看作是信息敏感的,那么此主机可能会被别名代替。如果port(端口号)没有被给定,那么它可能被假设为received-protocol的缺省port(端口)号。

Via头域里如果有多个域值,则每个值分别代表一个已经转发消息的代理或网关。每一个接收者必须把它的信息追加到最后,所以最后的结果是按照转发应用程序的顺序来的。

comment(注释)可能被用于Via头域是为了指定接收者代理或网关的软件,这个好比User-Agent和Server头域。然而,Via头域里所有的comment是可选的(译注:可有可无的),并且可以被接收者在转发消息之前移去。

例如,有一个请求消息来自于一个HTTP/1.0用户代理,被发送到代号为“fred”的内部代理,此内部代理利用HTTP/1.1协议转发此请求给一个站点为nowhere.com的公共代理,而此公共代理为了完成此请求通过把它转发到站点为www.ics.uci,edu的源服务器。被www.ics.uci.edu站点接收后的请求这时可能有下面的Via头域:

       Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)

被用作通向网络防火墙的入口的代理和网关在缺省情况下不应该转发host(主机)的名字和端口到防火墙区域里。如果这些信息显示地指定要被传送,那么就应该被传送。如果此信息显示地指定不能被传送,那么任何穿过防火墙而被接收的host(主机)应该用一个合适的别名替换。

为了隐藏组织结构的内部结构需要,一个代理(proxy)可能会在一个Via头域中把相同received-protocal值的项合成一个项。例如,

      Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy

将被折叠成

       Via: 1.0 ricky, 1.1 mertz, 1.0 lucy

应用程序不应该合并多个项,除非他们都在相同组织的控制下并且host(主机)已经被别名代替了。应用程序不能合并不同received-protocaol值的项。

14.46 Warning

Warning常用头域被用于携带额外关于消息的状态或变换的信息而这些信息是不能在消息里反应出来的。这些信息通常被用于去警告来自于缓存操作或来自于应用于消息实体主体转换的关于语义透明性(semantic transparency)的缺少。

Warning头域被用于响应里,这里有如下语法:

       Warning    = "Warning" ":" 1#warning-value

       warning-value = warn-code SP warn-agent SP warn-text

                                             [SP warn-date]

       warn-code = 3DIGIT

       warn-agent = ( host [ ":" port ] ) | pseudonym

                       ; the name or pseudonym of the server adding

                       ; the Warning header, for use in debugging

       warn-text = quoted-string

       warn-date = <"> HTTP-date <">

一个响应可能携带多个Warning头域。

warn-text必须使用对于接收响应的用户来说尽可能能理解的自然语言和字符集。找到用户自能理解的自然语言和字符集,必须基于任何可能的知识,如缓存或用户的位置,请求里的Accept-Language头域,响应里的Content-Language头域,等等。缺省语言是英语,缺省字符集是ISO-8859-1。

如果字符集不是ISO-8859-1,那么它必须利用RFC2047里描述的来在warn-text里进行编码。

Warning头域能被应用于任何消息,然而,一些warn-codes是特定于缓存的,并且能被应用于响应消息。新的Warning头域应该加在任何已存在Warning头域的后面。缓存不能删除任何它接收的消息里的Warning头域。然而,如果一个缓存要去成功验证了一个缓存项,那么它应该移除任何附加在那个缓存项以前的Warning头域除了特定于此Warning code的Warning头域。它然后必须添加任何接收的Warning头域于验证响应里。换句话说,附加的必须是最近的相关于响应的Warning头域。

当多个Warning头域被附加于一个响应里,那么用户代理应该通知用户尽可能多的警告,并且以它们呈现在响应里的顺序。如果用户代理不能通知用户所有的警告,那么用户代理应该按照下面的规则:

-          前面的响应里的警告优于后面响应的警告

-          用户偏爱的字符集的警告优于其它字符集的警告,但这除了warn-codes和warn-agents一致的情况。

产生多个Warning头域的系统应该时刻记住利用用户代理行为来安排警告。

关于警告的缓存行为的要求在13.1.2里描述。

下面是当前定义的warn-codes,每一个warn-code都有一个建议性的以英语表示的warn-text,和它的意思的描述。

110 Response is stale

 无论何时当返回响应是陈旧的时候,必须被包含。

111 Revalidation failed

   如果一个缓存因为尝试去重验证响应失败而返回一个陈旧的响应(由于不能到达服务器),必须被包含。

112 Disconnected operation

   如果缓存在一段时间被有意地断开连接,应该被包含。

113 Heuristic expiration

   如果缓存探索性地选择了一个保鲜寿命大于24小时并且响应的年龄大于24小时时,必须被包含。

199 Miscellaneous warning

   警告文本可能包含任意信息呈现给用户。除了呈现给用户警告,接收警告的系统不能采取任何自动行为。

214 Transformation applied

 如果一个中间缓存或代理采用任何对响应的内容编码(content-coding)(在Content-Encoding头域里指定)或媒体类型(media-type)(在Content-Type头域里指定)的改变变,或响应的实体主体(entity-body)的该变,那么此响应码必须被中间缓存或代理添加,除非此警告码(warning code)已经在响应里出现。

299 Miscellaneous persistent warning

 警告文本应该包含任意呈现给用户的任意信息。接收警告的系统不能采取任何自动行为。

如果一个实现在一个消息里发送多个版本是HTTP/1.0或更早的HTTP协议版本的Warning头域,那么发送者必须包含一个和响应日期(date)相等的warn-date到每一个Warning头域值中。

如果一个实现收到一条warning-value里包含一个warn-date的消息,并且那个warn-date不同于响应里的Date值,那么warning-value必须在保存,转发,或利用消息之前从消息里删除。(这回防止本地缓存去缓存Warning头域的恶果。)如果所有warning-value因为这个原因而被删除,Warning头域必须也要被删除。

14.47 WWW-Authenticate

WWW-Authenticate响应头域必须包含在401(没有被授权)响应消息中。此域值至少应该包含一个callenge,此callenge指明授权方案(译注:有的地方翻译成模式)和适用于请求URI的参数。

WWW-Authenticate =“WWW-Authenticate” “:” 1#challenge

HTTP访问授权过程在“HTTP Authentication: Basic and Digest Access Authentication”[43]里描述。用户代理被建议特别小心去解析WWW-Authenticate头域值,当此头域值包含多个challenge,或如果多个WWW-Authenticate头域被提供且challenge的内容能包含逗号分隔的授权参数的时候。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: