HTTP1.1协议-RFC2616-中文版

转自:http://www.cnblogs.com/k1988/...html

说明前端

本文档规定了互联网社区的标准组协议,并须要讨论和建议以便更加完善。请参考web

“互联网官方协议标准”(STD 1)来了解本协议的标准化状态。本协议不限流传发布。算法

版权声明数据库

Copyright (C) The Internet Society (1999). All Rights Reserved.浏览器

摘要缓存

超文本传输协议(HTTP)是一种为分布式,合做式,超媒体信息系统。它是一种通用的,无状态(stateless)的协议,除了应用于超文本传输外,它也能够应用于诸如名称服务器和分布对象管理系统之类的系统,这能够经过扩展它的请求方法,错误代码和报头[47]来实现。HTTP的一个特色是数据表现形式是可输入的和可协商性的,这就容许系统能被创建而独立于数据传输。 安全

HTTP在1990年WWW全球信息刚刚起步的时候就获得了应用。本说明书详细阐述了HTTP/1.1 协议,是RFC 2068的修订版[33]。服务器

目录(略)网络

1 引论
1.1 目的
超文本传输协议(HTTP)是一种为分布式,合做式,多媒体信息系统服务,面向应用层的 协议。在1990年WWW全球信息刚刚起步的时候HTTP就获得了应用。HTTP的第一个版本叫作HTTP/0.9,是一种为互联网原始数据传输服务的简单协议。由RFC 1945[6]定义的HTTP/1.0进一步完善了这个协议。它容许消息以相似MIME的格式传送,包括有关数据传输的维护信息和关于请求/响应的句法修正。可是,HTTP/1.0没有充分考虑到分层代理,缓存的做用以及对稳定链接和虚拟主机的需求。而且随着不完善的应用程序的激增,HTTP/1.0迫切须要一个新的版本,以便使两个通讯应用程序可以肯定彼此的真实性能。

这里规定的协议叫作擧TTP/1.1".这个协议与HTTP/1.0相比,要求更为严格,以确保各项功能获得可靠实现。

实际的信息系统除了简单的检索外,要求更多的功能性(functionality),包括查找(search),前端更新(front-end update)和注解(annotation)。HTTP容许可扩充的方法集和报头集以指示请求的目的[47]。它是创建在统一资源标识符(URI)[3]提供的地址(URL)[4]和名字(URN)上[20],以指出方法应用于哪一个资源的。消息以相似于一种叫作多用途网络邮件扩展(MIME)[7] 的互联网邮件的格式传送。

HTTP也是用于用户代理之间及代理/网关到其余网络系统的通用通讯协议,这样的网络系统可能由SMTP[16],NNTP[13],FTP[18],Gopher[2]和WAIS[10]协议支持。这样,HTTP容许不一样的应用程序对资源进行基本的超媒体访问。

1.2 要求
本文的关键词"MUST", "MUST NOT", "REQUIRED", "SHALL","SHALL NOT","SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 和 "OPTIONAL"将由RFC 2119[34]解释。

一个应用程序若是不能知足协议提供的一个或多个MUST或REQUIRED等级的要求,是不符合要求的。一个应用程序若是知足全部MUST或REQUIRED等级以及全部SHOULD等级的要求,则被称为非条件遵循(unconditionally compliant)的;若知足全部MUST等级的要求但不能知足全部SHOULD等级的要求则被称为条件遵循的(conditionally compliant)。

1.3 术语
本说明用到了若干术语,以表示HTTP通讯中各参与者和对象扮演的不一样角色。

链接(connection)

为通讯而在两个程序间创建的传输层虚拟电路。

消息(message)

HTTP通讯中的基本单元。它由一个结构化的八比特字节序列组成,与第4章定义的句法相匹配,并经过链接获得传送。

请求(request)

一种HTTP请求消息,参看第5章的定义。

响应(response)

一种HTTP响应消息,参看第6章的定义。

资源(resource)

一种网络数据对象或服务,能够用第3.2节定义的URI指定。资源能够以多种表现方式(例如多种语言,数据格式,大小和分辨率)或者根据其它方面而而不一样的表现形式。

实体(entity)

实体是请求或响应的有效承载信息。一个实体包含元信息和内容,元信息以实体头域(entity-header field)形式表示,内容以消息主体(entity-body)形式表示。在第7节详述。

表现形式 (representation)

一个响应包含的实体是由内容协商(content negotiation)决定的。如第12章所述。有可能存在一个特定的响应状态码对应多个表现形式。

内容协商(content negotiation)

当服务一个请求时选择资源的一种适当的表示形式的机制(mechanism),如第12节所述。任何响应里实体的表现形式都是可协商的(包括出错响应).

变量(variant)

在任何给定时刻,一个资源对应的表现形式(representation)能够有一个或多个(译注:一个URI请一个资源,但返回的是此资源对应的表现形式,这根据内容协商决定)。每一个表现形式(representation)被称做一个变量。使用变量这个术语并非意味着资源(resource)是必须由内容协商决定的.

客户端(client)

为发送请求创建链接的程序.

用户代理(user agent)

初始化请求的客户端程序。常见的如浏览器,编辑器,蜘蛛(网络穿越机器人),或其余的终端用户工具.

服务器(Server)

服务器是这样一个应用程序,它赞成请求端的链接,并发送响应(response)。任何给定的程序都有可能既作客户端又作服务器;咱们使用这些术语是为了说明特定链接中应用程序所担当的角色,而不是指一般意义上应用程序的能力。一样,任何服务器均可以基于每一个请求的性质扮演源服务器,代理,网关,或者隧道等角色之一。

源服务器(Origin server)

存在资源或者资源在其上被建立的服务器(server)被成为源服务器(origin server)。

代理( Proxy)

代理是一个中间程序,它既担当客户端的角色也担当服务器的角色。代理表明客户端向服务器发送请求。客户端的请求通过代理,会在代理内部获得服务或者通过必定的转换转至其余服务器。一个代理必须能同时实现本规范中对客户端和服务器所做的要求。透明代理(transparent proxy)须要代理受权和代理识别,但不修改请求或响应。非透明代理(non-transparent proxy)需修改请求或响应,以便为用户代理(user agent)提供附加服务,附加服务包括组注释服务,媒体类型转换,协议简化,或者匿名过滤等。除非透明行为或非透明行为经明确指出,不然,HTTP代理既是透明代理也是非透明代理。

网关(gateway)

网关实际上是一个服务器,扮演着表明其它服务器为客户端提供服务的中间者。与代理(proxy)不一样,网关接收请求,仿佛它就是请求资源的源服务器。请求的客户端可能觉察不到它正在同网关通讯。

隧道(tunnel)

隧道也是一个中间程序,它一个在两个链接之间充当盲目中继(blind relay)的中间程序。一旦隧道处于活动状态,它不能被认为是此次HTTP通讯的参与者,虽然HTTP请求可能已经把它初始化了。当两端的中继链接都关闭的时候,隧道再也不存在。

缓存(cache)

缓存是程序响应消息的本地存储。缓存是一个子系统,控制消息的存储、取回和删除。缓存里存放可缓存响应(cacheable response)为的是减小对未来一样请求的响应时间和网络带宽消耗。任一客户端或服务器均可能含有缓存,但高速缓存不能被一个充当隧道(tunnel)的服务器使用。

可缓存(cacheable)

咱们能够说响应(response)是可缓存的,若是一个缓存(cache)为了响应后继请求而被容许存储响应消息(response message)的副本。肯定HTTP响应的缓存能力(cacheability)在13节中有介绍。即便一个资源(resourse)是可缓存的,也可能存在缓存是否能利用缓存副本的约束。

第一手的(first-hand)

若是一个响应直接从源服务器或通过若干代理(proxy),而且没有没必要要的延时,最后到达客户端,那么这个响应就是第一手的(first-hand)。

若是响应被源服务器(origin server)验证是有效性(validity)的,那么这个响应也一样是第一手的。

明确过时时间(explicit expiration time)

是源服务器但愿实体(entity)若是没有被进一步验证(validation)就不要再被缓存(cache)返回的时间。

启发式过时时间(heuristic expiration time)

当没有明确终止时间(explicit expiration time)可利用时,由缓存所指定的终止时间.

年龄(age)

一个响应的年龄是从被源服务器发送或被源服务器成功确认的时间点到如今的时间。

保鲜寿命(freshness lifetime)

一个响应产生的时间点到过时时间点之间的长度。

保鲜(Fresh)

若是一个响应的年龄尚未超过保鲜寿命(freshness lifetime),它就是保鲜的.

陈旧(Stale)

一个响应的年龄已经超过了它的保鲜寿命(freshness lifetime),就是陈旧的.

语义透明(semantically transparent)

缓存(cache)可能会以一种语意透明(semantically transparent)的方式工做。这时,对于一个特定的响应,使用缓存既不会对请求客户端产生影响也不会对源服务器产生影响,缓存的使用只是为了提升性能。当缓存(cache)具备语意透明性时,客户端从缓存接收的响应跟直接从源服务器接收的响应彻底一致(除了使用hop-by-hop头域)。

验证器(Validator)

验证器实际上是协议元素(例如:实体头(entity tag)或最后更改时间(last-modified time)等),这些协议元素被用于识别缓存里保存的数据(即缓存项)是不是源服务器的实体的副本。

上游/下游(upstream/downstream)

上游和下游描述了消息的流动:全部消息都从上游流到下游.

向内/向外(inbound/outbound)

向内和向外指的是消息的请求和响应路径:"向内"即"移向源服务器","向外"即"移向用户代理(user agent)".

1.4 整体操做
HTTP协议是一种请求/响应协议。 与服务器创建链接后,客户端以请求方法,URI和协议版本号,而后紧接着跟随一个类MIME(MIME-like)消息,这个类MIME消息包括请求修饰符,客户信息和可能的消息主体。服务器以一个状态行并跟随一个类MIME(MIME-like)消息响应,状态行包含消息的协议版本和成功出错的状态码,类MIME消息包含服务器信息,实体元信息,和可能的实体。HTTP和MIME之间的关系如附录19.4节所阐述。

大部分的HTTP通讯是由用户代理(user agent)开始的,由应用到一个须要源服务器资源的请求构成。最简单的情形,能够经用户代理(UA)和源服务器(O)之间的单一链接(v)完成。

请求链(Request chain)--------------------- ----------à

用户代理(UA)----------------单一链接(v)--------------源服务器(O)

<---------------------------------------响应链(response chain)

当一个或多个中间者在请求/响应链中出现的时候,会出现更复杂的情形。常见的中间者有三种:代理(proxy),网关(gateway)和隧道(tunnel)。代理(proxy)是一种转发代理(a forwarding agent),它接收绝对URI(absoulute url,相对于相对url)请求,重写所有或部分消息,而后把格式化后的请求发送到URI指定的服务器上。网关是一种接收代理(receiving agent),它充当一个层(layer),这个层在服务器之上,必要时它会把请求翻译成为下层服务器的协议。隧道不改变消息而充当两个链接之间的中继点;它用于通讯须要穿过中间者(如防火墙)甚至当中间者不能理解消息内容的时候。

请求链(request chain)----------------------------------------à

UA-----v-----A-----v-----B-----v-----C------------v-----------------O

<----------------------------------------响应链(response chain)

上图显示了用户代理(user agent)和源服务器之间的三个中间者(A,B和C)。整条链的请求或响应将会经过四个单独的链接。这个特性很重要,由于某些HTTP通讯选项可能只能应用于与最近的非隧道邻接点的链接,只能应用于链的端点(end-point)的链接,或者能应用于此链的全部链接。图表尽管是线性的,每一个参与者可能忙于多路同时通讯。例如,B能够接收来自不一样于A的许多客户的请求,而且/或者能够把请求转到不一样于C的服务器,与此同时,它还在处理A的请求。

任何非隧道的通讯成员均可能会采用一个内部缓存(cache)来处理请求。若是沿着链的通讯成员对请求采用了缓存响应,请求/响应链就会大大缩短。下图阐明了一个最终请求响应链,这是在假定B拥有一个来自O(经过C)的之前请求的响应副本,但此响应还没有被UA或A缓存。

请求链(request chain)---------->

UA-----v----------A-----v-----B-----C----O

<---------响应链 (response chain)

并非全部的响应都能有效地缓存,一些请求可能含有修饰符,这些修饰符对缓存动做有特殊的要求。缓存动做和缓存响应的HTTP行为要求将在第13节定义。

实际上,目前万维网上有多种结构和配置的缓存(cache)和代理(proxy)正在被使用。这些系统包括节省带宽的缓存代理(proxy cache),能够广播或多点传送缓存数据的系统,经过CD-ROM分配缓存数据子集的机构,等等。HTTP系统(http system)会被应用于宽带链接的企业局域网中的协做,而且能够经过PDA进行低耗无线的,断续链接的访问。HTTP1.1的宗旨是为了支持各类各样的已经部署的配置,同时引进一种协议结构,让它知足那些须要较高可靠性,即便不能达到较高可靠性的要求,也要也让它至少能够指示故障的网络应用的要求。

HTTP通讯一般发生在TCP/IP链接上。默认端口是TCP 80,不过其它端口也能够使用。这并不妨碍HTTP的实现被应用于互联网(internt)或其它网的协议之上。Http仅仅指望的是一个可靠的传输(译注:HTTP通常创建在传输层协议之上);任何提供这种保证的协议均可以被使用;协议传输数据单元(transport data unit)与HTTP/1.1请求和响应的消息结构之间的映象已经超出了本说明书的范围。

大部分HTTP/1.0的实现都是针对每一个请求/响应交换产生一个新的链接。而http/1.1中,一个链接能够被用于一个或更多请求/响应交换,虽然链接可能会由于各类缘由中断(见第8.1节)。

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

3 协议参数
3.1 HTTP版本
HTTP使用一个“<major>.<minor>”数字模式来指明协议的版本号。协议的版本号是为了让发送端指明消息的格式和它的能力,这是为了进一步的HTTP通讯,而不只仅是得到通讯的特征。协议版本是不须要修改的,当消息组件的增长不会影响通讯行为或着只增长了扩展的域值。<minor>数字是递增的,当协议会由于添加一些特征而作了修改的时候。但这些变化不会影响一般的消息解析算法,可是它会给消息添加语意(semantic)而且会暗示发送者具备额外的能力。<major>数字也是不断递增的,当协议的消息格式每次发生变化时。

HTTP消息的版本在HTTP-Version域被指明,HTTP-Version域在消息的第一行中。

HTTP-Version = "HTTP" "/" 1DIGIT "." 1DIGIT

注意major和minor数字必须被当作两个独立整数,每一个整数均可以递增,而且能够增大到大于一位数的整数,如HTTP/2.4比HTTP/2.13低,而HTTP/2.4又比HTTP/12.3低。前导0必须被接收者忽略而且不能被发送者发送。

一个应用程序发送请求或响应消息,若是请求或响应消息里的HTTP-Version是”HTTP/1.1”,那么此应用程序必须条件遵循此协议规范。最少条件遵循此规范的应用程序应该把”HTTP/1.1”包含在他们的消息里,而且对任何不兼容HTTP/1.1的消息必须这么作。关于什么时候发送特定的HTTP-Version值的细节,参见RFC2145。

应用程序的HTTP版本是应用程序最少条件遵循的最高HTTP版本。

代理(proxy)和网关(gateway)应用程序须要被仔细对待,当转发(forwarding)消息的协议版本不一样于代理或网关应用程序的协议版本。由于消息里协议版本说明了发送者处理协议的能力,因此一个代理/网关千万不要发送一个高于该代理/网关应用程序协议版本的消息。若是代理或网关接收了一个更高版本的消息,它也必需要下降请求的版本,要么以一个错误响应,要么切换到隧道行为(tunnel behavior)。

因为自从RFC 2068[33]发布后,产生了与HTTP/1.0代理(proxy)的互操做问题,因此缓存代理(caching proxy)必须能改变请求(request),使请求能到达他们能支持的最高版本,但网关(gateway)能够这么作也能够不这么作,而tunnel不能这么作。代理(Proxy)/网关(gateway)的响应(Response)必须和请求(request)的HTTP版本的major数字相同。

注意:在HTTP版本间的转换可能包含头域(header field)的改变,而这些改变会可能会根据HTTP版本而被要求或被拒绝。

3.2 统一资源标识符(URI)
URIs的许多名字已为人所知:WWW地址,通用文档标识符,通用资源标识符[3],以及后来的统一资源定位器(URL)[4]和统一资源名称(URN)[20]。就HTTP而言,统一资源定位器只是格式化的字符串,它经过名称,地址,或任何别的特征识别资源。

3.2.1通常语法
根据使用的背景,HTTP里的URI能够表示成绝对(absoulute)形式或相对形式(相对于已知的URL)。两种形式的区别是根据这样的事实:绝对URI老是以一个方案(scheme)名做为开头,其后是一个冒号。关于URL更详尽的信息请参看"统一资源标识符(URI):通常语法和语义",RFC 2396 [42](代替了RFCs 1738 [4]和RFC 1808 [11])。本规范采用了RFC 2396里的"URI-reference","absoluteURI","relativeURI","port","host","abs_path","rel_path",和"authority"的定义格式。

HTTP协议不对URI的长度做事先的限制,服务器必须可以处理它们资源的URI,而且应该可以处理无限长度的URI,这种无效长度的URL可能会在客户端以GET形式的请求产生。服务器应该返回414状态码(此状态码表明Request-URI太长),若是服务器不能处理太长的URI的时候。

注:服务器在依赖大于255字节的URI时应谨慎,由于一些旧的客户或代理实现可能不支持这些长度。

3.2.2 http URL
经过HTTP协议,http方案(http scheme)被用于定位网络资源(resourse)的位置。本节定义了这种方案的语法和语义。

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

若是端口为空或未给出,就假定为80。语义即:已识别的资源放在服务器上,在那台主机的那个端口上监听TCP链接。这时资源的请求的URI为绝对路径(5.1.2节)。不管什么可能的时候,URL里使用IP地址都是应该避免的(参看RFC 1900 [24])。若是绝对地址(abs_path)没有出如今URL里,那么应该给出"/"。若是代理(proxy)收到一个主机(host)名,可是这个主机名不是全称的域名(fully quanlified domain name),则代理应该把它的域名加到主机名上。若是代理(proxy)接收了一个全称的域名,代理没必要改变主机。

3.2.3 URI 比较
当比较两个URI是否匹配时,客户应该对整个URI比较时应该区分大小写,而且一个字节一个字节的比较。 但下面有些特殊状况:

  • 一个为空或未给定的端口等同于URI-refernece(见RFC 2396)里的默认端口;
  • 主机(host)名的比较必须没必要分大小写;
  • 方案(scheme)名的比较必须是不区分大小写的;
  • 一个空绝对路径(abs_path)等同于"/"。

除了"保留(reserved)"和"不安全(unsafe)"字符集里的字符(参见RFC 2396 [42]) ,其它字符都等效于它们的"%HEXHEX"编码.

例如,如下三个URI是等同的:

http://abc.com:80/~smith/home.html

  http://ABC.com/%7Esmith/home.html

  http://ABC.com:/%7esmith/home.html

3.3 日期/时间格式(Date/Time Formats)
3.3.1完整日期 (Full Date)
HTTP应用曾经一直容许三种不一样日期/时间格式:

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标准提出来的,它是一个国定长度的,由RFC 1123 [8](RFC 822[9]的升级版本)定义的一个子集。第二种格式使用比较广泛,可是基于废弃的RFC 850 [12],而且没有年份。若是HTTP/1.1客户端和服务器解析日期,他们必须能接收全部三种格式(为了兼容HTTP/1.0),可是它们只能产生RFC 1123里定义的日期格式来填充头域(header field)用到日期的地方。

注:日期值的接收者被鼓励能健壮的接收可能由非HTTP应用发来的日期值,例若有时能够经过代理(proxy)/网关(gateway)向SMTP或NNTP得到或转发消息。

全部的HTTP日期/时间都必须以格林威治时间(GMT)表示。对HTTP而言,GMT彻底等同于UTC(世界协调时间)。前两种日期/时间格式里包含“GMT”,它是时区的三个字面的简写,而且当读到一个asctime格式时必须先被假定是GMT时间。HTTP日期(HTTP-date)区分大小写,不能包含一个额外的LWS,除非此LWS做为在下面的Http-date语法中指定的SP。

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对日期/时间格式的要求仅仅应用在协议的消息(译注:原文是protocol stream,便于理解这里译做消息)里。客户和服务器没必要把这种格式应用于用户呈现(user presentation),请求记录日志,等等。.

3.3.2 Delta Seconds
一些HTTP头域(header field)容许用整数秒表示时间值,整数秒用十进制表示,此整数秒表示消息被接收后时间。

delta-seconds = 1*DIGIT

3.4 字符集
HTTP使用术语"字符集"的定义,这和MIME中所描述的是同样.

本文档中的术语"字符集"涉及到一种方法,此方法是用一个或多个表将一个节序列转换成一个字符序列(译注:从这里来看,这应该是一种映射关系,表保存了映射关系)。注意反方向的无条件转换(译注:从一个字符序列到一个字节序列的转换)是不须要的,由于并非全部的字符都能在一个给定的字符集里获得,一个字符集可能提供多个字节序列表征一个特定的字符。这个定义是为了容许不一样种类的字符编码从单一简单表映射(如US-ASCII)到复杂表的转换方法如ISO-2022技术用到的。然而,与MIME字符集名字相关的定义必需要充分说明从字节到字符的映射。特别的,使用外部轮廓信息来精确肯定映射是不容许的.

注:这里使用的术语"字符集"通常的被称做一种"字符编码"。不过既然HTTP和MIME在同一机构注册,术语统一是很重要的。

HTTP字符集是用不区分大小写的标记(token)表示。全部的标记集由IANA字符集注册机构[19]定义。

charset = token

尽管HTTP容许用任意标记(token)做为字符集(charset)值,但任何标记值若是它已经在IANA字符集注册机构注册了则必须表示在该注册机构定义的字符集。对那些非IANA定义的字符集,应用程序应该限制使用。

HTTP协议的实现者应该注意IETF字符集的要求38.

3.4.1丢失的字符集(Missing Charset)
一些HTTP/1.0应用程序当他们解析Content-Type头时,当发现没有字符集参数(charset parameter,译注:Content-Type: text/plain; charset=UTF-8,此时charset=UTF-8就是字符集参数)可用时,这意味着接收者必须猜想实体主体(entity body,译注:这里翻译成“实体主体”由于Content-Type头是实体头,消息头能够分为实体头,经常使用头,请求头,响应头,在译文中屡次用到“头”和“头域”,如消息头,消息头域,实际上是同一个意思,HTTP1.1协议有时候概念并非彻底统一的)的字符集是什么。若是发送者但愿避免这种状况,他应该在Content-Type头域里包含一个字符集参数,即便字符集是ISO-8859-1也应该这样作,这样就不会让接收者产生混淆。

不幸的是,一些旧的HTTP/1.0客户端不能处理在Content-Type头域里明确指定的字符集参数。HTTP/1.1接收端必需要认真对待发送者提供的字符集;而且当用户代理(user agent,译注:如浏览器,可认为是接收端)开始显示一个文档时,虽然用户代理能够猜想文档的字符集,但若是content-type头域里提供了字符集,而且用户代理也支持这种字符集的显示,无论用户代理是否愿意,它必需要利用这种字符集。参见3.7.1节。

3.5 内容编码(Content Codings)
内容编码值(content coding value)表示一种已经或能够应用于实体的编码转换(encoding transformation)。内容编码主要用于文档的压缩或其它有效的变换,但这种变换须要不能丢失文档的媒体类型(media type,译注:文档通常会有媒体类型,这经过在content-type里指定)的特性,也不能丢失文档的信息(译注:就像有损压缩和无损压缩,前者不会丢失信息,后者会丢失信息)。实体常常被编码的储存,而后直接传送,接收端只能解码。

content-coding   = token

全部内容编码值(content-coding value)是不区分大小写的。HTTP/1.1在接收译码 (14.3节)和内容译码(Content-Encoding)(14.11节)头域里使用内容编码值(content-coding value)。尽管该值描述了内容编码,更重要的是它指出了一种解码机制,利用这种机制对实体的编码进行解码。

网络分配数字权威( (IANA)充当内容编码值标记(token)的注册机构。最初,注册表里包含下列标记:

gzip(压缩程序)

一种由文件压缩程序"gzip"(GNU zip)产生的编码格式(在RFC 1952中描述)。这种编码格式是一种具备32位CRC的Lempel-Ziv编码(LZ77)。

compress(压缩)

一种由UNIX文件压缩程序"compress"产生的编码格式。这种编码格式是一种具备可适应性的Lempel-Ziv-Welch编码(LZW)。

对于未来的编码,用程序名识表征编码格式是不可取。在这里用到他们是由于他们在历史的做用,虽然这样作并很差。为了同之前的HTTP实现相兼容,应用程序应该将"x-gzip"和"x-compress"分别等同于"gzip"和"compress"。

deflate(缩小) 

deflate编码是由RFC 1950 [31]定义的"zlib"编码格式与RFC 1951 [29]里描述的"deflate"压缩机制的组合的产物。

identity(一致性)

Identity是缺省编码;指明这种编码代表不进行任何编码转换。这种内容编码仅被用于接收译码(Accept-Encoding)头域,但不能被用在内容译码(Content-Encoding)头域。.

新的内容编码值标记(token)应该被注册;为了实现客户和服务器间的互操做性,实现新值的内容编码算法规范应该能公开利用而且能独立实现,而且与本节中被定义的内容编码目的相一致。

3.6 传输编码 (Transfer Codings)
传输编码值(transfer-coding value,译注:transfer coding和和transfer-coding这两个术语在本协议规范里所表达的意思其实没什么太大区别,“transfer-coding”可能更能表达语意,由于它是规则中的规则名,见下面红字的规则)被用来表示一个已经,可以,或可能应用于一个实体的编码转换,传输编码是为了可以确保网络安全传输。这不一样于内容编码(content coding),由于传输编码(transfer coding)是消息的属性而不是实体的属性。

transfer-coding = "chunked" | transfer-extension

   transfer-extension      = token *( ";" parameter )

参数(parameter)采用属性/值对的形式.

parameter                    = attribute "=" value

   attribute                   = token

   value                     = token |   quoted-string

全部传输编码值(transfer-coding value,译注:上面红体字等号右边规则表达式所表达的值)是大小写不敏感。传输编码值在TE头域(14.39节)和在传输译码(Transfer-encoding) 头域中(14.41节)被运用。

不管什么时候,传输编码(transfer-coding)应用于一个消息主体(message body)时,若是存在多个传输编码,则这些传输编码中必须包括“块”("chunked")传输编码,除非经过关闭链接而中断消息。当“块”(“chunked”)传输编码被用于传输编码时,它必须是应用于消息主体的最后传输编码。"块"("chunked")传输编码最多只能用于消息主体(message-body)一次。规定了上述规则后,接收者就能够肯定消息的传输长度(transfer-length)(4.4节)

传输编码与MIME[7]的内容传输译码(Content-Transfer-Encoding,译注:transfer应该是转移,迁移的意思,又例如HTTP协议,应该翻译成“超文本转移协议”,可是历史上都翻译成“超文本传输协议”,因此这里翻译成“超文本传输协议”)值有相相似型,它被定义可以实如今7位传输服务上保证二进制数据的传输安全。不过,传输编码与内容传输译码(Content-Transfer-Encoding)对纯8位传输协议有不一样的关注点。在HTTP中,消息主体存在不安全的隐患,由于有时候很难肯定消息主体的长度,在共享的传输上加密数据也会带来安全性问题(7.2.2节)。

网络分配数字权威(IANA)担任注册传输编码值标(token)记的角色。起初,注册包含以下标记:"块"(3.6.1节),"身份"(3.6.2节),"gzip"(3.5节),"压缩"(3.5节),和"缩小"(3.5节).

新的传输编码值标记应该注册,这同新的内容编码值标记也须要注册同样。.

接收端接收到一个带有传输编码(transfer-coding)(译注:经过消息头域transfer-encoding指明此实体主体的传输编码)的实体主体(entity body),若是它不能对这个编码后的实体主体进行解码,那么它应返回501(不能实现),而且要切断联系。服务器不能向HTTP/1.0客户发送传输编码.

3.6.1块传输编码(Chunked Transfer Coding)
块编码(chunked encoding)改变消息主体使消息主体(message body,译注:消息主体与实体主体是有区别的,后面章节将会介绍)成块发送。每个块有它本身的大小(size)指示器,在全部的块以后会紧接着一个可选的包含实体头域的尾部(trailer)。这容许发送端能动态生成内容,并能携带有用的信息,这些信息能让接收者判断消息是否接收完整。

Chunked-Body(块正文)   = *chunk(块)

                             last-chunk(最后块)

                                trailer(尾部)

                         CRLF

   chunk(块)          = chunk-size [ chunk-extension ] CRLF

                           chunk-data CRLF

   chunk-size     = 1*HEX

   last-chunk     = 1*("0") [ chunk-extension ] CRLF      

   chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )             

   chunk-ext-name = token

   chunk-ext-val = token | quoted-string

   chunk-data     = chunk-size(OCTET)

   trailer        = *(entity-header CRLF)

chunk-size是用16 进制数字字符串。块编码(chunked encoding)以任一大小为0的块结束,紧接着是尾部(trailer),尾部以一个空行终止。

尾部(trailer)容许发送端在消息的末尾包含附加的HTTP头域(header field)。Trailer头域(Trailer header field,译注:Trailer头是经常使用消息头,在14.40节说明)被应用来指明哪些头域被包含在块编码的尾部(trailer) (见14.40节)

若是服务器要用块传输编码进行响应,它不能包含尾部(trailer),除非如下至少一条为真:

a)若是此响应的请求包括一个TE头域,而且它指明了传输编码中的“trailers”是可接受的,当响应的传输编码(transfer-coding)是块编码时。这在14.39节中描述;或者

b)若是服务器是响应的源服务器,而且接收端接收块传输编码响应但不会去理会响应的尾部(trailer,译注:尾部包含头域,头域就是消息的元数据(metadata))而且这种方式源服务器是能够接受的,这时服务器是不须要把尾部(trailer)包含进消息的块传输编码中去的。换句话说,源服务器原意接受尾部(trailer)可能会在到达客户端时被丢弃的可能性。

此要求防止了一种互操做性的失败,当消息被一个HTTP/1.1(或更迟的)代理(proxy)接收而且转到一个HTTP/1.0的接收端的时候。

在附录19.4.6节介绍了一个例子,这个例子介绍怎样对一个块正文(chunked-body)进行解码。

全部HTTP/1.1应用程序必须能接收和解码块(chunked)传输译码,而且必须忽略它们不能理解的块扩展(chunk-extentsion,译注:见上面的规则表达式).

3.7 媒体类型(Media Type)
HTTP在Content-Type(14.17节)实体头域和Accept请求头域里利用网络媒体[17]类型,这是为了提供公开的,可扩展的数据打印和类型协商。

media-type = type "/" subtype *( ";" parameter )

type = token

subtype = token

参数(parameter)以一种属性/值对的形式跟随type/subtype(如3.6节定义) 。

类型(type),子类型(subtype),和参数(parameter)里属性名称是大小写不敏感的。参数值有多是大小写敏感的,也可能不是,这根据参数里属性名的语意。线性空白(LWS)不能被用于类型(type)和子类型(subtype)之间,也不能用于参数的属性和值之间。参数的出现或不出现对处理媒体类型(media-type)可能会有帮助,这取决于它在媒体类型注册表里的定义。

注意一些旧的HTTP应用程序不能识别媒体类型的参数(parameter)。当向一个旧的HTTP应用程序发送数据时,发送端只有在被type/subtype定义须要时才使用类型参数(parameter)。

媒体类型(media-type)值须要被注册到网络数字分配权威(IANA[19])里。媒体类型的注册程序在RFC 1590[17]中大概描述。使用未经注册的媒体类型是不被鼓励的。

3.7.1规范化和文本缺省 (Canonicalization and Text Defaults)
网络媒体类型以规范化的格式被注册。一个实体主体(entity-body)经过HTTP消息传输,它必须在传输前以一种合适的规范化的格式表征除了文本类型(text type),文本类型将会在下一段阐述。

当消息以一种规范化的格式表现时,文本类型的子类型(subtype)运用GRLF做为文本里的换行符。HTTP放松了这个要求,而且容许文本媒体以一个CR或LF表明一个换行符传输,而且这样作要贯穿整个实体主体(entity-body)。HTTP应用程序必须能接收CRLF,CR和LF做为在文本媒体一个换行符。另外,若是文本字符集(character set)不能用字节13和10来分别地表征CR和LF由于存在一些多字节字符,HTTP容许应用字符集里等价于CR和LF的字节序列来表示换行符。对换行符的灵活处理只能应用于实体主体里的文本媒体;在HTTP消息结构里,一个单独的CR或LF都不能代替CRLF(如头域和多边界体(multipart boundaries)结构里)。

若是一个实体主体(entity-body)用内容编码(content-coding)进行编码,原始数据(译注:被编码前的数据)在被编码前必须是一种定义的媒体类型格式。.

"charset"参数(parameter)被应用于一些媒体类型,来定义数据的字符集(见3.4节)。当发送者没有在媒体类型(media-type)里指明charset参数(parameter)时,文本类型的子媒体类型(subtype)被认为是缺省的ISO-8859-1字符集当被接收者接收后。数据必须被合适的字符集标识。3.4.1节描述了兼容性问题。

3.7.2多部分类型(Multipart type)
MIME提供了一系列"多部分"类型---在单个消息主体内包装一个或多个实体。全部的多部分类型共享一个公共的语法(这在RFC 2046[40]的5.1.1节中描述),而且包含一个边界(boundary)参数做为多部分媒体类型值的一部分。多部分类型的消息主体是一个协议元素,而且必须用CRLF来标识体部分(body-part,译注:见RFC 2046 的5节)之间的换行。

不一样于RFC 2046里的多部分消息类型的描述,HTTP1.1规定任何多部分类型的消息尾声(epilogue,译:见RFC 2046对多部分消息类型的规则描述)必须不能存在;HTTP应用程序不能传输尾声(epilogue)(即便原始的多部分消息尾部包含一个尾声)。存在这些限制是为了保护多部分消息主体的自我定界的特性,由于多部分边界的结束(译注:根据RFC2046中定义,多部分边界结束后可能还会有尾声)标志着消息主体的结束。

一般,HTTP把一个多部分类型的消息主体(message-body)和任何其余媒体类型的消息主体相同对待:严格看做有用的负载体。有一个例外就是"multipart/byterange"类型(附录19.2),当它出如今206(部份内容)响应时,此响应会被一些HTTP缓存机制解析,缓存机制将会在13.5.4节和14.16节介绍。在其它状况下,一个HTTP用户代理会遵循MIME用户代理同样的或者类似的行为,这依赖于接收何种多部分类型。一个多部分类型消息的每个体部分(bady-part)里的MIME头域对于HTTP并无太大意义除了MIME语意。

一般, 一个HTTP用户代理应该遵循与一个MINE用户代理相同或类似。若是一个应用程序收到一个不能识别的多部分子类型,这个应用程序必须将它视为"multipart/mixed"。

注:"multipart/form-data"类型已经被规范的定义为传送窗体数据(译注:通常用窗体上传数据时,上传的数据类型就是为multipart/form-data类型),当用POST请求方法处理数据时。这在RFC 1867[15]里定义。

3.8 产品标记 (product Tokens)
产品标记用产品名和版本号识别通信应用软件。不少头域都会利用产品标记,它容许构成应用程序重要部分的子产品被以空白分隔列举。一般,产品以应用程序的重要性的顺序来列举的。

product               = token ["/" product-version]

   product-version       = token

例:

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

Server: Apache/0.8.4

产品标示应言简意赅。它们不能用来作广告或其余不重要的信息。虽然任一标记可能出现product-version里,但这个标记仅能用来作一个版本 (i.e., 同产品中的后续版本应该在product-version上有区别)

3.9 质量值(Quality Values)
HTTP内容协商(content negotiation,12节介绍)运用短“浮点”数字(short floating point number)来表针不一样协商参数的相对重要性。重要性的权值被规范化成一个从0到1的实数。0是最小值,1是最大值。若是一个参数的质量值(quanlity value)为0,那么这个参数的内容不被客户端接受。HTTP/1.1应用程序不能产生多于三位小数的实数。下面规则限定了这些值。

qvalue         = ( "0" [ "." 0*3DIGIT ] )

                  | ( "1" [ "." 0*3("0") ] )

"质量值" 是一个不当的用词,由于这些值仅仅表现一中相对的降级。

3.10 语言标签 (Language Tags)
一个语言标签表征一种天然语言,这种天然语言能说,能写,或者被用来人与人之间的沟通。计算机语言明显不包括在内的。HTTP在Accept-Language和Content-Language头域里应用到语言标签(language tag)。

HTTP语言标签的语法和注册和RFC 1766[1]中定义的同样。总之,一个语言标签是由一部分或多部分构成:一个主语言标签和可能为空的子标签系列。

Language-tag      = primary-tag*("-" subtag)

    primary           = 1*8ALPHA

    subtag            = 1*8ALPHA

标签中不容许出现空格,标签大小写不敏感(case-insensitive)。由IANA来管理语言标签中的名字。典型的标签包括:

en, en-US, en-cockney, i-cherokee, x-pig-latin

上面的任意两个字母的主标签是一个ISO-639语言的缩,而且两个大写字母的子标签是一个ISO-3166的国家代码。(上面的最后三个标签是未经注册的标签;可是除最后一个以外全部的标签都会未来注册)。

3.11 实体标签 (Entity Tags)
实体标签被用于比较相同请求资源中两个或更多实体。HTTP/1.1在ETag(14.19节),If-match(14.24节),If-None-match(14.26节)和If-Rang(14.27节)头域中运用实体标签。关于它们怎样被看成一个缓存验证器(cache validator)而使用和比较在13.3.3节被定义。一个实体标签由一个给定的晦涩的引用字符串(opaque quoted string),还可能前面带一个弱指示器组成。

entity-tag = [ weak ] opaque-tag

  weak       = "W/"

  opaque-tag = quoted-string

一个“强实体标签”若是被一个资源的两个实体里共享,那么这两个实体必须在字节上等价。

一个“弱实体标签”是以"W/"前缀的,它可能会被一个资源的两个实体共享,若是这两个实体是等价的,而且能彼此之间能互相替代,而且也不会在语义上有太大改变。一个弱实体标签只能用于弱比较(weak comparison)。

在一个特定资源的全部实体版本里,一个实体标签必须能惟一。一个给定的实体标签值能够被于不一样的URI请求用来得到的实体。相同实体标签值运用于不一样URI请求得到的实体,并不意味着这些实体是等价的。

3.12 范围单位(Range Units)
HTTP/1.1容许一个客户请求响应实体的一部分。HTTP/1.1在Range(14.35节)和Content-Range(14.16节)头域里应用范围单位(range units)。任何实体根据不一样的结构化单元都能被分解是子范围

range-unit = bytes-unit | other-range-unit

bytes-unit = "bytes"

other-range-unit = token

HTTP/1.1中定义的惟一的范围单位是"bytes"。HTTP/1.1实现时可能忽略其余单位指定的范围。

HTTP/1.1被设计容许应用程序实现不依靠有关对范围的了解。

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)头域来看待。

5 请求(Request)
一个请求消息是从客户端到服务器端的,在消息首行里包含方法,资源指示符,协议版本。

Request = Request-Line ; Section 5.1

*(( general-header ; Section 4.5

| request-header ; Section 5.3

| entity-header ) CRLF) ; Section 7.1

CRLF

[ message-body ] ; Section 4.3

5.1 请求行 (Request-Line)
请求行(Request-Line)是以一个方法标记开始,后面跟随Request-URI和协议版本,最后以CRLF结束。元素是以SP字符分隔。CR或LF是不被容许的除了最后的CRLF。

Request-Line =Method SP Request-URL SP HTTP-Version CRLF

5.1.1方法 (Method)
方法标记指示了在被Request-URI指定的资源上执行的方法。这种方法是大小写敏感的。

Method = "OPTIONS" ;9.2节

| "GET"                        ;9.3节

         | "HEAD"                       ;9.4节

         |"POST"                        ;9.5节

         |"PUT"                         ;9.6节

         |"DELETE"                      ;9.7节

         |"TRACE"                       ;9.8节

         |"CONNECT"                     ;9.9节

         | extension-method

Extension-method = token

资源容许的方法由Allow头域指定(14.7节)。响应的返回码老是通知客户是否一个方法对一个资源在当前是被容许的,由于被容许的方法集合能被动态的改变。一个源服务器应该返回405状态码(方法不能容许)若是此方法对于一个请求资源在服务器那里不被容许,而且返回501状态码(没有实现)若是此方法不被源服务器识别或实现。方法GET和HEAD必须被全部常规目的的服务器支持。全部其它的方法是可选的;然而,若是上面的全部方法都被实现,这些方法必须遵循的语意和第9节指定的相同。

5.1.2请求URL(Request-URI)
Request-URI是一种全球统一资源标识符(3.2 节),而且它指定请求的资源。

Request-URI   ="*" | absoluteURI | abs_path | authotity

Request-URI的OPTIONS依赖于请求的性质。星号"*"意味着请求不能应用于一个特定的资源,可是能应用于服务器,而且只能被容许当使用的方法不能应用于资源的时候。举例以下

OPTIONS  *  HTTP/1.1

当向代理(proxy)提交请求时,绝对URI(absoluteRUI)是不可缺乏的。代理(proxy)可能会被要求再次转寄此请求。注意:代理可能再次提交此请求到另外一个代理或直接给源服务器。为了不循环请求,代理(proxy)必须能识别全部的服务器名字,包括任何别名,本地变量,数字IP地址。一个请求行(Request-Line)的例子以下:

GET http://www.w3.org/pub/www/TheProject.html HTTP/1.1

为了将来HTTP版本的全部请求能迁移到绝对URI(absoluteURI)地址,全部基于HTTP/1.1的服务器必须接受绝对URL地址,即便HTTP/1.1的客户端只向代理产生给绝对URI(absoluteURI)。

authority部分只被用于CONNECT方法(9.9节).

Request-URI大多数状况是被用于指定一个源服务器或网关(gateway)上的资源。这种状况下,URI的绝对路径(abs_path)必须被用做Request-URI,而且此URI(authority)的网络位置必须在Host头域里指出。例如:客户但愿直接从源服务器获取资源,这种状况下,它可能会创建一个TCP链接,此链接是特定于主机”www.w3.org”的80端口的,这是会发送下面行:

GET /pub/WWW/TheProject.html HTTP/1.1

Host:www.w3.org

接下来是请求的其余部分,注意绝对路径不能是空的;若是在原始的URI里没有出现绝对路径,必须给出"/"(服务器根目录).

Request-URI是以3.2.1节里指定的格式传输。若是Request-URI用"%HEX HEX"[42]编码,源服务器为了解析请求必须能解码它。服务器接收到一个无效的Request-URI时必须以一个合适的状态码响应。

透明代理(proxy)不能重写接收到的Request-URI里的”abs_path”当它转寄此请求到下一个服务器时,除了根据上面声明的把一个空的abs_path用”/”代替。

注:不重写的规则防止了代理(proxy)改变请求的意思,当源服务器不能正确的利用非保留(non-reserved)的URI字符时 。实现者应该知道某些pre-HTTP/1.1代理(proxy)能重写Request-URI。

5.2请求资源 (The Resource Identified by a Request)
请求里资源的精肯定位是由请求里的Request-URI和Host头域决定的。

若是源服务器资源不依赖于请求的Host头域指定的主机(译注:可能会存在虚拟主机),那么它会忽略请求的头域当它决定其资源的时候。(对于一个支持Host的HTTP/1.1服务器,在19.6.1.1节描述了其余的需求).

源服务器若是根据请求里的主机区别资源(这是由于存在虚拟主机和虚拟主机名),它必须遵循下面的规则去决定请求的资源当出现一个HTTP/1.1请求时:

1. 若是Request-URI是绝对地址(absoluteURI),这时请求里的主机存在于Request-URI里。任何出如今请求里Host头域值应当被忽略。

2. 假如Request-URI不是绝对地址(absoluteURI),而且请求包括一个Host头域,则主机由该Host头域值决定.

3. 假如由规则1或规则2定义的主机是一个无效的主机,则应当以一个400(错误请求)错误消息返回。

缺乏Host头域的HTTP/1.0请求的接收者可能会推测决定什么样的资源被请求(例如:检查URI的路径对于某个特定的主机是惟一的)。

5.3请求报头域 (Request Header Fields)
请求头域容许客户端传递请求的附加信息和客户端本身的附加信息给服务器。这些头域做为请求的修饰符,这和程序语言方法调用的参数语义是同样的。

请求头(request-header) = Accept ;14.1节

| Accept-Charset       ;14.2节

                      |Accept-Encoding         ;14.3节

                      |Accept-Language        ;14.4节

                      |Authorization       ;14.8节

                      |Expect                       ;14.20节

                      |From            ;14.22节

                      |Host                ;14.23节

                      |If-Match         ;14.24节

                      |If-Modified-Since       ;14.25节

                      | If-None-Match            ;14.26节

                      | If-Range                 ;14.27节

                      | If-Unmodified-Since   ;14.28节

                      | Max-Forwards        ;14.31节

                      | Proxy-Authorization  ;14.34节

                      | Range            ;14.35节

                     | Referer           ;14.36节

                      |TE                           ;14.39节

                      | User-Agent           ;14.43节

请求头域的名字是能结合于协议版本而能被扩展的。然而新的或实验性的头域应该被给出请求头域的语义若是通讯的全部方都把它看做请求头域。不能识别的头域会被看做实体头域(entity-header)。

6 响应 (Response)
接收和翻译一个请求消息后,服务器发出一个HTTP响应消息。

response   =Status-Line                           ;6.1节

       *(( general-header)                           ; 4.5节

                   | response-header     ;6.2节

                   | entity-header)CRLF)   ;7.1节

                  CRLF

                  [ message-body ]        ;7.2节

6.1 状态行 (Status-Line)
响应消息的第一行是状态行(stauts-Line),由协议版本以及数字状态码和相关的文本短语组成,各部分间用空格符隔开,除了最后的回车或换行外,中间不容许有回车换行.

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

6.1.1状态码与缘由短语 (Status Code and Reason Phrase)
状态码是试图理解和知足请求的三位数字的整数码,这些码的完整定义在第十章。缘由短语(Reason-Phrase)是为了给出的关于状态码的文本描述。状态码用于控制条件,而缘由短语(Reason-Phrase)是让用户便于阅读。客户端不须要检查和显示缘由短语。

状态码的第一位数字定义响应类型。后两位数字没有任何分类角色。第一位数字有五种值:

-1xx: 报告的 - 接收到请求,继续进程.

-2xx 成功 - 步骤成功接收,被理解,并被接受

-3xx 重发 - 为了完成请求,必须采起进一步措施.

-4xx 客户端出错 - 请求包括错的顺序或不能完成.

-5xx 服务器出错 - 服务器没法完成显然有效的请求.

下面列举了为HTTP/1.1定义的态码值,和对应的缘由短语(Reason-Phrase)的例子。缘由短语在这里例举只是建议性的----它们也许被一个局部的等价体代替而不会影响此协议的语义。

Status-Code =

"100" ; 10.1.1节: 继续    

       |"101"   ; 10.1.2节: 转换协议     

       |"200"   ; 10.2.1节: OK

  |"201"   ; 10.2.2节:   建立         

    |"202"   ; 10.2.3节:   接受         

 |"203"   ; 10.2.4节: 非权威信息   

    |"204"   ;   10.2.5节: 无内容       

    |"205"   ;   10.2.6节: 重置内容      

    |"206"   ;   10.2.7节: 局部内容      

    |"300"   ;   10.3.1节: 多样选择      

    |"301"   ;   10.3.2节: 永久移动      

   |"302"   ;   10.3.3节: 建立          

    |"303"   ;   10.3.4节: 观察别的部分          

    |"304"   ;   10.3.5节: 只读                  

    |"305"   ;   10.3.6节: 用户代理              

    |"307"   ;   10.3.8节   临时重发              

   |"400"   ;   10.4.1节: 坏请求                

    |"401"   ;   10.4.2节: 未受权的              

  |"402"   ;   10.4.3节: 必要的支付            

  |"403"   ;   10.4.4节: 禁用                  

  |"404"   ;   10.4.5节: 没找到                 

  |"405"   ;   10.4.6节: 不容许的方式          

  |"406"   ;   10.4.7节: 不接受                 

  |"407"   ;   10.4.8节: 须要代理验证

  |"408"   ;   10.4.9节: 请求超时              

  |"409"   ;   10.4.10节; 冲突                  

  |"410"   ;   10.4.11节: 中止                  

  |"411"   ;   10.4.12节: 须要的长度            

  |"412"   ; 10.4.13节; 预处理失败            

  |"413"   ;   10.4.14节: 请求实体太大      

  |"414"   ;   10.4.15节; 请求-URI太大      

  |"415"   ;   10.4.16节: 不支持的媒体类型   

  |"416"   ; 10.4.17节: 请求的范围不知足  

  |"417"   ;   10.4.18节: 指望失败           

  |"500"   ;   10.5.1节:   服务器内部错误       

  |"501"   ;   10.5.2节:   不能实现             

  |"502"   ;   10.5.3节:   坏网关               

  |"503"   ;   10.5.4节:   服务不能实现         

  |"504"   ;   10.5.5节:   网关超时             

  |"505"   ;   10.5.6节:   HTTP版本不支持  

  |扩展码

extension-code =3DIGIT

Reason-Phrase = *<TEXT,excluding CR,LF>

HTTP状态码是可扩展的。HTTP应用程序不须要理解全部已注册状态码的含义,尽管那样的理解显而易见是很合算的。可是,应用程序必须了解由第一位数字指定的状态码的类型,任何未被识别的响应应被看做是该类型的x00状态,有一个例外就是未被识别的响应不能缓存。例如,若是客户端收到一个未被识别的状态码431,则能够安全的假定请求有错,而且它会对待此响应就像它接收了一个状态码是400的响应。在这种状况下,用户代理(user agent)应当把实体和响应一块儿提交给用户,由于实体极可能包括人可读的关于解释不正常状态的信息。

6.2响应头域 (Response Header Fields)
响应头域容许服务器传送响应的附加信息,这些信息不能放在状态行(Status-Line)里.。这些头域给出有关服务器的信息以及请求URI(Request-URI)指定的资源的更进一步的访问。

response-header = Accept-Ranges ; 14.5节

|Age         ; 14.6节

               |Etag            ; 14.19节

               |Location          ; 14.30节

               |Proxy-Autenticate     ; 14.33节

               |Retry-After     ; 14.37节

               |Server      ; 14.38节

               |Vary        ; 14.44节

               |WWW-Authenticate ; 14.47节

响应头域的名字能依赖于协议版本的变化而扩展。然而,新的或者实验性的头域可能会给于响应头域的语义若是通讯的成员都能识别他们并把他们看做响应头域。不被识别的头域被看做实体头域。

7 实体(Entity)
若是不被请求的方法或响应的状态码所限制,请求和响应消息均可以传输实体。 实体包括实体头域(entity-header)与实体主体(entity-body),而有些响应只包括实体头域(entity-header)。

在本节中的发送者和接收者是不是客户端或服务器,这依赖于谁发送或谁接收此实体。

7.1 实体报文域(Entity Header Fields)
实体(entity-header)头域定义了关于实体主体的的元信息,或在无主体的状况下定义了请求的资源的元信息。有些元信息是可选的;一些是必须的。

entity-header = Allow ; Section 14.7

| Content-Encoding ; Section 14.11

| Content-Language ; Section 14.12

| Content-Length ; Section 14.13

| Content-Location ; Section 14.14

| Content-MD5 ; Section 14.15

| Content-Range ; Section 14.16

| Content-Type ; Section 14.17

| Expires ; Section 14.21

| Last-Modified ; Section 14.29

| extension-header

extension-header = message-header

扩展头机制容许在不改变协议的前提下定义额外的实体头域,但不保证这些域在接收端可以被识别。未被识别的头域应当被接收者忽略,且必须被透明代理(transparent proxy)转发。

7.2 实体主体(Entity Body)
由HTTP请求或响应发送的实体主体(若是存在的话)的格式与编码方式应由实体的头域决定。

Entity-body= *OCTET

如4。3节所述,实体主体(entity-body)只有当消息主体存在时时才存在。实体主体(entity-body)从消息主体经过传输译码头域(Transfer-Encoding)译码获得,传输译码用于确保消息的安全和合适的传输。

7.2.1类型(Type)
当消息包含实体主体(entity-body)时,主体的数据类型由实体头域Content-Type和Content-Encoding决定。这些头域定义了两层的顺序的编码模型:

Entity-body:=Content-Encoding( Content-Type( data) )

Content-Type指定了下层数据的媒体类型。Content-Encoding可能被用来指定附加的应用于数据的内容编码,常常用于数据压缩的目的,内容编码是请求资源的属性。没有缺省的译码。

任一包含了实体主体的HTTP/1.1消息都应包括Content-Type头域以定义实体主体的媒体类型。若是而且只有媒体类型没有经过Content-Type头域指定时,接收者可能会尝试猜想媒体类型,这经过观察实体主体的内容而且/或者经过观察URI指定资源的扩展名。若是媒体类型仍然不知道,接收者应该把类型看做”application/octec-stream”。

7.2.2实体主体长度(Entity Length)
消息的实体主体长度指的是消息主体在被应用于传输编码(transfer-coding)以前的长度。4.4节定义了怎样去肯定消息主体的传输长度。

8 链接
8.1 持续链接(Persistent Connection)。
8.1.1目的
在持续链接以前,为获取每个URL指定的资源都必须创建了独立的TCP 链接, 这就加剧了HTTP服务器的负担,易引发互联网的阻塞。嵌入的图片与其它相关数据一般使用户在短期内对同一服务器提交多个请求。目前已有针对这些性能问题的分析以及原型实现的结果26。 对其余方法也有了初步探究,如T/TCP [27]。

持续HTTP 链接有着诸多的优势:

--- 经过创建与关闭较少的TCP链接,不只节省了路由器与主机(客户端,服务器,代理服务器,网关,隧道或缓存)的CPU时间,还节省了主机用于TCP协议控制块的内存。

---能在链接上进行流水线请求方式。 流水线请求方式能容许客户端执行屡次请求而不用等待每个请求的响应(译注:即客户端能够发送请求而不用等待之前的请求的响应到来后再发请求),而且此时只进行了一个TCP链接,从而效率更高,减小了时间。

--- 网络阻塞会被减小,这是因为TCP链接后减小了包的数量,而且因为容许TCP有充分的时间去决定网络阻塞的状态。

--- 由于无须在建立TCP链接时的握手上耗费时间,而使后续请求的等待时间减小。

---HTTP改进的愈来愈好,由于在不须要关闭TCP链接的代价下能够报告错误。未来的HTTP版本客户端能够乐观的尝试一个新的特性,可是若是和老的服务器通讯时,在错误被报告后就要用旧的语义而进行从新尝试链接。

HTTP实现应该实现持久链接。

8.1.2整体操做
HTTP/1.1 与早期HTTP 版本的一个显著区别在于持续链接是任何HTTP/1.1链接的缺省方式。也就是说,除非另有指定,客户端总应当假定服务器会保持持续链接,即使在接到服务器的出错响应时也应如此。

持续链接提供了一种能够由客户端或服务器发信号来终止TCP链接的机制。利用Connect头域(14。10节)能够产生终止链接信号。一旦出现了终止链接的信号,客户端便不可再向此链接提出任何新请求。

8.1.2.1 协商(Negotiation)
除非请求的Connect头域中包含了"close"标签,HTTP/1.1服务器总能够假定HTTP/1.1 客户端想要维持持续链接(persistent connection)。若是服务器想在发出响应后当即关闭链接,它应当发送一个含”close”的Connect头域。

一个HTTP/1.1客户端可能指望保持链接一直开着,但这必须是基于服务器响应里是否包含一个Connect头域而且此头域里是否包含”close”。若是客户端不想为更多的请求维持链接,它应该发送一个值为”close”的Connect头域。

若是客户端和服务器之一在发送的Connect头域里包含”close”,那么客户端的请求将会变为此链接的最后一个请求。。

客户端和服务器不该该认为持续链接是低于1.1的HTTP版本所拥有的,除非它被显示地指明了。19.6.2节指出了跟HTTP/1.1客户端兼容的更多信息。

8.1.2.2 流水线(pilelining)
支持持续链接(persistent conncetio)的客户端能够以流水线的方式发送请求(即无须等待响应而发送多个请求)。服务器必须按接收请求的顺序发送响应。

假定持续链接而且在链接创建后进行流水线方式请求的客户端应该准备去从新尝试他们的链接若是第一个流水线请求方式尝试失败。若是客户端从新尝试链接,在客户端知道链接是持续以前客户端不能进行流水线发送请求。客户端必须准备去从新发送请求若是服务器在响应全部对应的请求以前关闭链接

客户端不该该利用非等幂的方法或者非等幂的方法序列(见9.1.2节)进行流水线方式的请求。不然一个过早的传输层链接的终止可能会致使不肯定的结果。一个可能但愿发送一个非等幂方法请求的客户端只有接收了上次它发出请求的响应后才能再次发送请求给服务器。

8.1.3代理服务器 (Proxy Servers)
它是很是重要的由于代理服务器正确地实现了Connect头域的属性,这在14.10节指出了。

代理服务器必须分别向和它相连的客户端或者源服务器(或其余的代理服务器)指明持续链接。每个持续链接只能应用于一个传输层链接。

代理服务器不能和一个HTTP/1.0客户端创建一个HTTP/1.1持续链接(可是参见RFC2068[33]里的关于许多HTTP/1.1客户端利用Keep-Alive头域的问题的讨论)。

8.1.4实际的考虑 (Practical Considerations)
服务器一般有一个时限值,超过必定时间即再也不维持处于非活动的链接。代理服务器会选一个较高的值,由于客户端极可能会与同一服务器创建多个链接。持续链接方式的采用对于客户端与服务器的时限均未提出任何要求。

当客户端或服务器但愿超时终止时, 它应该按规范终止传输链接。客户端与服务器端应始终注意对方是否终止了链接,并适当的予以响应。若客户端或服务器未能及时检测到对方已终止了链接,将会形成没必要要的网络资源浪费。

客户端,服务器,或代理服务器可能在任意时刻会终止传输链接。好比,客户端可能正想发出新的请求,而此时服务器却决定关闭"闲置"的链接。在服务器看来,链接已经由于闲置被关闭了, 但客户端认为我正在请求。

这代表客户端,服务器与代理服务器必须有能力从异步的链接终止事件中恢复。只要请求是等幂的(见9.1.2节),客户端软件应该能从新打开传输层链接并从新传输遗弃的请求序列而不须要用户进行交互来实现。对非等幂方法的请求不能自动进行重试请求,尽管客户代理(user agent)可能能提供一我的工操做去重试这些请求。应该用用户代理(user-agent)软件对应用程序语义识别的确认来替代用户的确认。若是再次重试请求失败,那么就不能再进行重复请求了。

服务器尽量应该在每次链接中至少响应一个请求。除非出于网络或客户端的故障,服务器不该在传送响应的中途断开链接。

使用持续链接的客户端应限制与某一服务器同时链接的个数。单用户客户端不该与任一服务器或代理服务器保持两个以上的链接。代理服务器与其它服务器或代理服务器之间应维护2*N个链接,其中N是同时在线的用户数。这些准则是为了改善响应时间和和避免阻塞。

8.2 消息传送要求(Message Transmission Requirements)
8.2.1持续链接与流量控制 (Persistent Connections and Flow Control)
HTTP/1.1服务器应当保持持续链接并使用TCP流量控制机制来解决临时过载,而不是在终止链接后期望客户端的重试。后一方法会恶化网络阻塞。

8.2.2监视链接中出错状态的消息
HTTP/1.1(或更新)客户端应在发送消息主体的时候同时监视网络链接是否处于出错状态。若客户端发现了错误,它应当当即中止消息主体的的传送。若正文是以块传输编码方式发送的(3.6节),能够用长度为零的块和空尾部来提早标记报文结束。若消息主体前有Content-Length头域,则客户端必须关闭链接。

8.2.3 100状态码的用途
100状态码(继续,见10.1.1节)的目的在于容许客户端断定服务器是否愿意接受客户端发来的消息主体(基于请求头域)在客户端发送此请求消息主体前。 在有些状况下,若是服务器拒绝查看消息主体,这时客户端发送消息主体是不合适的或会下降效率。

HTTP/1.1客户端的要求:

--- 若客户端要在发送请求消息主体以前等候100(继续)响应,则它必须发送一个Expect请求头域(见14.20节),而且值是”100-continue”。

--- 客户端不能发送一个值是”100-continue”的Expect请求头域,若是此客户端不打算发送带消息主体的请求。

因为存在旧的实现方法,协议容许二义性的情形存在,这在客户端在发送”Expect:100-continue”后而没有接收一个417(指望失败)状态码或着100(继续)状态码的状况下发生。所以,当一个客户端发送此头域给一个源服务器(可能经过代理),此服务器也没有以100(继续)状态码响应,那么客户端不该该在发送请求消息的主体前无限等待。

HTTP’/1.1源服务器的要求:

--- 当接收一个包含值为”100-contitue”的Expect请求头域的请求时,源服务器必须或者以100(继续)状态码响应而且继续从输入流里接收数据,或者以final状态码响应。源服务器不能在发送100(继续)状态码响应以前接收请求主体。若是服务器以final状态码响应后,它可能会关闭传输层链接或者它也可能会继续接收或遗弃剩余的请求。可是既然它返回了一个final状态码的响应,它就不能再去那个执行请求的方法(如:POST方法,PUT方法)。

--- 如请求消息不含值为"100-continue"的Expect请求头域, 源服务器不该发送100(继续)响应。当请求来自HTTP/1.0(或更早)的客户端时也不得发送100(继续)响应。对此规定有一例外:为了与RFC 2068兼容,源服务器可能会发送一个100(继续)状态响应以响应HTTP/1.1的PUT或POSt请求,虽然这些请求中没有包含值为”100-continue”的Expect请求头域。这个例外的目的是为了减小任何客户端由于等待100(继续)状态响应的延时,但此例外只能应用于HTTP/1.1请求,并不适合于其余HTTP版本的请求。

--- 若已经接收到部分或所有请求的消息的主体,源服务器能够不须要发100(继续)响应。

--- 发送100(继续)响应的源服务器必须最终能发送一个final状态响应,一旦请求消息主体被它接收到而且已经被它处理了,除非源服务器过早切断了传输层链接。

--- 若源服务器接收到不含值为"100-contitue"的Expect请求头域的请求,该请求含有请求消息主体,而服务器在从传输层链接上接收整个请求消息主体前返回一个final的状态响应,那么此源服务器不能关闭传输层链接直到它接收了整个请求或者直到客户端关闭了此链接。不然客户端可能不会信任接收此响应消息。然而,这一要求不该该被解释用来防止服务器抵抗服务攻击,或者防止服务器被客户端实现攻击。

对HTTP/1.1代理服务器的要求:

--- 若代理服务器接到一个请求,此请求包含值为"100-continue"的Expect请求头域,而且代理服务器可能知道下一站点的服务器遵循HTTP/1.1或更高版协议,或者不知道下一站点服务器的HTTP版本,那么它必须包含此Expect头域来转发此请求。

--- 若代理服务器知道下一站点服务器版本是HTTP/1.0或更低,则它不能转发此请求,而且它必须以417(指望失败)状态响应。

--- 代理服务器应当维护一个缓存,以记录最近访问下一站点服务器的HTTP版本号。

--- 若接收到的请求来自于版本是HTTP/1.0(或更低)的客户端,而且此请求不含值为"100-continue"的Expect请求头域,那么代理服务器不能转发100(继续)响应。 这一要求可覆盖1xx响应转发的通常规则(参见10.1节)。

8.2.4服务器过早关闭链接时客户端的行为
若是HTTP/1.1 客户端发送一条含有消息主体的请求消息,但不含值为"100-continue"的Expect请求头域,而且客户端直接与HTTP/1.1源服务器相连,而且客户端在接收到服务器的状态响应以前看到了链接的关闭,那么客户端应该重试此请求。在重试时,客户端能够利用下面的算法来得到可靠的响应。

1. 向服务器发起一新链接。

2. 发送请请求头域。

3. 初始化变量R,使R的值为通往服务器的往返时间的估计值(好比基于创建链接的时间),或在没法估计往返时间时设为一常数值5秒。

4. 计算T=R(2*N),N为此前重试请求的次数。

5. 等待服务器出错响应,或是等待T秒(二者中时间较短的)。

6. 若没等到出错响应,T秒后发送请求的消息主体。

7. 若客户端发现链接被提早关闭,转到第1步,直到请求被接受,接收到出错响应,或是用户因不耐烦而终止了重试过程。

在任意点上,客户端若是接收到服务器的出错响应,客户端

--- 不该再继续发送请求, 而且

--- 应该关闭链接若是客户端没有完成发送请求消息。

9 方法定义(Method Definitions)
HTTP/1.1经常使用方法的定义以下。虽然方法能够被展开,但新加的方法不能认为能分享与扩展的客户端和服务器一样的语义。

Hst请求头域(见13.23节)必须能在全部的HTTP/1.1请求里出现。

9.1 安全和等幂(Idempotent)方法
9.1.1安全方法(Safe Methods)
实现者应当知道软件是表明用户在互联网上进行交互,而且应该当心地容许用户知道任何它们可能采起的动做(action),这些动做可能给他们本身或他人带来没法预料的结果。

特别的,GET和HEAD方法仅仅应该获取资源而不是执行动做(action)。这些方法应该被考虑是“安全”的。可让用户代理用其余的方法,如:POST,PUT,DELETE,这样用户代理就能知道这些方法可能会执行不安全的动做。

天然的,保证当服务器因为执行GET请求而不能产生反作用是不可能的;实际上,一些动态的资源会考虑这个特性。用户并无请求这些反作用,所以不须要对这些反作用负责。

9.1.2等幂方法(Idempotent Mehtods)
方法能够有等幂的性质由于(除了出错或终止问题)N>0个相同请求的反作用同单个请求的反作用的效果是同样(译注:等幂就是值不变性,相同的请求获得相同的响应结果,不会出现相同的请求出现不一样的响应结果)。方法GET,HEAD,PUT,DELETE都有这种性质。一样,方法OPTIONS和TRACE不该该有反作用,所以具备内在的等幂性。然而,有可能几个请求的序列是不等幂的,即便在那样的序列中全部方法都是等幂的。(若是整个序列总体的执行的结果老是相同的,而且此结果不会由于序列的总体,部分的再次执行而改变,那么此序列是等幂的。)例如,一个序列是非等幂的若是它的结果依赖于一个值,此值在之后相同的序列里会改变。

根据定义,一个序列若是没有反作用,那么此序列是等幂的(假设在资源集上没有并行的操做)。

9.2 OPTIONS(选项)
OPTIONS方法代表请求想获得请求/响应链上关于此请求里的URI(Request-URI)指定资源的通讯选项信息。此方法容许客户端去断定请求资源的选项和/或需求,或者服务器的能力,而不须要利用一个资源动做(译注:使用POST,PUT,DELETE方法)或一个资源获取(译注:用GET方法)方法。

这种方法的响应是不能缓存的.。

若是OPTIONS请求消息里包括一个实体主体(当请求消息里出现Content-Length或者Transfer-Encoding头域时),那么媒体类型必须经过Content-Type头域指明。虽然此规范没有定义如何使用此实体主体,未来的HTTP扩展可能会利用OPTIONS请求的消息主体去获得服务器得更多信息。一个服务器若是不支持OPTION请求的消息主体,它会遗弃此请求消息主体。

若是请求URI是一个星号(""),,OPTIONS请求将会应用于服务器的全部资源而不是特定资源。由于服务器的通讯选项一般依赖于资源,因此””请求只能在“ping”或者“no-op”方法时才有用;它干不了任何事情除了容许客户端测试服务器的能力。例如:它能被用来测试代理是否遵循HTTP/1.1。

若是请求URI不是一个星号("*"),,OPTIONS请求只能应用于请求URI指定资源的选项。

200响应应该包含任何指明选项性质的头域,这些选项性质由服务器实现而且只适合那个请求的资源(例如,Allow头域),但也可能包一些扩展的在此规范里没有定义的头域。若是有响应主体的话也应该包含一些通讯选项的信息。这个响应主体的格式并无在此规范里定义,可是可能会在之后的HTTP里定义。内容协商可能被用于选择合适的响应格式。若是没有响应主体包含,响应就应该包含一个值为“0”的Content-Length头域。

Max-Forwards请求头域可能会被用于针对请求链中特定的代理。当代理接收到一个OPTIONS请求,且此请求的URI为absoluteURI,而且此请求是能够被转发的,那么代理必需要检测Max-Forwards头域。若是Max-Forwards头域的值为“0”,那么此代理不能转发此消息;而是,代理应该以它本身的通讯选项响应。若是Max-Forwards头域是比0大的整数值,那么代理必须递减此值当它转发此请求时。若是没有Max-Forwards头域出如今请求里,那么代理转发此请求时不能包含Max-Forwards头域。

9.3 GET
GET方法意思是获取被请求URI(Request-URI)指定的信息(以实体的格式)。若是请求URI涉及到一个数据生成过程,那么这个生成的数据应该被做为实体在响应中返回,但这并非过程的资源文本,除非资源文本刚好是过程的输出(译注:URI指示的资源是动态生成的)。

若是请求消息包含 If-Modified-Since,,If-Unmodified-Since,If-Match,,If-None-Match,或者 If-Range头域,,GET的语义将变成“条件(conditionall) GET”。一个条件GET方法会请求知足条件头域的实体。条件GET方法的目的是为了减小没必要要的网络使用,这经过利用缓存的实体的更新,从而不用屡次请求或传输客户已经拥有的数据。.

若是请求方法包含一个Range头域,那么GET方法就变成“部分Get”方法。一个部分GET会请求实体的一部分,这在14.35节里描述了。 部分GET方法的目的是为了减小没必要要的网络使用,这经过容许获取部分实体,从而不须要传输客户端已经拥有的数据。

GET请求的响应是可缓存的(cacheable)若是此响应知足第13节HTTP缓存的要求。

看15.1.3节关于GET请求用于表单时安全考虑。

9.4 HEAD
HEAD方法和GET方法一致,除了服务器不能在响应里返回消息主体。HEAD请求响应里HTTP头域里的元信息应该和GET请求响应里的元信息一致。此方法被用来获取请求实体的元信息而不须要传输实体主体(entity-body)。此方法常常被用来测试超文本连接的有效性,可访问性,和最近的改变。.

HEAD请求的响应是可缓存的,由于响应里的信息可能被用于更新之前的那个资源的缓存实体.。若是出现一个新的域值指明了缓存实体和当前源服务器上实体的不一样(可能由于Content-Length,Content-MD5,ETag或Last-Modified值的改变),那么缓存(cache)必须认为此缓存项是过期的(stale)。

9.5 POST
POST 方法被用于请求源服务器接受请求中的实体做为请求资源的一个新的从属物。POST被设计涵盖下面的功能。

-已存在的资源的注释;

-发布消息给一个布告板,新闻组,邮件列表,或者类似的文章组。

-提供一个数据块,如提交一个表单给一个数据处理过程。

-经过追加操做来扩展数据库。

POST方法的实际功能是由服务器决定的,而且常常依赖于请求URI(Request-URI)。POST提交的实体是请求URI的从属物,就好像一个文件从属于一个目录,一篇新闻文章从属于一个新闻组,或者一条记录从属于一个数据库。

POST方法执行的动做可能不会对请求URI所指的资源起做用。在这种状况下,200(成功)或者204(没有内容)将是适合的响应状态,这依赖于响应是否包含一个描述结果的实体。

若是资源被源服务器建立,响应应该是201(Created)而且包含一个实体,此实体描述了请求的状态而且此实体引用了一个新资源和一个Location头域(见14.30节)。

POST方法的响应是可缓存的。除非响应里有Cache-Control或者Expires头域指示其响应不可缓存。然而,303(见其余)响应能被利用去指导用户代理(agent)去得到可缓存的响应。

POST 请求必须遵循8.2节里指明的消息传输需求。

参见15.1.3节关于安全性的考虑.

9.6 PUT
PUT方法请求服务器去把请求里的实体存储在请求URI(Request-URI)标识下。若是请求URI(Request-URI)指定的的资源已经在源服务器上存在,那么此请求里的实体应该被看成是源服务器此URI所指定资源实体的修改版本。若是请求URI(Request-URI)指定的资源不存在,而且此URI被用户代理(user agent,译注:用户代理可认为是客户浏览器)定义为一个新资源,那么源服务器就应该根据请求里的实体建立一个此URI所标识下的资源。若是一个新的资源被建立了,源服务器必须能向用户代理(user agent) 发送201(已建立)响应。若是已存在的资源被改变了,那么源服务器应该发送200(Ok)或者204(无内容)响应。若是资源不能根据请求URI建立或者改变,一个合适的错误响应应该给出以反应问题的性质。实体的接收者不能忽略任何它不理解的Content-*(如:Content-Range)头域,而且必须返回501(没有被实现)响应。

若是请求穿过一个缓存(cache),而且此请求URI(Request-URI)指示了一个或多个当前缓存的实体,那么这些实体应该被看做是旧的。PUT方法的响应不该该被缓存。

POST方法和PUT方法请求最根本的区别是请求URI(Request-URI)的含义不一样。POST请求里的URI指示一个能处理请求实体的资源(译注:此资源多是一段程序,如jsp里的servlet) 。此资源多是一个数据接收过程,一个网关(gateway,译注:网关和代理服务器的区别是:网关能够进行协议转换,而代理服务器不能,只是起代理的做用,好比缓存服务器其实就是一个代理服务器),或者一个单独接收注释的实体。而PUT方法请求里有一个实体一一用户代理知道URI意指什么,而且服务器不能把此请求应用于其余URI指定的资源。若是服务器指望请求被应用于一个不一样的URI,那么它必须发送301(永久移动了)响应;用户代理能够本身决定是否重定向请求。

一个独立的资源可能会被许多不一样的URI指定。如:一篇文章可能会有一个URI指定当前版本,此URI区别于其文章其余特殊版本的URI。这种状况下,一个通用URI的PUT请求可能会致使其资源的其余URI被源服务器定义。

HTTP/1.1没有定义PUT方法对源服务器的状态影响。

PUT请求必须遵循8.2节中的消息传输要求。

除非特别指出,PUT方法请求里的实体头域应该被用于资源的建立或修改。

9.7 DELETE(删除)
DELETE方法请求源服务器删除请求URI指定的资源。此方法可能会在源服务器上被人为的干涉(或其余方法)。客户端不能保证此操做能被执行,即便源服务器返回成功状态码。然而,服务器不该该指明成功除非它打算删除资源或把此资源移到一个不可访问的位置。

若是响应里包含描述成功的实体,响应应该是200(Ok);若是DELETE动做没有经过,应该以202(已接受)响应;若是DELETE方法请求已经经过了,但响应不包含实体,那么应该以204(无内容)响应。

若是请求穿过缓存,而且请求URI(Request-URI)指定一个或多个缓存当前实体,那么这些缓存项应该被认为是旧的。DELETE方法的响应是不能被缓存的。

9.8 TRACE
TRACE方法被用于激发一个远程的,应用层的请求消息回路(译注:TRACE方法让客户端测试到服务器的网络通路,回路的意思如发送一个请返回一个响应,这就是一个请求响应回路,)。最后的接收者或者是接收请求里Max-Forwards头域值为0源服务器或者是代理服务器或者是网关。TRACE请求不能包含一个实体。

TRACE方法容许客户端知道请求链的另外一端接收什么,而且利用那些数据去测试或诊断。Via头域值(见14.45)有特殊的用途,由于它能够做为请求链的跟踪信息。利用Max-Forwards头域容许客户端限制请求链的长度去测试一串代理服务器是否在无限回路里转发消息。

若是请求是有效的,响应应该在响应实体主体里包含整个请求消息,而且响应应该包含一个Content-Type头域值为”message/http”的头域。TRACE方法的响应不能不缓存。

9.9 CONNECT(链接)
HTTP1.1协议规范保留了CONNECT方法,此方法是为了能用于能动态切换到隧道的代理服务器(proxy,译注:能够为代理,也能够是代理服务器)。

10.状态码定义
每个状态码在下面定义,包括此状态码依赖于方法的描述和响应里须要的任何元信息的描述。

10.1 通知的 1xx
这类状态代码指明了一个备用的响应,包含一个Status-Line和可选的头域,而且一一个空行结束(译注:空行就是CRLF)。没有必须的头域对这类状态码。由于HTTP/1.0没有定义任何1xx状态码,因此服务器不能发送一个1xx响应给一个HTTP/1.1客户端,除了实验性的目的。

客户端必须能准备去接受一个或多个1xx状态响应优先于一个常规响应,即便客户端不指望100(继续)状态响应。不被客户端指望的1xx状态响应可能会被用户代理忽略。

代理服务器必须能转发1xx响应,除非代理服务器和它的客户端的链接关闭了,或者除非代理服务器本身响应请求并产生1xx响应。(例如:若是代理服务器添加了”Expect:100-continue”头域当转发请求时,那么它没必要转发相应的100(继续)响应。)

10.1.1 100 继续 (Continue)
100状态响应告诉客户端应该继续请求。100响应是个中间响应,它被用于通知客户端请求的初始部分已经被接收了而且此请求尚未被服务器丢弃。客户端应该继续发送请求的剩余部分,或者若是此请求已经完成了,客户端会忽略此100响应。服务器必须发送一个final响应在请求接收后。见8.2.3节关于此状态码的讨论和使用。

10.1.2 101切换协议 (Switching Protocols)
服务器理解和愿意遵循客户端这样的请求,此请求经过Upgrade消息头域(见14.42节)指明在链接上应用层协议的改变。 服务器将会切换到响应里Upgrade头域里指明的协议,而后紧接着跟随一个结束此101响应的空行。

只有当协议切换时能受益,协议才应该切换。例如,当传输资源时,切换到一个新的HTTP版本比旧的版本要好,或者切换到一个实时的,同步的协议带来好处时,咱们都应该考虑切换。

10.2 成功 2xx
这类状态码指明客户端的请球已经被服务器成功的接收了,理解了,而且接受了。

10.2.1 200 OK
此状态码指明客户端请求已经成功了。响应返回的信息依赖于请求里的方法,例如:

GET 请求资源的相应的实体已经包含在响应里并返回给客户端。

HEAD 相应于请求资源实体的实体头域已经被包含在无消息主体的响应里。

POST 响应里已经包含一个实体,此实体描述或者包含此POST动做执行的结果

TRACE 响应里包含一个实体,此实体包含终端对服务器接的请求消息。

10.2.2 201 已建立(Created)
请求已经被服务器知足了而且已经产生了一个新的资源。新建立的资源的URI在响应的实体里返回,可是此资源最肯定的URI是在Location头域里给出的。响应应该含有一实体,此实体包含此资源的特性和位置,用户或用户代理能从这些特性和位置里选择最合适的。实体格式被Content-Type头域里媒体类型指定。源服务器必须能在返回201状态码以前创建资源。若是动做(译注:这里指能建立资源的方法,如POST方法)不能被当即执行,那么服务器应该以202(接受)响应代替。

一个201响应能够包含一个ETag响应头域,此头域为请求的变量(译注:变量的含义见第1.3节“变量”的解释)指明当前的实体标签(entity tag)值,当资源被建立时,见14.19节。

10.2.3 202 接受(Accepted)
请求已经被接受了,可是尚未对此请求处理完。请求可能处理完也可能没有最终被处理完,由于当处理发生的时候服务器可能会发现此请求不能被处理。

202响应是非委托的。这是为了容许服务器为其余处理(如:天天执行一次的过程)而接受一个请求从而不须要用户代理和服务器之间在处理完成以前必须进行持久链接。响应里的实体应该包含请求当前状态的声明而且应该包含一个状态监视指针或一些用户指望什么时候请求被知足的评估。

10.2.4 203 非权威信息(Non-Authoritative information)
此状态码响应指明响应里的实体头域里的元信息对源服务器来讲是没有意义的,这些元信息是从局部的或第三方的响应副本里获得的。这些元信息多是源服务器版本的子集或超集。如,包含一个存在本地的资源注释信息就能够产生一个源服务器能理解的元信息的超集。203响应状态码的使用并非必须的而且只有在响应是非200(Ok)响应时才是合适的。

10.2.5 204 无内容 (No Content)
服务器已经知足了请求但不须要返回一个实体,而且可能只想返回更新了的元信息。204状态响应可能包含一个新的或更新了的,和请求变量(译注:变量是资源的一种表现形式,这和rest架构里的定义是同样的,因此这里咱们能够理解请求变量是请求资源的一种表现形式)相联系的元信息(元信息以实体头域的形式表式)。

利用此204响应,客户端若是是一个用户代理,它就能够不用改变引发请求发送的文档视图(译注:如一篇html文档在浏览器里呈现的样子)。204状态响应主要的目的是容许输入,而没必要引发用户代理当前文档视图的改变,虽然一些新的或更新了的元信息可能会应用于用户代理视图里的此文档。

204响应不能包含一个消息主体,而且在头域后包含一个空行结束。

10.2.6 205 重置内容(Reset Content)
205状态响应是服务器告诉用户代理应该重置引发请求被发送的文档视图。此响应主要的目的是清空文档视图表单里的输入框以便用户能输入其它信息。此响应不能包含一个实体。

10.2.7 206 部份内容(Partial Content)
服务器已经完成了客户端对资源的部分GET请求。请求必须包含一个Range头域(14.35节)用来指出想要的范围,而且也有可能包含一个If-Range头域(见14.27节)来使请求成为一个条件请求。

206状态的响应必须包含如下的头域:

  • 或者Content-Range头域,此头域指明了响应里的范围;或者一个值为”multipart/byteranges”的Content-Type头域和为每部分指明范围的Content-Range头域。若是一个Content-Length头域出如今响应里,它的值必须是实际的消息主体的字节数。
  • Date头域
  • ETag 和/或 Content-Location头域,若是这些头域已经在之前相同请求的200响应里返回过。
  • Expire,Cache-Control,和/或者Vary头域,若是域值与同一变量之前响应中的域值不同。

若是206响应是使用了强缓存验证(见13.3.3)的If-Range请求的结果,那么此响应不该该包含其余的实体头域。若是响应是使用了弱缓存验证的If-Range请求的结果,那么响应不能包含其余的实体头域;这能防止出如今缓存的实体主体和更新的头域之间的不一致性。其余的状况下,响应必须包含全部的实体头域,这些头域可能已经在之前的相同请求的200响应里返回过。

缓存不能把206响应和之前的缓存内容结合若是ETag或Last-Modified头域并不能精确匹配,见13.5.4。

一个不能支持Range和Content-Range头域的缓存不能缓存206(部分的)响应。

10.3 从新定向 3xx.
这类状态码指明用户代理须要更进一步的动做去完成请求。进一步的动做可能被用户代理自动执行而不须要用户的交互,而且进一步动做请求的方法必须为GET或HEAD。一个客户端应该发现无限的重定向回路,由于此回路能产生网络拥挤。

注意:之前此规范版本建议一个最多能有五个重定向。内容开发者应该知道客户端可能存在这个限制。

10.3.1 300 多个选择.(Multiple Choices)
资源对应有多个表现形式,客户端请求资源的表现形式对应于其中的一个,每一个表现形式都有一个指向本身的位置(location),而且代理驱动协商(agent-driven negotiation)能选择一个更适的表现形式并重定向请求到那个表现形式的位置。

除非是HEAD请求,不然300状态响应应该包含一个实体,此实体包含一个资源特性和位置列表,从这个列表里用户或用户代理能选择最合适的资源的表现形式。实体格式被Content-Type头域里的媒体类型指定。依赖于此格式和用户代理的能力,用户代理选择最合适的表现形式的行为可能会被自动执行。然而,此规范并无定义自动执行行为的标准。

若是服务器能肯定更好的表现形式,它应该为此表现形式在Location头域里包含一个特定的URI来指明此表现形式的位置;用户代理可能会利用此Location头域自动重定向。300状态响应是可缓存的除非被特别指明。

10.3.2 301 永久移动 (Moved Permanently)
请求资源被赋于一个新的永久的URI,而且任何未来对此资源的引用都会利用此301状态响应返回的URI。具备连接编辑能力的客户端应该能自动把请求URI的引用转到到服务器返回的新的引用下。此响应是能缓存的除非另外声明。

新的永久URI应该在响应中被Location头域给定。除非请求方法是HEAD,不然此响应的头域应该包含对此新URI超文本连接的一个超文本提示。

若是客户端接收了一个301状态响应,此响应相应的请求的方法不是GET或HEAD,那么用户代理不能自动重定向请求,除非它能被用户确认,由于这可能会改变请求提交的条件。

注意:当客户端在接收了301状态码响应后,会重定向POST请求,一些已经存在的HTTP/1.0用户代理将错误的把此请求变成一个GET请求。

10.3.3 302 发现(Found)
请求的资源放在一个不一样的暂时的URI下。由于重定向可能会偶尔被改变,客户端应该继续利用请求URI(Request-URI)为未来的请求。302响应是只有在Cache-Control或Expires头域指明的状况下才能被缓存。

临时的URI应该在Location头域里指定。除非请求方法是HEAD,不然响应的实体应该包含指向此新URI的超文本连接的短超超文本提示。

若是302状态代码在一个不是GET和HEAD方法请求的响应中,用户代理不能自动重定向请求除非用户确承认以自动重定向,由于这能改变请求提交的的条件。

注意:RFC1945和RFC2068指定客户端不能在重定向请求的时候改变请求方法。然而,大多数用户代理实现把302响应当作是303响应,根据Location头域值的URI执行GET请求,无论原始的请求方法。303和307状态响应的目的是为使服务器明白客户端指望哪一种类型的重定向。

10.3.4 303 见其余(See Other)
请求的响应被放在一个不一样的URI下,而且应该用GET方法得到那个资源。此方法的存在主要是容许POST执行脚本的输出重定向到用户选择的资源。新的URI并非原始请求资源的代替引用。303响应不能被缓存,可是再次重定向请求的响应应该被缓存。

不一样的URI应该在Location头域里指定。除非请求方法是HEAD,303响应的实体应该包含一个短的指向新的URI连接的超文本提示。

注意:许多HTTP/1.1之前版本的用户代理不能理解303状态响应。当这些客户端比较关注于互操做性的时候,302状态码应该被代替利用,由于大多用户代理对302响应的理解就是303响应。

10.3.5 304 没有被改变(Not Modified)
若是客户端已经执行了条件GET请求,而且访问服务器资源是容许的,可是服务器上的文档并无被改变,那么服务器应该以此状态码响应。304响应不能包含一个消息主体(message-body),而且在头域后面老是以一个空行结束。

此响应必须包含下面的头域:

-Date,除非14.18.1指明的那些规则下Date是能够遗漏的。若是时钟不许确的源服务器遵循这些规则,而且代理服务器和客户端在接收了一个没有Date头域的响应后加上了本身的Date(这在RFC 2086里声明了,见14.19节),缓存将会正确地操做。

-ETag 和/或 Content-Location,若是这些头域已经在相请求的200响应里出现过。

Expires,Cache-Control,和/或 Vary,若是这些头域的域值可能与之前相同请求的响应的域值不一致。

若是条件GET用强缓存验证(见13.3.3)节,那么响应不该该包含其余的实体头域。当条件GET用于弱缓存验证时,那么响应不能包含其余的实体头域;这能防止缓存的实体主体和更新了的头域之间的不一致性。

若是304响应指明实体不能被缓存,那么此缓存必须遗弃此响应,而且以无条件请求重复请求。

若是缓存利用一个304响应去更新一个缓存项,那么此缓存必须更新缓存项里关于响应里新的域值的那些域值。

10.3.6 305 使用代理服务器 (User Proxy)
请求资源必须能经过代理服务器访问,代理服务器的地址在响应的Location头域里指定。Location头域指定了代理服务器的URI。接收者被指望经过代理服务器重复此请求,305响应必须能被源服务器产生。

注意:RFC 2068并无说明305响应的目的是重定向一个独立请求,而且只能被源服务器产生。不注意这些限制会有重要的安全后果。

10.3.7 306没有使用的(unused)
306状态码被用于此规范之前的版本,是再也不使用的意思,而且此状态码被保留。

10.3.8 307临时重发(Temporary Redirect)
请求的资源临时存在于一个不一样的URI下。因为从新向可能会偶尔改变,因此客户端应该继续利用此请求URI(Request-URI)为未来的请求。307响应只有被Cache-Control或Expire头域指明时才能被缓存。

临时URI应该在响应的Location头域里给定。除非请求方法是HEAD,不然响应的实体应该包含一个指向新URI的超文本连接提示,由于许多HTTP/1.1之前的用户代理不能理解307状态响应。所以,此提示应该包含用户重复原始请求到新的URI的必需的信息。

若是307状态响应.对应的请求的方法不是GET或HEAD,那么用户代理不能自动重定向此请求除非它能被用户确认它能够重定向,由于这可能改变请求提交的条件。

10.4 客户错误 4xx
状态码4xx类的目的是为了指明客户端出现错误的状况。除了当响应一个HEAD请求,服务器应该包含一个实体,此实体包含一个此错误请求的解释。此状态码对全部请求方法都是适合的。用户代理应该展现任何响应里包含的实体给用户。

若是客户端发送数据,利用TCP的服务器实现应该当心确保客户端回复包含在响应里的接收包,这在服务器关闭此输入链接前。若是在关闭链接后,客户端继续发送数据给服务器,那么服务器的TCP栈将发送一个重置包给客户端,

10.4.1 400 坏请求(Bad Request)
请求不能被服务器理解,因为错误的语法。客户端不该该没有改变请求而重复请求。

10.4.2 401 未受权的 (Unauthorized)
请求须要用户受权。响应必须包含一个WWW-Authenticate头域(见14.47),此头域包含一个适用于请求资源的受权的激发。客户端会以一个Authorization头域重复此请求。若是请求包含了一个受权证书,若是服务器以401响应,它指明这些证书的受权被拒绝。若是401响应包含一个一样的受权激发和之前的响应同样,而且用户代理已经尝试至少受权了一次,那么用户应该被呈现包含在响应里的实体,由于这些实体可能包含相关的诊断信息。HTTP受权访问在“HTTP Authentication:Basic and Digest Access Authentication”[43]里解释。

10.4.3 402 必需的支付 (Payment Required)
此状态码为未来的应用保留。

10.4.4 403 禁用 (Forbidden)
服务器理解此请求,但拒绝知足此请求。受权是没有做用的而且请求不能被重复。若是请求方法是HEAD而且服务器想让客户端知道请求为何不能被知足,那么服务器起应该在响应实体里描述此拒绝的缘由。若是服务器不但愿告诉客户端拒绝的缘由,那么404状态码(Not Found)响应将被使用。

10.4.5 404 没有找到(Not Found)
服务器并无找到任何能够匹配请求URI的资源。条件是长期的仍是暂时的也没有被服务器指明。410(Gone)状态响应应该被使用,若是服务器知道一个旧的资源不能长期的使用而且没有转发地址时。 此状态码一般别用于当服务器不但愿指出为何请求被拒绝,或者没有任何其余响应是适合的。

10.4.6 405 不被容许的方法(Method Not Allowed)
此状态码表示请求行(Request-Line)里的方法对此资源来讲不被容许。响应必须包含一个Allow头域,此头域包含以一系列对此请求资源有效的方法。

10.4.7 406 不接受的 (Not Acceptable)
根据客户端请求的接受头域(译注:如:Accept, Accept-Charset, Accept-Encoding, 或者 Accept-Language),服务器不能产生让客户端能够接受的响应。

除非是HEAD请求,响应应该包含一个实体,此实体包含一系列实体的特性和位置,经过他们用户或用户代理能选择最合适的资源的表现形式。实体格式被媒体类型指定。依赖于此格式和用户代理的能力,选择最合适的会被自动执行。然而,此规范并无定义自动执行选择的标准。

注意:HTTP/1.1服务器被容许返回这样的响应,此响应根据接受头域(译注:如:Accept, Accept-Charset, Accept-Encoding, or Accept-Language)是不可接受的。在一些状况下,这可能更倾向于发送一个406响应。用户代理被鼓励观察响应来决定是否此响应是可接受的。

若是响应是不可接受的,用户代理应该暂时中止更多的数据的接收而且询问用户去决定进一步的动做。

10.4.8 407 代理服务器受权所需(Proxy Authentication Required)
此状态码和401(Unauthorized)类似,可是指明客户端必须首先利用代理服务器对本身受权。代理服务器必须返回一个Proxy-Authenticate头域(见14.33节),此头域包含一个适用于代理服务器的受权激发。客户端可能会重复此请求利用一个合适的Proxy-Autorization头域(见14.34节)。HTTP访问受权在“HTTP Authentication;Basic and Digest Access Authentication”[43]。

10.4.9 408 请求超时(Request Timeout)
客户端在服务器等待的时间里不能产生请求。客户端端可能在之后会重复此请求。

10.4.10 409 冲突 (Confilict)
请求不能完成因为和当前资源的状态冲突。此状态码只被容许出如今指望用户可能能解决此冲而且能从新提交此请求的状况下。响应主体应该包含足够的为用户认识此资源冲突的信息。理想的状况下,响应实体应该包含足够为用户或用户代理解决此问题的信息;然而,这是不可能的而且也是不须要的。

冲突最可能发生在响应PUT请求的时候。例如,若是版本被使用而且被提交的实体包含资源的改变,这些改变和之前的请求的改变想冲突,那么服务器应该使用409响应去指明它不能完成此请求。在这种状况下,此响应实体应该包含这两个版本的不一样,响应的格式在响应的Content-Type头域里指定。

10.4.11 410 不存在(gone)
请求资源再也不能够在服务器上获得而且也不知道转发地址(译注:转向此资源的地址)。此条件是长期条件。具备连接编辑能力的客户端应该在用户确认后删除请求URI的引用。若是服务器不知道或不能方便断定条件是不是长期的,那么此404(没有发现)状态响应将被代替利用。响应是可缓存的,除非另外申明。

410响应主要的目的是通知接收者资源不能被获得而且告诉接收者指向那个资源的链接已经被移动了。这样一个事件对时间要求比较严格的服务来讲是比较广泛的,而且对属于我的但已经不在服务器站点工做的人的资源来讲,这个事件来也是比较广泛的。把全部长期不能获得的资源标记成“gone”或保持这些标记任意长时间,这是没有必要的。

10.4.12 411 必需的长度 (Length Required)
此响应服务器拒绝接受没有包含Content-Length头域的请求。客户端能够重复此请求若是它添加了一个有效的Content-Length头域,此头域包含了请求消息里消息主体的长度。

10.4.13 412 先决条件失败 (Precondition Failed)
先决条件在一个或多个请求头域里指定,412响应是代表先决条件在服务器上测试等于false。此响应容许客户端把先决条件放到请求消息的元信息里(头域数据)。

10.4.14 413 请求实体太大
服务器拒绝处理请求由于请求实体太大以至达到服务器不肯意去处理。服务器可能关闭此链接去防止客户端继续请求。

若是条件是暂时的,服务器应该包含一个Retry-After头域用来指明此请求是暂时的而且什么时间后客户端应该重试。

10.4.15 414 请求URI太长(Request-URI Too Long)
服务器拒绝为请求服务由于此请求URI太长了以致于服务器不能理解。这种状况是不多的,只发生在当客户端把POST请求不合适地转换为带有大量查询信息的GET请求时。

10.4.16 415 不被支持的媒体类型(Unsupported Media Type)
服务器拒绝为请求服务由于请求的实体的格式不能被请求的资源支持。

10.4.17 416 请求范围不知足 (Requested Range Not Satisfiable)
服务器返回一个此状态码的响应,若是请求包含一个Range请求头域(见14.35节),而且此头域里range-specifier值不和选择资源的当前的extent值重叠,而且请求没有包含一个If-Range请求头域。(对byte-ranges来讲,这意味着byte-range-spec的全部first-byte-pos

值大于选择的资源的当前长度。

当此状态码响应在一个byte-range请求后返回时,此响应应该包含一个Content-Range实体头域用来指定选择资源的当前长度(见14.16节)。此响应不能利用multipart/byteranges媒体类型。

10.4.18 417 指望失败
Expect请求头域里指定的但愿不能被服务器知足,或者,若是服务器是代理服务器,服务器有有不肯定的理由肯定请求不能被下一站的服务器知足。

10.5 服务器错误 5xx (Server Error)
这类状态码指明服务器处理请求时产生错误或不能处理请求。除了HEAD请求,服务器应该包含一个实体,此实体用来解释错误,和是不是暂时或长期条件。用户代理应该展现实体给用户。此响应状态码能应用于任何请求方法。

10.5.1 500 服务器内部错误 (Internal Server Error)
服务器遇到了一个意外条件,此条件防止服务器知足此请求。

10.5.2 501 不能实现 (Not Implemented)
服务器不能支持知足请求的功能需求。这个响应是很合适的当服务器不能识别请求方法时而且不能支持它请求的资源的时候。

10.5.3 502 坏网关 (Bad Gateway)
此响应说明:服务器,看成为网关或代理时,它从上行服务器接收了一个无效的响应并尝试知足客户端的请求。

10.5.4 503 难以得到的服务.(Service Unavailable)
服务器不能处理请求因为服务器暂时的过载或维护。这就是说这是暂时条件,此条件将会在一些延时后被减轻。延迟的长度能够在Retry-After头域里指定。若是没有Retry-After被给,那么客户端应该处理此响应就像它处理500响应同样。

注意:503状态码的存在并非意指服务器当产生过载时必须利用它。一些服务器可能但愿拒绝此链接。

10.5.5 504 网关超时(Gateway Timeout)
服务器,看成为网关或代理服务器时,不能接收一个从被URI指定的上行服务器的响应(例如:HTTP,FTP,LDAP服务器)或者它为完成请求而须要访问的一些其余的辅助性服务器(例如:DNS服务器)。

注意:一些部署的代理服务器将会返回400或500响应当DNS查找超时。

10.5.6 505 HTTP版本不支持 (HTTP version Not Supported)
服务器不能支持,或拒绝支持,此HTTP协议版本消息。505响应指明服务器不能或不肯意完成这样的请求,这在3.1中描述了。此响应应该包含一个实体,此实体描述了为何此协议版本不被支持和其余的能被服务器支持的协议版本。

11.入口验证(Access Authentication)
HTTP提供一些可选的响应受权激发机制,这些机制能被用于服务器激发客户端请求而且使客户端受权。经常使用访问受权框架,还有“basic”和“digest”受权规范,都在“HTTP Authentication:basic and Digest Access Authentication”[43]规范里指定。HTTP/1.1规范采用了“激发(chanllenge)”和“证书(credentials)”的定义。

12.内容协商 (Content Negotiation)
大多数响应包含一个实体,此实体包含人类用户能理解的信息。一般,但愿提供给用户相应于请求最容易获得的实体。对服务器和缓存来讲,不幸的是,并非全部的用户都对这个最容易获得的实体有喜爱,而且并非全部的用户代理(如web浏览器)都能一致的呈现这些实体。因此,HTTP提供了一些“内容协商”机制 — 当有多个可得的表现形式的时候,对特定的响应选择最好的表现形式的处理过程。

注意:没有称作“格式协商”(译注:“格式”指的是“媒体类型”)的,由于可替换的表现形式可能会同原来的有相同的媒体类型,只是利用了此媒体类型不一样的性质,例如一种不一样的语言。

任何包含一个实体主体的响应包括错误响应均可能会受协商的支配。

有两种类型的内容协商在HTTP中:服务器驱动协商和代理驱动协商。这两种类型的协商具备正交性而且能被单独使用或联合使用。一个联合使用方法的协商会被叫作透明协商,当缓存利用代理驱动协商的信息的时候,此代理驱动协商的信息被为后续请求提供服务器驱动协商的源服务器提供。

12.1 服务器驱动协商(Server-driven Negotiation)
若是响应的最好的表现形式的选择是经过服务器上的算法来实现,那么这种方式的协商称作服务器驱动协商。选择是基于响应可得的表现形式(根据不一样的维度,响应会不一样;例如,语言,内容编码,等等)和请求消息里特定的头域或关于请求的其余信息(如:网络客户端的地址)。

服务器驱动协商是有优势的,当从可行的表现形式里进行选择的算法对用户代理进行描述是比较困难的时候(译注:代理驱动协商),或者当服务器指望发送“最好的猜想”给客户端而只经过一个响应(以免后续请求的回路(一个请求会返回一个响应)延迟若是此“最好的猜想“对用户适合的时候)的时候。为了改善服务器的猜想,用户代理应该包含请求头域(Accept,Accept-Language,Accept-Encoding,等等),这些头域能描述它对响应的喜爱。

服务驱动协商有以下缺点:

  1. 对服务器不可能确切的决定对用户来讲什么是最好的,由于那须要对用户代理和用户对此响应目的的全面理解(如:用户到底想把响应展现到屏幕仍是打印到纸上?)。
  2. 使用户代理描述请求里的能力是很是无效的(假设只有响应的一小部分有多个表现形式)还有会侵犯用户的隐私。
  3. 使源服务器的实现变得复杂,也对为请求产生响应的算法实现变得复杂。
  4. 可能会限制公有缓存(public cache)为多个客户请求利用相同响应的能力

HTTP/1.1包含下面的请求头域来使服务器驱动协商启动,这些请求头域描述了用户代理的能力和用户喜爱:Accept(14.1节),Accept-Charset(14.2节),Accept-Encoding(14.3节),Accept-Language(14.4节),和User-Agent(14.43节)。然而,一些源服务器并不仅局限于这些维度,这些服务器能基于请求的任何方面来让响应不一样,这些方面包括请求头域以外的信息或在此规范里没有定义的扩展头域。

Vary头域能被用来表达服务器选择表现形式(representation)利用的参数,表现形式受服务器驱动协商的支配。见14.44节描述了Vary头域如何被服务器的使用,13.6节描述了Vary头域被缓存的使用。

12.2 代理驱动协商 (Agent-driven Negotiation)
对代理驱动协商来讲,响应的最好表现形式的选择被用户代理执行,这在接收到源服务器一个初始的响应后。选择是基于响应的一系列可得的表现形式,这些表现形式被包含在初始响应的头域或初始响应的实体主体(entity-body)里,每一个表现形式被一个属于本身的URI指定。从这些表现形式中选择可能被自动执行(若是用户代理有能力这样作)或者被用户从超文本链接菜单中手工选择。

代理驱动协商是有优势的,当响应可能会根据通常用途的维度(如:类型,语义,编码)而不一样的时候,当源服务器不能经过查看请求而断定用户代理能力的时候,当共有缓存(public cache)被用来分派服务器的承载和减小网络使用的时候。

代理驱动协商也一样存在须要第二次请求而得到最好表现形式的缺点。第二次请求只有当缓存被使用时才是有效率的。另外,此规范没有定义用户代理自动选择表现形式的机制,因此不能防止任何这样的机制被用于HTTP/1.1

HTTP/1.1定义了300(多个选择)和406(不接受的)状态响应,当使用代理驱动协商时服务器不能或不肯意利用服务器驱动协商来提供一个不一样的响应的是时候。

12.3 透明协商(Transparent Negotiation)
透明协商是服务器驱动协商和代理驱动协商的结合体。当一个缓存被提供了构成响应的一系列可得的表现形式(就像在代理驱动协商里的响应同样)而且维度的差别能彻底被缓存理解,那么此缓存变得有能力表明源服务器为那个资源的后续请求去执行服务器驱动协商。

透明协商的优势在于它能分发源服务器的协商工做而且能移去代理驱动协商的第二次请求的延迟,由于缓存能正确的猜想到合适的响应。

此规范没有定义透明协商的机制,因此,它不能防止任何这样的机制被用于HTTP/1.1。

13 HTTP中的缓存
HTTP典型应用于能经过采用缓存技术而提升性能的分布式信息系统。HTTP/1.1协议包括的许多使缓存尽量的工做的元素。由于这些元素与协议的其余方面有着千丝万缕的联系,并且他们相互做用、影响,所以有必要单独的来介绍基本的缓存设计。

若是缓存不能改善性能,他将一无用处。HTTP/1.1中缓存的目的是为了在不少状况下减小发送请求,同时在许多状况下能够不须要发送完整响应。前者减小了网络回路(译注:一个请求会返回一个响应,请求响应这个过程就是一个回路)的数量;咱们利用一个“过时(expiration)”机制来为此目的(见13.2节)。后者减小了网络应用的带宽;咱们用“验证(validation)”机制来为此目的。

对行为,可行性,和关闭的操做的要求放松了语义透明性的目的。HTTP/1.1协议容许服务器,缓存,和客户端能显示地下降透明性当在必要的时候。然而,由于不透明的操做能混淆非专业的用户,同时可能和某个服务器应用程序不兼容(例如订购商品),所以此协议透明性在下面状况下才能被放松要求:

-- 只有在一个显示的协议层的请求时,透明性才能被客户端或源服务器放松

-- 当出现一个对终端用户的显示的警告时,透明性才能被缓存或被客户端放松

所以,HTTP/1.1协议提供这些重要的元素:

1.提供完整语义透明的协议特征,当这些特征被通讯的全部方须要时

  1. 容许源服务器或用户代理显示的请求和控制不透明操做的协议特征
  2. 容许缓存给这样的响应绑定警告信息的协议特征,这些响应不能保留请求的语义透明的近似

一个基本的原则是客户端必须可以发现语义透明性的潜在的放松。

注意:服务器,缓存,或者客户端的实现者可能会面对设计上的判断,而这些判断没有显示地在此规范里讨论。若是一个判断可能会影响语义透明性,那么实现者应该能维持语义透明性,除非一个仔细的完整的分析能说明打破透明性的好处。

13.1.1缓存正确性(Cache Correctness)
一个正确的缓存必须能用最新的响应来响应请求,此响应当在下面的条件知足时才适合此请求(见13.2.5,13.2.6,和13.12)

此缓存响应已被检测与假设经过源服务器重验证后源服务器返回的响应相等价。

此缓存响应是足够保鲜(fresh)的(见13.2节)。缺省的状况下,这意味着此响应必须知足客户端,源服务器,和缓存的最严格的保鲜要求(见14.9节);若是源服务器指定了保鲜寿命,这说明它是源服务器本身的保鲜要求。

因为客户端和源服务器的最严格的保鲜要求,若是一个缓存的响应不是足够保鲜的,那么在仔细考虑的状况下,缓存可能仍然返回此缓存的响应经过合适的Warning头域(见13.1.5和14.46节),除非此响应被阻止(例如:经过”no-store” cache-directive ,或者经过一个”no-cache”cache-request-directive;见14.9节)。

此缓存响应是一个304(没有被改变),305(代理重定向),或 错误(4xx或者5xx)响应消息。

若是缓存不能同源服务器通讯,那么一个正确的缓存应该用它缓存的响应去响应请求,若是此缓存的响应能正确的服务于请求;若是不能服务器于此请求,那么缓存必须能返回一个错误或警告指示存在通讯失败。

若是缓存从服务器端接收到一个响应(或者是一个完整的响应,或者一个304(没有被改变)的响应),此响应应该是正常状况下要发送到请求的客户端的,而且此响应并非新鲜的,那么此缓存应该把此响应转发给请求客户端不须要添加一个新的Warning头域(可是没有移去已经存在的Warning头域)。缓存并非简单的由于传输中响应变得陈旧而尝试去重验证响应;这可能会致使一个无限的循环。用户代理接收一个陈旧的没有Warning头域的响应应该提示用户一个警告信息。

13.1.2警告信息(Warnings)
不管什么时候,缓存返回一个响应,此响应既不是第一手的(first-hand)也不是足够保鲜(在13.1.1节的条件2),那么缓存必须利用一个Warning经常使用头域来警告产生的效果。Warning头域和当前定义的警告在14.46节里描述。这些警告容许客户端去采起合适的动做。

警告可能被用于其余的目的,和缓存相关的目的和其余的目的。警告和错误状态码的区别在因而否是真正的失败。

警告被赋予三位数字warn-codes。第一个数字指明:警告是否必须或没必要须从缓存项里删除,在一个成功的重验证以后。

1xx 警告描述了响应的保鲜或重验证状态信息,而且这些信息应该在一个成功的重验证以后删除。1xx警告码多是由缓存产生的,当缓存验证一个缓存项时。此警告码不能被客户端产生。

2xx 警告描述了实体主体或实体头域的某些方面的信息,这些信息不能被重验证修改,而且这些信息不能在一个成功重验证以后被删除。

见14.46节关于警告码的定义。

HTTP/1.0缓存将缓存全部响应中的警告,而且不会删除第一类警告。穿过HTTP/1.0缓存响应中的警告会携带一个额外的warning-date域,这是为了防止未来的HTTP/1.1接收端信任一个错误的缓存警告。

警告一样携带一个警告文本。此文本多是任何合适的天然语义(可能基于客户端请求的Accept头域),同时包含一个可选择的关于何种字符集被使用的声明。

多个警告可能会绑定一个响应(或者被源服务器或者被一个缓存发送的),这包括多个警告能够共用一个警告码。例如,服务器可能会以英语和法语提供相同的警告。

当多个警告绑定一个响应时,有时候不可能把全部的警告都展现给客户。HTTP版本不能指定一个严格的优先值去决定警告的优先和顺序显示,可是能够探索一些方法。

13.1.3缓存控制机制 (Cache-control Mechanism)
HTTP/1.1基本的缓存机制(服务器指定过时时间和验证器)对缓存是隐含的指令。某些状况下,服务器或客户端可能须要给HTTP缓存提供显示的指令。咱们利用Cache-Control头域为此目的。

Cache-Control头域容许客户端或服务器在请求或响应里传输多个指令。这些指令经常覆盖缺省的缓存算法。做为一个经常使用规则,若是头域值中存在一个明显的冲突,那么最具严格解释的头域值会被应用(也就是说,能保留语义透明性的值)。然而,一些状况下,cache-control指令被显示地指定用来削弱语义透明性的类似性(例如,”max-stale” 或者 “public”)。

Cache-control指令在14.9节被描述。

13.1.4显示的用户代理警告(Explicit User Agent Warnings)
不少用户代理容许用户覆盖基本缓存机制。例如,用户代理可能容许用户指定缓存实体(即便实体明显是陈旧的)历来不要被验证。或者,用户代理可能习惯于给任何请求加上“Cache-Control:max-stale=3600”。用户代理不能缺省的执行不透明行为,或者不能缺省的执行致使非正常的无效率的缓存行为,可是可能被显示地设置去这样作经过一个显示的用户动做。

若是用户已经覆盖基本的缓存机制,那么用户代理应该给用户指示什么时候显示不能知足服务器透明要求的信息(特别地,若是显示的实体被认为是陈旧的)。由于此协议一般容许用户代理去断定响应是不是陈旧或不是陈旧的,因此此指示只须要当实际发生时显示。此指示没必要是对话框;它应该是一个图标(例如,一个正在腐烂的鱼)或者一些其余的指示器。

若是用户以一种方式已经覆盖了缓存机制,这种方式可能不正常地减小缓存效率,那么用户代理应该继续指示用户的状态(例如,经过一个图片显示)以便用户不能不注意地消费过分的资源或者忍受过分的延迟。

13.1.5规则和警告的例外状况
在某些状况下,缓存的操做者应该设置缓存返回陈旧的响应,即便此响应没有被客户端请求。这个断定原本不该该轻易决定,可是因为某些缘由可能会这样作,特别是当缓存和源服务器链接很差时。无能什么时候当缓存会返回一个陈旧的响应时,缓存必须给此响应作个标记(利用Warning头域),由于这样能使客户端提示用户响应是陈旧的。

用户代理照样能采起步骤去得到第一手的或保鲜的响应。因为这个缘由,若是客户端显示地请求第一手的或保鲜的响应,缓存就不能返回一个陈旧的响应,除非因为技术或策略方面的缘由。

13.1.6由客户控制的行为(Client-controlled Behavior)
当源服务器是过时信息得主要来源时,有时候客户端可能须要控制缓存去断定是否返回一个缓存响应而不须要缓存经过服务器验证它。客户端经过利用一些Cache-Control头域来达到此目的。

客户端的请求可能会指定本身愿意接受一个没有验证的响应的最大的年龄(age);指定0值会强迫缓存重验证全部的响应。客户端照样会指定在响应过时前的最小保持时间。这些选项增长了对缓存行为的限制,同时这样作并不能进一步地放松缓存语义透明的近似。

客户端可能照样会指定它会接受陈旧响应直到陈旧数达到最大数量。这放松了对缓存的限制,同时这可能违反了源服务器指定对语义透明性的限制,可是这可能支持无链接的操做或者高得到性当链接很差时。

13.2 过时模型 (Expiration Model)
13.2.1 服务器指定模型(Server-Specified Expiratiion)
HTTP缓存会工做的很好,这是由于缓存能彻底地避免客户端对源服务器的请求。避免对源服务器请求的主要机制是服务器未来会提供一个显示过时时间(explicit expiration time),此显示过时时间用来指示响应可能会知足后续的请求。也就是说,客户端请求响应时,缓存能返回一个保鲜(fresh)的响应而不须要从源服务器那里得到。

咱们但愿服务器给响应设置显示过时时间(explicit expiration time),服务器相信在过时时间以前实体不会改变。这能保持语义透明性(译注:语义透明性状况1.3节里关于“语义透明”的解释),只要服务器对过时时间仔细选择。

过时机制只能应用于能从缓存得到的响应,不能应用于客户端请求的第一手(first-hand,见1.3节术语)的响应。

若是源服务器但愿强制一个语义透明缓存去验证每一个请求,它会使显示过时时间(explicit expiration time)设为过去。这就是说响应老是陈旧的,因此此缓存应该验证此响应当缓存利用此响应去服务于后续的请求时。见14.9.4节,有更多强迫重验证的方法

若是源服务器但愿强迫任何HTTP/1.1缓存(无论此缓存是怎样设置的)去验证每个请求,源服务器应该在Cache-Control头域里指定“must-revalidate”缓存控制指令(见14.9节)。

源服务器利用Expires头域或在Cache-Control头域里经过max-age缓存控制指令,来指定显示过时时间(explicit expiration time)。

过时时间不能被用于强制客户代理去从新刷新它的显示或重载资源;过时的语义只能应用于缓存机制,而且这个机制值只须要检测资源的过时状态当请求那个资源的一个新请求发生时。见13.13节,关于缓存和历史机制的区别。

13.2.2 启发式过时
由于源服务器不能老是提供一个显示过时时间(explicit expiration time),HTTP缓存一般会设置一个启发式过时时间(heuristic expiration time),它采用一种算法,此算法利用其它的值(例如Last-Modified时间)去估计一个彷佛合理的过时时间。HTTP/1.1规范没有提供特定的算法,可是的确是增强了对这些算法结果的最坏状况的限制。由于启发式过时时间可能会对语义透明性妥协,他们本应该被谨慎地使用,而且咱们鼓励源服务器尽量提供显示过时时间。

13.2.3 年龄(Age)计算
为了了解缓存项(译注:缓存项是用来响应请求的,它包含缓存的响应实体)是不是保鲜的(fresh),缓存须要知道其年龄是否已超过保鲜寿命(freshness lifetime)。咱们在13.2.4节中讨论如何计算保鲜寿命,本节讨论如何计算响应或缓存项的年龄。

在此讨论中咱们用“now”来表示主机进行计算时时钟的“当前值”。使用HTTP协议的主机,特别是运行于源服务器和缓存的主机,应该使用NTP[28] 或其余相似协议来将其时钟同步到一个全球性的精确时间标准上。

HTTP1.1协议要求源服务器尽量在发送每条响应时都附加一个Date头域,要尽量在每一个响应里给出响应产生的时间(见14.18节)。咱们利用术语“date_value”去表示Date头域的值,这是一种适合于运算操做的表示方法。

当从缓存里获取响应消息时,HTTP/1.1利用Age响应头域来传送响应消息的估计年龄。Age响应头域值是缓存对响应从产生或被重验证开始到如今的时间估计值。

实际上,年龄的值是响应从源服务器途径每个缓存的逗留时间的总和,再加上响应在网络路径上传输的时间。

咱们用“age_value”来表示Age头域的值,这是一种适于算术操做的表示方法。

一个响应的年龄(age)能够经过两种彻底不一样的途径来计算::

若是本地时钟与源服务器时钟同步的至关好,则用 now - date_value ,若结果为负,则取零。

若是途径响应路径(response path)的全部缓存均遵循HTTP1.1协议,则用age_value。

若是咱们有两种独立的方法计算响应的年龄(译注:注意这里是响应的年龄),咱们能够合并两者以下:

corrected_received_age = max(now – date_value,age_value)

而且只要咱们或者有同步的时钟或者响应途径的全部缓存遵循HTTP/1.1,咱们就能获得一个可信赖的结果。

因为网络附加延时,一些重要时隙会在服务器产生响应与下一个缓存或客户端接收之间流逝。若是不经修订,这一延迟会带来不正常的低年龄。

因为致使产生年龄值的请求(译注:就是存在Age头域的请求)是早于年龄值的产生,咱们能校订网络附加延迟经过记录请求产生的时间。而后,当一个年龄值被接收后,它必须被解释成相对于请求产生的时间,而不是相对响应接收的时间。无论有多少延迟,此算法会致使稳定的结果。因此,咱们计算:

corrected_initial_age = corrected_received_age + (now - request_time)

这里“request_time”是请求的发送时间。

缓存收到响应时,它计算响应年龄的算法以下:

/*

   * age_value

   *      is the value of Age: header received by the cache with this response.

   * date_value

   *      is the value of the origin server's Date: header

   * request_time

   *      is the (local) time when the cache made the request

   *              that resulted in this cached response

   * response_time

   *      is the (local) time when the cache received the response

   * now

   *      is the current (local) time

   */

  apparent_age = max(0, response_time - date_value); //缓存收到响应时响应的年龄

  corrected_received_age = max(apparent_age, age_value);

  response_delay = response_time - request_time;

  corrected_initial_age = corrected_received_age + response_delay;

  resident_time = now - response_time; //即收到响应到如今的时间间隔

  current_age   = corrected_initial_age + resident_time;

缓存项(cache entry)的current_age是缓存项从被源服务器最后验证开始到如今的时间间隔(以秒记)加上corrected_initial_age。当从缓存项里产生一条响应时,缓存必须在响应里包含一个Age头域,它的值应该等于缓存项的current_age值。

Age头域出如今响应里说明响应不是第一手的(first-hand)(译注:第一手的说明,响应是直接来自于源服务器到达接收端的,而不是来自于缓存里保存的副本)。然而相反的状况并不成立,由于响应里缺乏Age头域并不能说明响应是第一手的(fisrt-hand),除非全部请求路径上的缓存都遵循HTTP/1.1协议(也就是说,之前HTTP版本缓存没有定义Age头域)。

13.2.4 过时计算(Expiration Calculations)
为了肯定一条响应是保鲜的(fresh)仍是陈旧的(stale),咱们须要将其保鲜寿命(freshness lifetime)和年龄(age)进行比较。年龄的计算见13.2.3节,本节讲解怎样计算保鲜寿命,以及断定一个响应是否已通过期。在下面的讨论中,数值能够用任何适于算术操做的形式表示。

咱们用术语“expires_value”来代表Expires头域的值。咱们用术语“max_age_value”来表示Cache-Control头域里“max-age”控制指令的值(见14.9.3节)。

max-age指令优于Expires头域执行,因此若是max-age出如今响应里,那么定义以下:

freshness_lifetime = max_age_value

不然,若Expires头域出如今响应里,定义以下:

freshness_lifetime = expires_value - date_value

注意上述运算不受时钟偏差影响,由于全部信息均来自源服务器。

若是Expires, Cache-Control:max-age, 或 Cache-Control:s-maxage (见 14.9.3) 均未在响应中出现,且响应没有包含对缓存的其余控制,那么缓存能够用启发式算法计算保鲜寿命(freshness lifetime)。缓存器必须对年龄大于24小时的响应附加113警告,若是此响应不带这种警告。

并且,若是响应有最后修改时间,启发式过时值应不大于从那个时间开始间隔的某个分数。典型设置为间隔的10% 。

计算响应是否过时很是简单:

response_is_fresh = (freshness_lifetime > current_age)

13.2.5澄清过时值(Disambiguation Expiration Values)
因为过时值很容易被设置,有可能两个缓存会包含同一资源的不一样保鲜值。

若是客户端执行请求接收到一个非第一手的响应,此响应在此客户端拥有的缓存里仍然是保鲜的,而且缓存里的缓存项里的Date头域的值比此新响应的Date头域值要新,那么客户端应该忽略此响应。若是这样,它可能会从新以“Cache-Control:max-age=0”指令(见14.9节)请求去强制任何中间缓存经过源服务器对其进行检查。

若是缓存对有不一样验证器(validator)的同一个表现形式(representation)有两个保鲜响应,那么缓存必须利用Date头域值最近的响应。这种状况可能发生因为缓存会从其余缓存获得响应,或者因为客户端请求对一个保鲜缓存项的重载或重验证(revalidation)。

13.2.6澄清多个响应(Disambiguating Multiple Response)
由于客户端可能收到经多个路径而来的响应,因此有些响应会通过一些缓存,而其余的响应会通过其余的缓存,客户端收到响应的顺序可能与源服务器发响应的顺序不一样。咱们但愿客户端利用最新的响应,即便旧响应仍然是保鲜的。

实体标签(entity tag)和过时值都不能影响响应的顺序,由于可能会出现晚一点的响应可能会故意携带过早的过时时间。日期值的精度被规定只有一秒。

当客户端试着从新验证一个缓存项的时候(译注:这里的客户端应该包含一个本地缓存),并且接收到的响应的Date头域晚于已存在的缓存项,那么客户端应该从新进行无条件请求,而且包含

Cache-Control: max-age=0

去强制任何中间缓存经过源服务器来验证(validate)这些中间缓存的副本,或者

Cache-Control: no-cache

去强制任何中间缓存去从源服务器得到一个新的副本。

13.3 验证模型(Validation Model)
当缓存有一个旧缓存项而且缓存想利用此缓存项来做为客户端请求的响应时,缓存必须首先经过源服务器(或者可能经过一个有保鲜响应的中间缓存)对其进行检验看看此缓存项是否可用。咱们称作“验证(validating)”此缓存项。由于咱们不想对完整响应的传输付出太大代价,并且若是缓存项无效时也不会产生额外的回路(译注:回路的意思,如:从请求到响应就一条回路),HTTP1.1协议支持使用条件方法。.

协议支持条件方法的关键特征是围绕“缓存验证器(cache validator)”展开的。当源服务器产成一个完整响应时,它同时会附加一些验证器给响应,这些验证器和缓存项一块儿保存。当客户端(用户代理或缓存服务器)对对应有缓存项的资源执行条件请求时,客户端包含一个相关的验证器(validator)在请求里。

服务器(译注:服务器多是缓存服务器)则核对请求里的验证器和当前本地的验证器是否匹配,若是他们匹配(见13.3.3),则返回一个特定状态码(一般为304(没有改变))的响应而且此响应不包含实体主体(entity body)。若是不匹配,服务器就返回完整响应(包含实体主体)。这样,咱们就避免了传输完整响应若是验证器匹配,同时咱们也避免了额外的回路若是验证器不匹配。

在HTTP1.1协议中,一个条件请求和普通的请求差很少,除了条件请求携带一些特殊的头域(这些头域包含验证器),包含这些特殊的头域隐含地代表请求方法(一般是GET方法)为条件请求方法。

协议中包括缓存验证条件的正和负。也就是说请求方法将会执行若是验证器的匹配或不会执行若是验证器不匹配。

注意:缺乏验证器的响应可能会被缓存,并且会被缓存用来为请求提供服务直到缓存的副本过时,除非显示地用缓存控制指令来禁止缓存这样作。然而,缓存不能执行条件方法获取资源若是它没有此资源实体的验证器,那意味着缓存副本将会不可更新在它过时后。

13.3.1最后修改日期 (Last-Modified Dates)
Last-Modifed实体头域值常常被用做一个缓存验证器。简而言之,缓存项被认为是有效的若是实体自从Last-Modifed值以后没有改变。

13.3.2 实体标签缓存验证器(Entity Tag Cache Validators)
ETag响应头域值是实体标签,它提供了一个“不透明(opaque)的缓存验证器。这能获得更可靠的验证当在不方便存放修改日期的状况下,当在HTTP日期值的一秒精度不能知足须要的状况下,或当在源服务器但愿避免使用修改日期产生的冲突的状况下。

实体标签在3.11节描述了。使用了实体标签的头域在14.19,14.24,14.26和14.44节里描述了。

13.3.3 强,弱验证器 (Weak and Strong Validators)
因为源服务器和缓存会比较两个验证器来肯定他们是否表明相同的实体,因此一般但愿实体(entity,实体主体或实体头域)发生任何变化时验证器也相应变化,这样的验证器为强验证器。.

然而,可能存在这样的请求,服务器倾向于仅在实体发生重要的语义变化时才改变验证器,而在实体的某些方面不发生重大改变时就不改变验证器。在资源变化时验证器未必变化的称为弱验证器.。

实体标签一般是强验证器,但协议提供一种机制来使实体标签变成弱验证器。能够认为强验证器在实体的每一字节变化时而变化,而弱验证器仅在实体的语义变化时才变化。换言之,咱们能认为强验证器是特定实体的标识,而弱验证器是同一类语义等价实体的标识。

注: 强验证器的例子:一个整数他会随着每次实体发生变化而递增。一个实体的修改时间,若是以秒为精度,能被看成弱验证器,由于在一秒内资源可能改变两次。是否支持弱验证器是选择的。然而,弱验证器能够能高效的去缓存等效对象。

.

客户端产生请求并把验证器包含在一个验证头域里的时候或在服务器比较两个验证器的时候均用到验证器。强验证器可在任何状况下使用,而弱验证器仅在不依赖严格相等时才可用。当客户端产生条件GET请求来请求一个完整实体时,任何类型的验证器均可以使用。然而,子范围(sub-range)请求时只能使用强验证器,由于客户端可能会获得一个不一致的实体。

客户端能够在发出简单(非子范围)GET请求里既能够包含弱验证器也能够包含强验证器。客户端不能利用弱验证器在其它的请求形式里。

HTTP1.1协议定义验证的惟一功能就是比较。有两种验证器的比较方法,这依赖因而否能利用弱验证器进行比较。

.

  • 强比较方法:在考虑相等的状况下,两验证器必须彻底一致,而且两个验证器都是强验证器。.
  • 弱比较方法:在考虑相等的状况下,两验证器必须彻底一致,但至少有一个验证器可能在不影响结果的状况下被标明为“weak”。

实体标签是强验证器除非它被显示地标记为弱(weak)的。3.11节给出了实体标签的语法。

最后修改时间(译注:Last-Modifed头域的值)被用做请求的验证器时默认为弱验证器,,除非知足下列规则才断定它是强验证器:.

  • 验证器被源服务器用来和当前实体的验证器进行比较而且源服务器知道相关的实体不会在当前验证器函盖的秒数内改变两次,

或者

  • 验证器可能被客户端用于If-Modified-Since 或者 If-Unmodified-Since头域里,由于客户端有一个关于此实体的缓存项,而且
  • 缓存项包含一个日期值,此日期值给出了源服务器发送源响应(译注:源服务器产生的响应)的时间,而且
  • Last-Modifed头域值至少提早于日期值(Date头域值)60秒。

或者

  • 验证器已经被中间缓存同此实体的缓存项里的验证器比较过 ,而且
  • 缓存项包含日期值(Date头域值),此日期值指明了源服务器发送源响应的时间,而且
  • Last-Modifed头域值至少提早于日期值(Date头域值)60秒。

此种方法依赖于如下事实,若是两个响应被服务器在同一秒内被发出,但这两个响应都有相同的最后修改(Last-Modified)时间,那么至少有一个响应的日期值(译注:Date头域的值)和最后修改时间值(Last-Modifed头域的值)是相等的。60秒的限制能保证Date和Last-Modifed头域的值在不一样时刻产生。一个实现可能会利用大于60秒的值,若是它认为60秒过短。

若是客户端但愿执行子范围(sub-range)请求来请求一个只有最后修改(Last-Modifed)时间和而没有透明验证器的值时,它可能会认为只有最后修改(Last-Modified)时间是强的。

若缓存或源服务器收到一个条件请求,而不是获得完整响应的GET请求时,他必须使用强比较方法去计算此条件。

此规定容许HTTP1.1的,缓存和客户端安全地执行子范围(sub-range)请求来请求从HTTP/1.0得来的值。

13.3.4 关于什么时候使用实体标签和最后修改时间的规则
咱们对源服务器,客户端和缓存采用一套规则和建议来规定不一样的验证器什么时候应该被使用,出

于何种目的被使用。

HTTP/1.1 源服务器:

  • 应该发送一个实体标签验证器除非源服务器产生这样一个实体标签不可行。
  • 可能会发送弱实体标签而不是强实体标签,若是使用弱实体标签能提升性能的话或者若是发送一个强实体标签不可行的状况下。
  • 应该发送一个Last-Modifed值若是可行的话,除非打破语义透明性(这可能由利用If-Modified-Since头域里的日期产生)可能会致使严重的后果。

换句话说,对http1.1源服务器来讲,比较好的作法是同时发送强实体标签和Last-Modified值。.

为了合法,强实体标签必须随相关联的实体值改变而改变。弱实体标签应该随相关联的实体在语义上发生改变而改变。

注意:为保证语义透明缓存,源服务器必须避免为两个不一样的实体重复利用一个特定的强实体标签值。缓存项应该能保持任意长的时间,而无论过时时间(expiraton time),因此缓存可能会再去尝试去利用在过去某一时刻得到的验证器去验证缓存项。

HTTP/1.1 客户端:

  • 若实体标签被源服务器提供,HTTP/1.1客户端必须在任何缓存条件请求(利用了If-Match或If-None-Match的请求)里利用实体标签.。
  • 仅当Last-Modified值被源服务器提供时,HTTP/1.1客户端应该在非子范围缓存条件请求(利用If-Modified-Since)里利用此值。
  • 仅当Last-Modified值被HTTP/1.0源服务器提供,HTTP/1.1客户端可能会在子范围缓存条件请求(利用了If-Unmodified-Since)里利用此值。
  • 若是一个实体标签和Last-Modified值被源服务器提升,HTTP/1.1客户端应该在缓存条件请求里利用这两个验证器。这容许HTTP/1.1和HTTP/1.1缓存能合适地进行响应。

HTTP/1.1源服务器,当接收到一个条件请求而且此请求同时包含Last-Modifed日期(例如,在If-Modified-Since,或If-Unmodified-Since头域里)和一个或多个实体标签(例如在If-Match,If-None=Match,或If-Range头域里)做为缓存验证器时,源服务器不能返回一个304状态响应(Not Modified)除非这样作能当当前实体的验证器和请求里全部的条件头域里的验证器一致。

HTTP/1.1缓存服务器,当接收到一个条件请求而且此请求里同时包含Last-Modified日期和一个或多个实体标签做为缓存验证器时,它不能返回一个本地的副本给客户端除非那个副本的验证器和全部请求里条件头域里的验证器一致。

注意:这些规则背的经常使用的原则是HTTP/1.1服务器和客户端应该在请求和响应里尽量传输非冗余的信息。接收这些非冗余信息的HTTP/1.1系统将会假设它接收了验证器。

HTTP/1.0客户端和缓存将会忽略实体标签。一般,Last-Modified值被这些系统接收后将会保证透明和高效的缓存行为,因此HTTP/1.1源服务器这时将会提供Last-Modified值。在这些状况下,当HTTP/1.0系统利用一个Last-Modified值做为一个验证器可能会带来严重的后果时,HTTP/1.1服务器将不会提供Last-Modified值。

13.3.5非验证条件(Non-validating Conditionls)
实体标签背后的原则是只有服务的做者才知道资源的语义而去选择一个合适的缓存验证机制,而且任何验证器比较方法的标准均可能会带来风险。因此,任何其余的头域的比较(除了Last-Modified,为了兼容HTTP/1.0)历来不会被用于验证缓存项。

13.4 响应的可缓存性(Response Cacheability)
除非被缓存控制(见14.9节)指令明确地限制,缓存系统能够将一成功的响应做为缓存项,能够返回缓存项里的响应副本而不须要验证它若是此副本是保鲜的,而且也能够在验证成功后返回它。若是既没有和响应相关的缓存验证器也没有和响应相关的显示过时时间(explicit expiration time,译注:见13.3.1节里关于什么是显示过时时间的说明),咱们不会认为它是可缓存的,可是某些缓存可能会违反这个指望(例如,当不能进行网络链接时)。客户端能常常发现从缓存里得到的响应,只须要经过把Date头域值同当前时间做比较。

注意:某些HTTP1.0缓存可能违反这一指望而不提示警告。

还有,某些状况下可能不便保留一实体,或将其返回给后续请求.

然而,在一些状况下,缓存不适合保存一个实体,或者不适合把它放于后续请求的响应里。这可能由于服务做者认为彻底语义透明性是有必要的,或着由于安全和隐私的考虑。某些缓存控制指令是为了让服务器能指明某些资源实体或其中的一部分不能被缓存。

注意在14.8节里描述了防止一个共享缓存去保存和返回一个之前请求的响应,若是那个请求包含一个Authorization头域。

除非缓存控制指令防止此响应被缓存,一个接收的响应若是它的状态码是200,203,206,300,301或410,那么此响应应该被缓存保存并且可用于后续的请求,但这必须受限于过时机制(expiration mechanism)。然而,缓存若是不支持Range和Content-Range头域,那么它不能缓存206响应(部份内容)响应。

接收到的响应若是是其余的状态码(如,302和307),那么此响应不能被用于服务于后续的请求,除非缓存控制指令或其余的头域明确地容许它能这样作。例如,这些头域包含下面的头域:Expires头域(见14.21);“max-age”,“s-maxage”,“must-revalidate”,“prox-revalidate”,“public”或“private”缓存控制指令(见14.9)。

13.5 从缓存里构造响应
缓存的目的是存储请求的响应信息,为了响应未来的请求。在不少状况下,缓存能返回响应的合适部分给请求者。然而,若是缓存拥有一个基于之前响应的缓存项,它可能必须把新响应的部分和它缓存项里的内容合起来。

13.5.1End-to-end和Hop-by-hop头域
为定义缓存和非缓存代理服务器的行为,咱们将HTTP头域分红两类:

  • end-to-end头域,他们被传输给最终请求或响应的接收者。响应里end-to-end头域必需做为缓存项的一部分存储,而且必须在从缓存项造成的响应里传输。
  • hop-by-hop头域,他们被只对传输层上的链接有意义,而且不能被缓存保存或被代理转发。

下面的HTTP/1.1头域是hop-by-hop头域:

  • Connection
  • Keep-Alive
  • Proxy-Authenticate
  • Proxy-Authorization
  • TE
  • Trailers
  • Transfer-Encoding
  • Upgrade

全部其余被HTTP/1.1定义的头域均为end-to-end头域。

13.5.2不可更改的头域 (Non-modifiable Headers)
HTTP1.1的某些特征,如数字认证,基于某一些end-to-end头域。一个透明代理不该该改变end-to-end头域,除非这些头域的定义要求或容许它这样作。

一个透明代理(译注:代理通常是缓存,缓存能够叫缓存代理,缓存服务器,代理服务器)不能改变请求或响应里的下面的头域,并且它不能添加这些头域到没有这些头域的请求或响应里:

  • Contents-location
  • Content-MD5
  • ETag
  • Last-Modified

一个透明代理不能改变响应里下面的的头域:

  • Expires

但它能够添加这些头域若是响应里没有这些头域的时候。若是一个Expires头域被添加,它必须等于响应里Date头域的值。

一个代理(译注:缓存就是一个代理,咱们通常称作缓存代理,或缓存服务器,或缓存代理服务器,都是一个意思)不能在消息中改变或添加下面的头域若是此消息包含no-transform缓存控制指令,或在任何请求里也不能添加或改变这些头域。

  • Content-Encoding
  • Content-Range
  • Content-Type

一个非透明代理可能会改变或添加这些头域给一个消息若是此消息不包含no-transform缓存控制指令,可是若是代理这样作了,它必须添加一个警告214(转换被应用)(见14.46节)。

警告:end-to-end头域的没必要要的改变可能会致使认证机的失败若是更强的认证机制被应用于后续的HTTP版本中。此认证机制可能依赖于没有在此出现的头域值。

请求或响应里的Content-Length头域被添加或被删除会根据4.4节的规则。一个透明代理必须保留实体主体的entity-length(见7.2.2),尽管它能够可能改变transfer-length(4.4节)。

13.5.3联合头域(Combining Headers)
当一个缓存对服务器发出验证请求时,并且服务器提供304(没有改变)响应或206(部份内容)响应时,那么缓存将构造一个响应发送给请求客户端。

若是状态码是304(没有改变),缓存利用缓存项里的实体主体(entity-body)做为客户端请求响应的实体主体。若是响应状态码是206(部份内容)而且Etag或Last-Modified头域能精确匹配,那么缓存可能把存入缓存项里的内容和接收到的响应里的新内容合并而且利用最后合并的结果做为输出响应(见13.5.4)。

存储于缓存项里端end-to-end头域被用于构造响应,除了:

  • 任何存储的警告码是1xx(见14.46)Warning头域必须从缓存项和转发的响应里删除。
  • 任何存储的警告码是2xx的Warning头域必需要在缓存项和转发的响应里保留。
  • 任何在304或206响应里的end-to-end头域必须替换缓存项里相应的头域

除非缓存决定去删除缓存项,不然它必须照样能用接收的响应里的相应的end-to-end头域去替换存储在缓存项里的头域,除了上面描述的Warning头域。若是输入响应里的一个头域匹配缓存项里多个头域,那么全部这些旧的头域必须被替换。

从另外一方面说,输入响应的全部end-to-end头域会覆盖缓存项里全部相应的end-to-end头域(除了缓存的警告码是1xx的Warning头域,它将会被删除即便没有被覆盖)。

注意:此规则容许源服务器去利用304(没有改变)或一个206(部份内容)响应去更新任何同一实体或实体的子范围的之前响应的头域,虽然它可能没有意义或这样作不正确。这条规则不容许源服务器去利用304(没有改变)或206(部份内容)响应去彻底地删除一个之前响应的头域。

13.5.4联合字节范围(Combing Byte Ranges)
一条响应可能仅传送一个实体主体的某一部分,这是因为请求包含一个或多个Range指定的范围,或者因为链接会被过早地断开。在几回这样得传输后,缓存可能已经接收了同一个实体主体的多个范围部分。

若是缓存有一个实体的非空子范围,而且一个输入(incoming)响应(译注:输入响应是进入缓存的响应,输出响应是从缓存出去的响应)携带了另外一个子范围,那么缓存可能会把新的子范围和已经存在的子范围联合起来若是二者遵循下面的规则:

  • 输入响应和缓存项都有缓存验证器。
  • 当利用强比较方法的时候,两个缓存验证器彻底匹配(见13.3.3)。

若是任何一个要求不能知足,缓存必须利用最近的部分响应(这基于任何响应的Date头域值,而且会利用输入响应若是这些Date头域值相等或丢失了),并且必须丢弃其余的部分信息。

13.6 缓存已经协商过的响应(Caching Negotiated Responses)
在Vary头域出如今响应里的时候,服务器驱动内容协商(12.1节)的使用会改变缓存利用响应去响应后续请求利用的条件和过程。见14.44节关于服务器利用Vary头域的描述。

服务器应该利用Vary头域去通知一个缓存什么样的请求头域应该被使用从而从一个可缓存的并受限于服务器驱动协商的响应的多个表现形式中选择合适的表现形式。Vary头域里指定的头域被称作选择请求头域(selecting request-header)。

当缓存接收到一个后续的请求,此请求的URI对应一个或多个包含了Vary头域的缓存项时,此缓存不能利用这样一个缓存项去构造出一个响应去服务于新来的请求,除非全部出如今新请求里的选择请求头域匹配存储在源请求里被存储的请求头域。

在两个请求里,咱们定义这两个选择请求头域匹配,若是而且只有第一个请求的选择请求头域能被转换为第二个请求里的头域经过添加或删除线性空白(被容许出如今相应的BNF里的线性空白)和/或把多个消息头域结合成一个头域经过4.2节里的规则。

一个Vary头域值是“*”老是不能匹配的,而且后续那个资源的请求只能合适地被源服务器解析。

若是缓存项里的选择请求头域(selecting request-header)不能匹配新请求的选择请求头域,那么缓存不能利用缓存项去知足请求除非它能以一个条件请求把此新请求接力到源服务器而且此源服务器以一个304(没有改变)的状态码进行响应并包含一个实体标签或者Content-Location头域指明将要被使用的实体。

若是一个实体标签被赋予一个缓存的表现形式,那么此转发的请求将是条件的而且全部那个资源的缓存项的实体标签将会被包含于If-None-Match头域里。这向服务器表达当前缓存拥有的实体集,以致于若是这些实体里的任何实体匹配请求的实体,服务器会利用Etag头域在304(没有改变)响应里去告诉缓存哪一个缓存项是合适的。若是新响应的实体标签匹配已经存在的缓存项,那么新响应应该被利用去更新已经存在的缓存项的头域,并且此结果必须返回给客户端。

若是任何已经存在的缓存项包含只有相关实体的部份内容,那么此实体的实体标签不该该被包含在If-None-Match头域里除非这个请求是为了请求实体的一个范围,此范围彻底能够被缓存项知足。

若是缓存接收到一个成功的响应,此响应的Content-Location头域匹配于已经存在的缓存项的Content-Location头域对同一请求URI来讲,而且此响应的实体标签不一样于已经存在的缓存项的实体标签,并且此响应的Date头域值比已经存在的缓存项更近,那么已经存在的缓存项不能被返回去响应未来的请求而且将会从缓存里删除。

13.7 共享和非共享缓存 (Shared and Non-Shared Caches)
出于安全和保密考虑,有必要区分共享和非共享缓存。非共享缓存是仅供一个用户使用的缓存,此种状况下,可用性由适当的安全机制控制。全部其它的缓存均被认为是共享缓存。此协议的其它部分给一些对共享缓存的限制以防止隐私丢失或访问控制的失败。

13.8 错误和不彻底的响应缓存行为
缓存收到不完整响应(例如响应的字节数比Content-Length头域指定的值要小)也能够存储它,可是必须把它看做部分响应。部分相应能够合并(见13.5.4);合并结果多是完整的响应或可能还是部分的响应。.缓存不能把部分响应返回给客户端除非有明确要求能够这样作例如利用206(部份内容)状态码响应。缓存不能使用一个200(OK)状态码返回一个部分响应。

若是缓存在试图重验证一个缓存项而收到一个5xx响应时,它既能够将此响应转发给请求的客户端,或者作的就像服务器不能响应似的。在后面的状况下,它可能返回一个之前的接收的响应除非缓存项包含一个“must-revalidate”缓存控制指令(见14.9节)。

13.9 GET 和 HEAD 的反作用(Side Effects of GET and HEAD)
除非源服务器明确地禁止缓存保存它们的响应,对任何资源应用的GET和HEAD方法不该该有反作用,这些反作用会致使错误的行为若是这些响应将从缓存产生。他们可能会仍然有反作用,但缓存在决定缓存时没必要考虑这些反作用。缓存老是指望去观察一个源服务器对缓存的明确限制。

一个例外:有些应用习惯于在在GETs和HEADs方法里使用查询URLs(在rel_path_part里包含一个“?”)去执行一个操做而带来很大的反作用,缓存不能把此URIs的响应看做一个保鲜的除非服务器提供一个显示过时时间(explicit expiration time)。这意味着此URIs的之前从HTTP/1.0服务器产生的响应不能来自于缓存。见9.1.1节相关的信息。

13.10 在更新或删除后的无效性
对源服务器上的某资源执行方法的反作用可能会使一个或多个已经存在的缓存项的不透明性无效。那就是说,虽然他们可能会继续是保鲜的,可是他们不能准确的反应出源服务器将会对这一个新的请求返回什么。

HTTP协议没法保证全部此类缓存项均被标明无效。例如,引发源服务器上资源变化的请求可能不会穿过存有一个缓存项的代理。然而,一些规则帮助减小错误行为的可能。

在此节里,短语“使实体无效”意味着缓存会将全部那个实体的实例从它的存储里移除,或者把这些实体的实例标记为“无效的”而且在他们可能做为后续请求的响应时会被进行重验证。

一些HTTP方法必须让缓存去使一个实体无效 。这些实体被请求URI指定,或在Location或在Content-Location头域里被指定(若是出现的话)。这些方法是:

  • PUT
  • DELETE
  • POST

为了防止服务器攻击拒绝,一个基于Location或Content-Location头域里的URI的无效性处理必须只有在host部分和请求URI里的host部分相同时才被执行。

一个缓存若是不能理解请求里的方法,那么它应该使请求URI指定的任何实体无效。

13.11 强制写经过( Write-Through Mandatory)
全部可能对源服务器资源进行修改的方法都要写经过给源服务器(译注:直接穿过缓存在服务器上修改)。这一般包括全部方法除了GET和HEAD方法。缓存在将此种请求转发给服务器并得到相应的响应前不能对请求客户端作出响应。 这个不能防止代理缓存(译注:也能够叫缓存服务器,缓存)在服务器已经发送最终回复以前发送100(继续)响应。

相反状况(一般叫“写回”或“拷贝回”缓存)在HTTP1.1中是不容许的,这是因为提供一致更新很是困难,而且服务器,缓存和网络的故障会出如今比写回早。

13.12 缓存替换 (Cache Replacement)
若是一个新的可缓存的响应被缓存接收,同时对这一资源的响应已经在缓存里存在,那么缓存应该利用最新的响应去回复当前的请求。缓存可能会把此新响应放进存储里,而且若是它知足全部其余的要求,缓存将会利用此响应来响应任何未来的请求。若是缓存想把此新的响应加进缓存的存储,13.5.3的规则必须应用。

说明:一个新响应若是它的Date头域值比已经存在的缓存响应的Date头域值老,那么它是不能缓存的。

13.13 历史列表 (History Lists)
用户代理常用历史机制,如“Back”按钮和历史列表,来从新展现在一个会话里接收的一个稍早的实体。

历史机制和缓存机制是不一样。历史机制不该该尝试展现一个当前资源状态的语义透明视图。其历史机制只是为了展现在得到资源时看到了什么。

默认状况,一个过时时间不会应用于一个历史机制。若是实体仍然在存储里,历史机制应该显示它即便实体过时了,除非用户叫用户代理去刷新过时的文档。

这不能被解释去防止历史机制告诉用户视图可能过时了。

注意:若是历史机制不必地防止了用户看陈旧的资源,那么这会强制服务做者去避免利用HTTP过时控制和缓存控制。服务做者可能会认为这是很是重要的当用户没有被呈现错误消息或警告消息当他们利用导向按钮(如BACK按钮)去看之前得到的资源时。即便有时这些资源本不能被缓存保存或应该可能会很快过时,用户界面可能会强制服务做者去求助于其余防止缓存的方法(例如,一次性URLs)为了不历史机制功能的不合适的做用。

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 | "*" )[ ";" "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什么是可缓存的

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/Peo...

注: 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的内容能包含逗号分隔的受权参数的时候。

15.安全考虑 (Security Consideration)
这一部分是用来提醒程序开发人员,信息提供者,和用户关于HTTP/1.1安全方面的限制。讨论并不包含对披露问题的明确的解决办法,然而,确对减小安全风险提供了一些建议。

15.1 我的信息 (Personal Information)
HTTP的客户端常常要对大量的我的信息保密(例如用户的名字,域,邮件地址,口令,密匙等。),而且应当很是当心地防止这些信息无心识地经过HTTP协议泄露到其余的资源。咱们很是强烈地建议应该给用户提供一个方便的界面来控制这种信息的传播,而且设计者和实现者在这方面应该特别注意。历史告诉咱们在这方面的错误常常引发严重的安全和/或者隐私问题,并致使对设计或实现者的公司产生很是不利的影响。

15.1.1服务器日志信息的滥用 (Abuse of Server Log Information)
服务器是用来保存用来指定用户读模型或感兴趣主题的请求的。这些信息一般显然是需保密的,而且它的使用在某些国家被法律保护。利用HTTP协议提供数据的人们必须保证在这些数据被许可的状况下分发。

15.1.2敏感信息的传输 (Transfer of Sensitive Inforamtion)
就像任何数据传输协议同样,HTTP不能调整数据传输的内容,也没有任何经验方法去决定给定请求背景里特定信息的敏感性。所以,应用程序应该尽量为此信息提供者提供对此信息的控制。背景里有四个头域须要提出来,这四个头域是:Server,Via,Referer 和From。

揭露服务器特定软件版本可能会使服务器的机器更容易受到经过软件安全漏洞来进行攻击。实现者应该使Server头域成为可设置的选项。

用做穿过网络防火墙入口的代理应该特别当心关于指定防火墙后的主机(host)头域信息的传输。特别地,代理应该移除或用杀毒后的版本替换任何产生于防火墙以后的Via头域。

Referer头域容许学习的读模型和反向连接牵引。虽然它很是有用,但也会被滥用若是用户详情没有从包含在Referer头域里信息分离开来。即便当我的信息已经被移除了,那么这个Referer头域也可能指定私有的文档URI,此文档不适合做为共有的。

From头域里的信息可能会和用户的私有兴趣或他们站点的安全策略相冲突,所以这些信息在用户使此头域内容无效、有效和改变的状况下不能被传输。用户必须能在用户的喜好或应用程序的缺省设置范围内设置此头域的内容。

咱们建议,尽管不须要,给用户提供一个方便的触发器来使发送From和Referer头域信息有效或失效。

User-Agent(14.4节)或Server(14.38节)头域有时候能被用来去肯定一个特定的客户端或服务器存在安全漏洞。不幸的是,一样的信息常常被用于其它的有价值的目的由于HTTP如今没有更好的机制。

15.1.3 URI中敏感信息的编码(Encoding Sensitive Information in URI’s)
由于一个连接的源多是私有信息或者可能揭露其它私有信息资源,因此强烈建议用户能选择是否须要发送Referer头域。例如,浏览器客户端可能为了开放/匿名方式会有一个触发开关,此开关可能使Referer头域和From头域信息的发送有效/无效。

客户端不该该包含一个Referer头域在一个非安全HTTP请求里,若是参考页面在一个安全的协议上传输。

利用HTTP协议的服务做者不该该利用基于窗体GET提交敏感数据,由于这个能引发数据在请求URI里被编码。许多已存在的服务,代理,和用户代理将记录请求URI于某些对第三方可见的地方。服务器能利用基于窗体POST提交来取代基于窗体GET提交。

15.1.4链接到Accept头域的隐私问题
Accept请求头域能揭露用户的信息给全部被访问的服务器。Accept-Language头域能揭露用户的私有信息,由于能理解特定语言的人常常被认为就是某个特定种族里的成员。提供选择设置Accept-Language头域内容于每次请求里的用户代理被强烈鼓励让设置过程包含一个让用户知道隐私丢失的消息。

限制私有信息的方法多是在缺省状况下让用户代理不发送Accept-Language头域,而且让用户代理询问用户是否发送Accept-Language头域给服务器若是用户代理经过查看任何由服务器产生的Vary响应头域时发现此次发送能提升服务的质量。

请求里的用户配置性的接受头域若是这些接受头域(accept header fileds)包含质量值,那么他们应该被服务器用做相对信赖和长久的用户标识符。这样的用户标识符将会容许内容提供者进行click-trail跟踪以及容许合做内容提供者匹配跨服务器click-trail或者造成单个用户窗体提交。注意对于许多并不在代理服务器后面的用户,运行用户代理的主机的网络地址也将做为长久用户的标识符。在代理服务器被用做加强隐私的环境里,用户代理在提供给终端用户接受(accept)头域配置选项上应该是保守的。提供高度头域配置能力的用户代理应该警告用户隐私可能的丢失。

15.2 基于文件和路径名称的攻击
HTTP的源服务器的实现应该当心地限制HTTP请求返回的文档给那些由管理员受权的人。若是HTTP服务器要把HTTP URIs翻译成文件系统的调用,那么服务器必须当心去对待提供给HTTP客户端的文件传输。例如,UNIX,微软Windows,和其余操做系统都利用”..”去指示当前的父目录。对于这一个系统,若是HTTP服务器容许访问一个资源,但这些资源经过HTTP服务器不能访问,那么一个HTTP服务器必须不容许任何这样的构造存在于请求URI。一样的,用做服务器内部文件的引用的文件(如访问控制文件,配置文件,脚本代码)必须受到保护不让不合适的获取,由于他们可能包含敏感的信息。经验告诉咱们一个在HTTP服务器实现里的一个小小的错误会带来安全风险。

15.3 DNS欺骗
使用HTTP的客户端严重依赖于域名服务,所以这会致使基于IP和DNS名称的不关联的攻击。客户端须要当心关注IP地址/DNS名称关联的持久合法性。

特别地,HTTP客户端为了确认IP地址/DNS名称关联性,应该依赖于客户端本身的的名称解析器,而不是缓存之前主机(host)名称查找(host name lookups)结果。许多平台已经能本地的去缓存主机名称查找(host name lookups)当在合适的时候,而且他们应该被配置成能这样作。然而,只有当被名称服务器报告的TTL(Time To Live)信息使被缓存的信息仍然有用时,缓存查找(lookups)才是合适的。

若是HTTP客户端为了提升性能去缓存主机名称查找(host name lookups)的结果,那么他必须观察被DNS报告的TTL信息。

若是HTTP客户端不能看到这条规则,那么他们就会被欺骗当之前访问的IP地址改变时。由于网络地址的改变变得很日常,因此这种形式的攻击在不断增长。看到这个规则能减小潜在的安全攻击的可能性。

此要求照样能提供客户端负载平衡行为由于重复的服务器能利用同一个DNS名称,此要求能下降用户在访问利用策略(strategy)的站点中的体验失败。

15.4 Location头域和欺骗
若是单个的服务器支持互不信任的多个组织,那么它必须检查自称的某个组织控制下产生响应里Location和Content-Location头域值,以确认这些组织没有企图使它们没有权限的资源无效。

15.5 Content-Disposition的问题
RFC 1806 [35],在HTTP中常用的Content-Disposition(见19.5.1节)头域就源于此文档,有许多很是认真的安全考虑在此文档里说明。Content-Disposition并非HTTP标准版本中的一部分,但自从它被普遍应用以来,咱们正在证实它对使用者的价值和风险。详细资料见RFC 2183 [49](对RFC 1806的升级)。

15.6 受权证书和空闲客户端
现有的HTTP客户端和用户代理一般会不肯定地保留受权信息。HTTP/1.1并无为服务器提供一个方法让服务器去指导客户端丢弃这些缓存的证书(credentials)。这是一个重大缺陷,此缺陷须要扩展HTTP协议来解决。在某些状况下,证书的缓存能干涉应用程序的安全模型,此状况包含但不局限于:

Ø 这样的客户端。此客户端已经空闲时间超长而且服务器可能但愿再次让客户端出示证书。

Ø 这样的应用程序。此应用程序包括了一个会话中断指令(例如在一页上有"logout"或者"commit"的按钮),依据此指令应用程序的服务器端“知道”没有更多的理由为客户端保留证书。

这是做为当前单独研究的。有不少解决这个问题的社区,而且咱们鼓励在屏幕保护程序,空闲超时,和其余能减轻安全问题的方法里利用密码保护。特别地,能缓存证书的用户代理被鼓励去提供一个容易地访问控制机制让在用户的控制下去丢弃缓存的证书。

15.7 代理和缓存 (Proxies and Caching)
本质上说,HTTP代理是中间人(men-in-the-middle),而且存在中间人攻击(man-in-the-middle attacks)危险。代理运行在其上系统的折中能致使严重的安全和隐私问题。代理拥有对相关安全信息、用户和组织的我的信息、和属于用户和内容提供者的专有信息的访问权限。一个妥协的代理,或一个没有考虑安全性和隐私性的代理可能会被用作进行攻击的代理。

代理操做者应该保护代理运行其上的系统,正如他们保护任何包含或传输敏感信息的系统同样。特别的,代理上收集的日志信息常常包含较高的我的敏感信息,和/或关于组织的信息。日志信息应该被当心的保护,而且要合适地开发利用。(见15.1.1)节。

代理的设计者应当考虑到设计和编码断定所涉及到的隐私和安全问题,以及他们提供给代理操做人员配置选项(尤为是缺省配置)所牵涉到的隐私和安全问题。

代理的用户须要知道他们本身不比运行代理的操做员更值得信赖;HTTP协议自身不能解决这个问题。

当合适的时候,对密码学的正确应用,可能会保护普遍的安全和隐私攻击。密码学的讨论不在本协议文档的范围内。

15.7.1关于代理的服务攻击的拒绝
代理是存在的。代理很难被保护。关于此研究正在进行。

16 感谢(Acknowledgment)
这份规范大量使用了扩展BNF和David为RFC 822 [9]定义的经常使用结构。一样的,它继续使用了不少Nathaniel Borenestein和Ned Freed为MIME [7]提供的定义。咱们但愿在此规范里他们的结论有助于减小过去在HTTP和互联网邮件消息格式关系上的混淆。

HTTP协议在这几年已经有了至关的发展。它受益于大量积极的开发人员的社区--许多人已经经过www-talk邮件列表参与进来--而且一般就是那个社区对HTTP和万维网的成功做了重大贡献。 Marc Andreessen, Robert Cailliau, Daniel W. Connolly, Bob Denny, John Franks, Jean-Francois Groff , Phillip M. Hallam-Baker, Hakon W. Lie, Ari Luotonen, Rob McCool, Lou Montulli, Dave Raggett, Tony Sanders, 和 Marc VanHeyningen由于他们在定义协议早期方面的贡献应该获得特别的赞誉。

这篇文档从全部那些参加HTTP-WG的人员的注释中得到了很大的益处。除了已经提到的那些人之外,下列人士对这个规范作出了贡献:

Gary Adams                  Ross Patterson

   Harald Tveit Alvestrand     Albert Lunde

   Keith Ball                  John C. Mallery

   Brian Behlendorf            Jean-Philippe Martin-Flatin

   Paul Burchard               Mitra

   Maurizio Codogno            David Morris

   Mike Cowlishaw              Gavin Nicol

   Roman Czyborra              Bill Perry

   Michael A. Dolan            Jeffrey Perry

   David J. Fiander            Scott Powers

   Alan Freier                 Owen Rees

   Marc Hedlund                Luigi Rizzo

   Greg Herlihy                David Robinson

   Koen Holtman                Marc Salomon

   Alex Hopmann                Rich Salz

   Bob Jernigan                Allan M. Schiffman

   Shel Kaphan                 Jim Seidman

   Rohit Khare                 Chuck Shotton

   John Klensin                Eric W. Sink

   Martijn Koster              Simon E. Spero

   Alexei Kosut                Richard N. Taylor

   David M. Kristol            Robert S. Thau

   Daniel LaLiberte            Bill (BearHeart) Weinman

   Ben Laurie                  Francois Yergeau

   Paul J. Leach               Mary Ellen Zurko

   Daniel DuBois               Josh Cohen

缓存设计的许多内容和介绍应归于如下人士的建议和注释:Shel Kaphan, Paul Leach, Koen Holtman, David Morris, 和 Larry Masinter。

大部分规范的范围是基于Ari Luotonen和John Franks早期作的工做,以及从Steve Zilles另外加入的内容。

感谢Palo Alto的"cave men"。大家知道大家是谁。

Jim Gettys(这篇文档如今的编者)特别但愿感谢Roy Fielding,这篇文档之前的编者,连同John Klensin, Jeff Mogul, Paul Leach, Dave Kristol, Koen Holtman, John Franks, Josh Cohen, Alex Hopmann, Scott Lawrence, 和Larry Masinter一块儿感谢他们的帮助。还要特别感谢Jeff Mogul和Scott Lawrence对“MUST/MAY/ SHOULD”使用的检查。

Apache组,Anselm Baird-Smith,Jigsaw的做者,和Henrik Frystyk在早期实现了RFC 2068,咱们但愿感谢他们发现了许多这篇文档正尝试纠正的问题。

17 参考资料 (Reference)
[1] Alvestrand, H., "Tags for the Identification of Languages", RFC

1766, March 1995.

[2] Anklesaria, F., McCahill, M., Lindner, P., Johnson, D., Torrey,

D. and B. Alberti, "The Internet Gopher Protocol (a distributed

   document search and retrieval protocol)", RFC 1436, March 1993.

[3] Berners-Lee, T., "Universal Resource Identifiers in WWW", RFC

1630, June 1994.

[4] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform Resource

Locators (URL)", RFC 1738, December 1994.

[5] Berners-Lee, T. and D. Connolly, "Hypertext Markup Language -

2.0", RFC 1866, November 1995.

[6] Berners-Lee, T., Fielding, R. and H. Frystyk, "Hypertext Transfer

Protocol -- HTTP/1.0", RFC 1945, May 1996.

[7] Freed, N. and N. Borenstein, "Multipurpose Internet Mail

Extensions (MIME) Part One: Format of Internet Message Bodies",

   RFC 2045, November 1996.

[8] Braden, R., "Requirements for Internet Hosts -- Communication

Layers", STD 3, RFC 1123, October 1989.

[9] Crocker, D., "Standard for The Format of ARPA Internet Text

Messages", STD 11, RFC 822, August 1982.

[10] Davis, F., Kahle, B., Morris, H., Salem, J., Shen, T., Wang, R.,

Sui, J., and M. Grinbaum, "WAIS Interface Protocol Prototype

    Functional Specification," (v1.5), Thinking Machines

    Corporation, April 1990.

[11] Fielding, R., "Relative Uniform Resource Locators", RFC 1808,

June 1995.

[12] Horton, M. and R. Adams, "Standard for Interchange of USENET

Messages", RFC 1036, December 1987.

[13] Kantor, B. and P. Lapsley, "Network News Transfer Protocol", RFC

977, February 1986.

[14] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part

Three: Message Header Extensions for Non-ASCII Text", RFC 2047,

    November 1996.

[15] Nebel, E. and L. Masinter, "Form-based File Upload in HTML", RFC

1867, November 1995.

[16] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821,

August 1982.

[17] Postel, J., "Media Type Registration Procedure", RFC 1590,

November 1996.

[18] Postel, J. and J. Reynolds, "File Transfer Protocol", STD 9, RFC

959, October 1985.

[19] Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC 1700,

October 1994.

[20] Sollins, K. and L. Masinter, "Functional Requirements for

Uniform Resource Names", RFC 1737, December 1994.

[21] US-ASCII. Coded Character Set - 7-Bit American Standard Code for

Information Interchange. Standard ANSI X3.4-1986, ANSI, 1986.

[22] ISO-8859. International Standard -- Information Processing --

8-bit Single-Byte Coded Graphic Character Sets --

    Part 1: Latin alphabet No. 1, ISO-8859-1:1987.

    Part 2: Latin alphabet No. 2, ISO-8859-2, 1987.

    Part 3: Latin alphabet No. 3, ISO-8859-3, 1988.

    Part 4: Latin alphabet No. 4, ISO-8859-4, 1988.

    Part 5: Latin/Cyrillic alphabet, ISO-8859-5, 1988.

    Part 6: Latin/Arabic alphabet, ISO-8859-6, 1987.

    Part 7: Latin/Greek alphabet, ISO-8859-7, 1987.

    Part 8: Latin/Hebrew alphabet, ISO-8859-8, 1988.

    Part 9: Latin alphabet No. 5, ISO-8859-9, 1990.

[23] Meyers, J. and M. Rose, "The Content-MD5 Header Field", RFC

1864, October 1995.

[24] Carpenter, B. and Y. Rekhter, "Renumbering Needs Work", RFC

1900, February 1996.

[25] Deutsch, P., "GZIP file format specification version 4.3", RFC

1952, May 1996.

[26] Venkata N. Padmanabhan, and Jeffrey C. Mogul. "Improving HTTP

Latency", Computer Networks and ISDN Systems, v. 28, pp. 25-35,

    Dec. 1995. Slightly revised version of paper in Proc. 2nd

    International WWW Conference '94: Mosaic and the Web, Oct. 1994,

    which is available at

    http://www.ncsa.uiuc.edu/SDG/IT94/Proceedings/DDay/mogul/HTTPLat

    ency.html.

[27] Joe Touch, John Heidemann, and Katia Obraczka. "Analysis of HTTP

Performance", <URL: http://www.isi.edu/touch/pubs/http-perf96/>,

    ISI Research Report ISI/RR-98-463, (original report dated Aug.

    1996), USC/Information Sciences Institute, August 1998.

[28] Mills, D., "Network Time Protocol (Version 3) Specification,

Implementation and Analysis", RFC 1305, March 1992.

[29] Deutsch, P., "DEFLATE Compressed Data Format Specification

version 1.3", RFC 1951, May 1996.

[30] S. Spero, "Analysis of HTTP Performance Problems,"

http://sunsite.unc.edu/mdma-release/http-prob.html.

[31] Deutsch, P. and J. Gailly, "ZLIB Compressed Data Format

Specification version 3.3", RFC 1950, May 1996.

[32] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P.,

Luotonen, A., Sink, E. and L. Stewart, "An Extension to HTTP:

    Digest Access Authentication", RFC 2069, January 1997.

[33] Fielding, R., Gettys, J., Mogul, J., Frystyk, H. and T.

Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC

    2068, January 1997.

[34] Bradner, S., "Key words for use in RFCs to Indicate Requirement

Levels", BCP 14, RFC 2119, March 1997.

[35] Troost, R. and Dorner, S., "Communicating Presentation

Information in Internet Messages: The Content-Disposition

    Header", RFC 1806, June 1995.

[36] Mogul, J., Fielding, R., Gettys, J. and H. Frystyk, "Use and

Interpretation of HTTP Version Numbers", RFC 2145, May 1997.

    [jg639]

[37] Palme, J., "Common Internet Message Headers", RFC 2076, February

1997. [jg640]

[38] Yergeau, F., "UTF-8, a transformation format of Unicode and

ISO-10646", RFC 2279, January 1998. [jg641]

[39] Nielsen, H.F., Gettys, J., Baird-Smith, A., Prud'hommeaux, E.,

Lie, H., and C. Lilley. "Network Performance Effects of

    HTTP/1.1, CSS1, and PNG," Proceedings of ACM SIGCOMM '97, Cannes

    France, September 1997.[jg642]

[40] Freed, N. and N. Borenstein, "Multipurpose Internet Mail

Extensions (MIME) Part Two: Media Types", RFC 2046, November

    1996. [jg643]

[41] Alvestrand, H., "IETF Policy on Character Sets and Languages",

BCP 18, RFC 2277, January 1998. [jg644]

[42] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource

Identifiers (URI): Generic Syntax and Semantics", RFC 2396,

    August 1998. [jg645]

[43] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S.,

Leach, P., Luotonen, A., Sink, E. and L. Stewart, "HTTP

    Authentication: Basic and Digest Access Authentication", RFC

    2617, June 1999. [jg646]

[44] Luotonen, A., "Tunneling TCP based protocols through Web proxy

servers," Work in Progress. [jg647]

[45] Palme, J. and A. Hopmann, "MIME E-mail Encapsulation of

Aggregate Documents, such as HTML (MHTML)", RFC 2110, March

    1997.

[46] Bradner, S., "The Internet Standards Process -- Revision 3", BCP

9, RFC 2026, October 1996.

[47] Masinter, L., "Hyper Text Coffee Pot Control Protocol

(HTCPCP/1.0)", RFC 2324, 1 April 1998.

[48] Freed, N. and N. Borenstein, "Multipurpose Internet Mail

Extensions (MIME) Part Five: Conformance Criteria and Examples",

    RFC 2049, November 1996.

[49] Troost, R., Dorner, S. and K. Moore, "Communicating Presentation

Information in Internet Messages: The Content-Disposition Header

    Field", RFC 2183, August 1997.

18 做者地址
Roy T. Fielding

Information and Computer Science

University of California, Irvine

Irvine, CA 92697-3425, USA

Fax: +1 (949) 824-1715

EMail: fielding@ics.uci.edu

James Gettys

World Wide Web Consortium

MIT Laboratory for Computer Science

545 Technology Square

Cambridge, MA 02139, USA

Fax: +1 (617) 258 8682

EMail: jg@w3.org

Jeffrey C. Mogul

Western Research Laboratory

Compaq Computer Corporation

250 University Avenue

Palo Alto, California, 94305, USA

EMail: mogul@wrl.dec.com

Henrik Frystyk Nielsen

World Wide Web Consortium

MIT Laboratory for Computer Science

545 Technology Square

Cambridge, MA 02139, USA

Fax: +1 (617) 258 8682

EMail: frystyk@w3.org

Larry Masinter

Xerox Corporation

3333 Coyote Hill Road

Palo Alto, CA 94034, USA

EMail: masinter@parc.xerox.com

Paul J. Leach

Microsoft Corporation

1 Microsoft Way

Redmond, WA 98052, USA

EMail: paulle@microsoft.com

Tim Berners-Lee

Director, World Wide Web Consortium

MIT Laboratory for Computer Science

545 Technology Square

Cambridge, MA 02139, USA

Fax: +1 (617) 258 8682

EMail: timbl@w3.org

19 附录
19.1 互联网媒体类型message/http和application/http
这篇文档除了定义HTTP/1.1协议外,还用做互联网媒介类型"message/http"和"application/http"的规范。此类型用于封装一个HTTP请求消息或响应消息,这假设此类型遵循MIME对 全部“消息”类型关于行长度和编的限制。application/http类型能够用来封装一个或者更多HTTP请求或响应信息(非混合的)的传输路径(pipeline)。下列是在IANA[17]注册的。

媒介类型名称:    message

    媒介次类型名称: http

    必须参数:        无

    可选参数:        版本,信息类型

    版本:封装信息的HTTP版本号(例如,"1.1")。若是不存在,版本能够从消息的第一行肯定。

    信息类型:信息类型--"请求"或者"响应"。若是不存在,类型能够从报文的第一行肯定。 

    编码考虑:只有"7bit","8bit",或者"二进制"是容许的。

    安全考虑:无

    媒介类型名称:    application

    媒介次类型名称: http

    必须参数:        无

    可选参数:        版本,信息类型

    版本:封装信息的HTTP版本号(例如,"1.1")。若是不存在,版本能够从报文的第一行肯定。

    信息类型:信息类型--"request"或者"response"。若是不存在,类型能够从报文的第一行肯定。     

    编码考虑:用这种类型封装的HTTP信息是"二进制"的格式;当经过E-mail传递的时候一种合适的内容传输编码是必须的。

    安全考虑:无

19.2 互联网媒体类型multipart/byteranges
当一个HTTP206(部份内容)响应信息包含多个范围的内容(请求响应的内容有多个非重叠的范围),这些是做为一个多部分消息主体来被传送的。这种用途的媒体类型被称做"multipart/byteranges"。

multipart/byteranges媒体类型包括两个或者更多的部分,每个都有本身Content-type和Content-Range头域。必需的分界参数(boundary parameter)指定分界字符串,此分界字符串用来隔离每一部分。

媒介类型名称:    multipart

    媒介次类型名称: byteranges

    必须参数:        boundary

    可选参数:        无

    编码考虑:只有"7bit","8bit",或者"二进制"是容许的。

    安全考虑:无

例如:

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-type:multipart/byteranges;boundary=THIS_STRING_SEPARATES

--THIS_STRING_SEPARATES

Content-type: application/pdf

Content-range: bytes 500-999/8000

...第一部分...

--THIS_STRING_SEPARATES

Content-type: application/pdf

Content-range: bytes 7000-7999/8000

...第二部分

--THIS_STRING_SEPARATES--

注意:

在实体(entity)中,在第一个分界字符串以前能够有多余的CRLFs。

虽然RFC 2046 [40]容许分界字符串加引号,可是一些现有的实现会不正确的处理分界字符串

许多浏览器和服务器是按照字节范围标准的早期草案关于使用multipart/x-byteranges媒体类型来进行编码的的,这个草案不老是彻底和HTTP/1.1中描述的版本兼容。

19.3 宽松的应用程序 (Tolerent Applications)
虽然这篇文档列出了HTTP/1.1消息所必须的元素,可是并非全部的程序在实现的时候都是正确的。所以咱们建议当误差能够明确解释的时候,运算程序对这种误差应该是宽容的。

客户端应该宽松的解析Status-Line(状态行);服务器也应该宽松的解析Request-Line(请求行)。特别的,他们应该能够接受头域之间任何数量的SP或HT字符,即便协议规定只有一个SP。

消息头域的行终结符是CRLF。然而,当解析这样的头域时,咱们建议应用程序能识别单一LF做为行终结符并能忽略CR。

实体主体(entity-body)的字符集应该被标记为应用于实体主体字符编码的最小公分母,而且指望不对实体进行标记要优于对实体标记为US-ASCII或ISO-8859-1。见3.7.1和3.4.1。

对关于日期分析和编码的要求的额外规则以及其它对日期编码的潜在问题包含:

Ø HTTP/1.1客户端和缓存应该假定一个彷佛是50多年之后的RFC-850日期其实是过去的(这有助于解决"2000年"问题)。

Ø 一个HTTP/1.1的实现能够内部地表示一个比正确日期值更早的已解析后的Expires日期,可是必定不要(MUST NOT)内部地表示一个比正确日期值更迟的已解析过的Expires日期。

Ø 全部过时日期相关的计算必须用GMT时间。本地时区必定不能(MUST NOT)影响年龄或过时时间的计算。

Ø 若是一个HTTP头域不正确的携带了一个非GMT时间区的日期值,那么必须利用最保守的可能转换把此日期值转换成GMT时间值。

19.4 HTTP实体和RFC 2045实体之间的区别
HTTP/1.1使用了许多Internet Mail(RFC 822 [9])和Multipurpose Internet Mail Extensions(MIME [7])里定义的结构,去容许实体以多种表现形式和扩展机制去传输。然而,RFC2045讨论邮件,而且HTTP有许多不一样于RFC2045里描述的特征。这些不一样被当心地挑选出来优化二进制链接的性能,为了容许使用新的媒体类型有更大的灵活性,为了使时间比较变得容易,和为了认可一些早期HTTP服务器和客户端的实效。

本附录描述了HTTP协议不一样于RFC 2045的特殊区域。在严格的MIME环境中的代理和网关应该意识到这些不一样而且在必要的时候要提供合适地转换。从MIME环境到HTTP的代理服务器和网关也须要意识到这些不一样由于一些转换多是须要的。

19.4.1 MIME版本(MIME-Version)
HTTP不是一个遵照MIME的协议。然而HTTP/1.1消息能够(MAY)包含一个单独的MIME-Version经常使用头域用来指出什么样的MIME协议版本被用于去构造消息。利用MIME-Version头域指明彻底遵循MIME协议的消息(在RFC2045[7])。代理/网关要保证彻底遵照MIME协议当把HTTP消息输出到严格MIME环境的时候。

MIME-Version   = "MIME-Version" ":" 1*DIGIT "." 1*DIGIT

在HTTP/1.1用的缺省值是MIME1.0版本。然而,HTTP/1.1消息的解析和语义是由本文档而不是MIME规范定义的。

19.4.2转换到规范化形式 (Conversion to Canoical Form)
RFC 2045 [7]须要一个Internet mail实体在被传输以前要被转换成一个规范化的形式,这在RFC2049[48]里第四章里描述的。这篇文档的3.7.1节描述了当用HTTP协议传输时容许使用的”text”子媒体类型的形式。RFC2046要求以类型为“text”的内容要用CRLF表示为换行符,以及在换行符外禁止使用CR或LF。

RFC 2046须要像在"text"类型的内容里同样,用CRLF表示行间隔符并禁止在行间隔符序列之外使用CR或者LF。HTTP容许CRLF,单个CR,和单个LF来表示一个换行符在一个文本内容消息中。

在可能的地方,从HTTP到严格MIME环境的代理或网关应该(SHOULD)把RFC2049里描述的text媒体类型里全部换行符转换成RFC2049里CRLF的规范形式。然而,注意这可能在Content-Encoding出现的时候,以及HTTP容许利用一些没有利用13和10表明CR和LF的字符集时候都会变得复杂。

实现者应该注意转换将会破坏任何应用于源内容(original content)的密码校验和,除非源内容已是规范化形式。所以,对任何在HTTP中使用校验和的内容被建议要表示为规范化形式。

19.4.3日期格式的转换 (Conversion of Date Formate)
为了简化日期比较的过程,HTTP/1.1使用了一个限制的日期格式(3.3.1节)。其它协议的代理和网关应该保证任何消息里出现的Date头域应该遵循HTTP/1.1规定的格式,若是有必要须要重写此日期。

19.4.4 Content-Encoding头域介绍 (Introduction of Content-Encoding)
RFC 2045不包含任何等价于HTTP/1.1里Content-Encoding头域的概念。由于这个头域做为媒体类型(media type)的修饰,从HTTP协议到MIME遵照的协议的代理和网关在转发消息以前必须既能改变Content-Type头域的值,也能解码实体主体(entity-body).。(一些为Internet mail类型的Content-Type的实验性的应用已经使用了一个媒体类型参数“; conversions=<content-coding>”去执行等价于Content-Encoding的功能。然而,此参数并非RFC2045的部分)

19.4.5没有Content-Transfer-Encoding头域
HTTP不使用RFC 2045里的Content-Transfer-Encoding(CTE)头域。从使用MIME协议到HTTP的代理和网关在把响应消息发送给HTTP客户端以前必须删除任何非等价(non-identity,译注:identity编码,表示没有进行任何编码)CTE("quoted-printable"或"base64")编码。

从HTTP到MIME协议遵循的代理和网关要确保消息在那个协议安全传输上是用正确的格式和正确的编码,“安全传输”是经过使用的协议的限制而被定义的。这样一个代理或网关应该用合适的Content-Transfer-Encoding头域来标记数据若是这样作将提升安全传输的可能性。

19.4.6 Transfer-Encoding头域的介绍
HTTP/1.1介绍了Transfer-Encoding头域(14.41节)。代理/网关在转发经由MIME协议的消息以前必须移除任何传输编码。

一个解码"chunked"传输代码(3.6节)的程序能够用代码表示以下:

length := 0

   read chunk-size, chunk-extension (if any) and CRLF

   while (chunk-size > 0) {

      read chunk-data and CRLF

      append chunk-data to entity-body

      length := length + chunk-size

      read chunk-size and CRLF

   }

   read entity-header

   while (entity-header not empty) {

      append entity-header to existing header fields

      read entity-header

   }

   Content-Length := length

   Remove "chunked" from Transfer-Encoding

19.4.7 MHTML和行长度限制
和MHTML实现共享代码的HTTP实现须要了解MIME行长度限制。由于HTTP没有这个限制,HTTP并不折叠长行。用HTTP传输的MHTML消息遵照全部MHTML的规定,包括行长度的限制和折叠,规范化等,由于HTTP传输全部消息主体(见3.7.2)而且不解析消息的内容和消息中包含任何MIME头域。

19.5 其它特征
RFC 1945和RFC 2068里一些协议元素被一些已经存在的HTTP实现使用,可是这些协议元素对于大多数HTTP/1.1应用程序既不兼容也不正确。实现者被建议去了解这些特征,可是不能依赖于它们的出现或不依赖于与其它HTTP/1.1应用程序的互操做性。这些特征中的一些特征描述了实验性的特征,以及还有一些特征描述了没有在基本HTTP/1.1规范里被描述的实验性部署特征。

一些其它头域,如Content-Dispositon和Title头域,他们来自于SMTP和MIME协议,他们一样常常被实现(见2076[37]).

19.5.1 Content-Disposition
Content-Disposition响应头域被建议做为一个这样的用途,那就是若是用户请求要使内容被保存为一个文件,那么此头域被源服务器使用去建议的一个缺省的文件名。此用途来自于RFC1806[35]关于对Content-Disposition的定义。

content-disposition = "Content-Disposition" ":"

                          disposition-type *( ";" disposition-parm )

    disposition-type = "attachment" | disp-extension-token

    disposition-parm = filename-parm | disp-extension-parm

    filename-parm = "filename" "=" quoted-string

    disp-extension-token = token

    disp-extension-parm = token "=" ( token | quoted-string )

一个例子是:

Content-Disposition: attachment; filename="fname.ext"

接收用户的代理不该该(SHOULD NOT)关注任何在filename-parm参数中出现的文件路径信息,这个参数被认为在此次仅仅是应用于HTTP实现。文件名应该(SHOULD)只被看成一个终端组件。

若是此头域用于一个Content-Type为application/octet-stream响应里,那么含义就是用户代理不该该展示响应,可是它应该直接进入一个‘保存响应为…’对话框。

见15.5节关于Content-Disposition的的安全问题。

19.6 和之前版本的兼容
要求和之前的版本的兼容超出了协议规范的范围。然而HTTP/1.1有意设计成很容易支持之前的版本。必须值得注意的是,在写这份规范的时候,咱们但愿商业的HTTP/1.1服务器去:

--接受HTTP/0.9,1.0和1.1请求的请求行(Request-Line)格式;

  --理解HTTP/0.9,1.0或1.1格式中的任何有效请求;

  --恰当地用客户端使用的主要版原本响应。

而且咱们但愿HTTP/1.1的客户端:

--接受HTTP/1.0和1.1响应的状态行(Status-Line)格式;

  --懂得HTTP/0.9,1.0或1.1的格式的任何有效的响应。

对大多数HTTP/1.0的实现,每个链接要在请求以前被客户端创建,而且在发送响应以后要被服务器关闭。一些实现了在RFC 2068 [33]的19.7.1节描述的持久链接的Keep-Alive版本。

19.6.1对HTTP/1.0的改变
这一部分总结HTTP/1.0和HTTP/1.1之间主要的区别。

19.6.1.1 对多主机web服务器和保留IP地址简化的改变
客户端和服务器必须支持Host请求头域,而且若是Host请求头域在HTTP/1.1请求里缺乏,那么服务器应该报告一个错误,而且服务器能接受一个绝对URIs(5.1.2节),对于这个要求是在此规范里最重要的改变。上面的改变将容许互联网,一旦旧的客户端再也不经常使用时,去支持一个IP地址的多个web站点,这大大简化了大型运算的web服务器,在那里分配多个IP地址给一个主机(host)会产生很严重的问题。此互联网照样能恢复这样一个IP地址,此IP地址做为特殊目的被分配给被用于根级HTTPURLs的域名。给定web的增加速度,服务器的部署数量部,那么全部HTTP实现(包括对已存HTTP/1.0应用程序)应该正确地知足下面这些需求:

--客户端和服务器都必须(MUST)支持Host请求头域。

--发送HTTP/1.1请求的客户端必须(MUST)发送Host头域。

--若是HTTP/1.1请求不包括Host请求头域,服务器就必须(MUST)报告错误400(Bad Request)。

--服务器必须(MUST)接受绝对URIs(absolute URIs)。

19.6.2和HTTP/1.0持续链接的兼容
一些客户端和服务器可能但愿和一些对之前持续链接实现的HTTP/1.0客户端和服务器兼容。HTTP/1.0持久链接须要显示地协商,由于它们不是缺省的行为。持久链接的HTTP/1.0实验性的实现有错误,而且HTTP/1.1里的新的功能被设计成去矫正这些问题。此问题是一些已经存在的1.0客户端可能会发送Keep-Alive头域给不理解链接的代理服务器,而后代理服务器会把此Keep-Alive转发给下一个入流(inbound)服务器。因此HTTP/1.0客户端必须禁止利用Keep-Alive当和代理会话的时候。

然而,和代理进行会话最重要是利用持久链接,因此那个禁止很显然不能被接受。所以,咱们须要一些其它的机制去指明须要一个持久链接,而且它必须能安全的使用甚至当和忽略链接的老代理。持久链接缺省是为HTTP/1.1消息的;为了声明非持久链接(见14.10节),咱们介绍一个新的关键字(Connection:close)。

持久链接的源HTTP/1.0的形式(the Connection: Keep-Alive and Keep-Alive 头域)在RFC2068里说明

19.6.3对RFC 2068的改变
这篇规范已经被仔细的审查来纠正关键字的用法和消除它们的歧义;RFC 2068在遵照RFC 2119 [34] 制定的协定方面有不少问题。

澄清哪一个错误代码将会使入流服务器失灵(例如DNS失灵)。(10.5.5节)

CREATE有一个特色当一个资源第一次被建立的时候必须须要一个Etag。(10.2.2节)

Content-Base头域今后规范里删除了:它没法普遍的实现,而且在没有健壮的扩展机制的状况下,没有简单的,安全的方式去介绍它。而且,它以一种类似的而不是相同的方式在MHTML[45]里被使用。

略…..

20 索引 (Index)
21 所有版权声明

转自:http://www.cnblogs.com/k1988/...

相关文章
相关标签/搜索