Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2350179
  • 博文数量: 609
  • 博客积分: 10061
  • 博客等级: 上将
  • 技术积分: 5920
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-25 08:30
文章分类

全部博文(609)

文章存档

2010年(13)

2009年(39)

2008年(558)

我的朋友

分类: 系统运维

2008-08-14 09:23:23

HTTP超文本传输协议-HTTP/1.1中文版(上)       


说明
   本文档规定了互联网社区的标准组协议,并需要讨论和建议以便更加完善。请参考
“互联网官方协议标准”(STD 1)来了解本协议的标准化状态。本协议不限流传发布。

版权声明
   Copyright (C) The Internet Society (1999).          All Rights Reserved.
 Copyright  (2007).          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迫切需要一个新的版本,以便使两个通信应用程序能够确定彼此的真实性能。

这里规定的协议叫做“HTTP/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)
作为请求或应答的有效负荷而传输的信息.一个实体包含报头形式的维护信息和消息体形式的内容,由第7节详述.

表示方法(Representation)
一个应答包含的实体是由内容协商决定的,如第12章所述.一个特定的应答状态所对应的表示方法可能有多个.
 
内容协商(Content Negotiation)
为请求服务时选择适当表示方法的机制(mechanism),如第12节所述.任何应答里实体的表示方法都是可协商的(包括出错应答).

变量(Variant)
在任何给定时刻,与一个资源对应的表示方法可以有一个或更多.每个表示方法称作一个变量.使用变量这个术语并不必然意味着资源是由内容协商决定的.

客户机(Client)
为发送请求建立连接的程序.

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

服务器(Server)
同意连接以便通过发回应答为请求提供服务的应用程序.任何给定的程序都有可以既做客户端又做服务器;我们使用这些术语仅指特定连接中程序完成的任务,而不是指通常意义上程序的性能.同样,任何服务器都可以基于每个请求的性质扮演原服务器,代理,网管,或者隧道等诸角色之一。

原服务器(Origin server)
给定的资源驻留或创建的地方.
 
代理服务器( Proxy)
一个既做服务器又做客户端的中介程序.,其用途是代表其他客户发送请求.请求在内部得到服务,或者经过一定的翻译转至其他服务器.一个代理服务器必须能同时履行本说明中客户端和服务器要求.“透明代理”(transparent proxy)是一种除了必需的验证和鉴定外不修改请求或相应的代理.“非透明代理”(non-transparent proxy)是一种修改请求或应答以便为用户代理提供附加服务的代理,附加服务包括类注释服务,媒体类型转换,协议简化,或者匿名滤除等.除非经明确指出,HTTP代理要求对两种代理都适用.

网关(gateway)
为其他服务器充当中介的服务器.与代理服务器不同,网关接收请求,仿佛它就是被请求资源所在的原服务器;提出请求的客户可能觉察不到它正在同网关通信.
一个在两个连接之间充当盲目中继(blind relay)的中间程序.一旦有效,隧道便不再被认为是HTTP通信的用户,虽然隧道可能已经被HTTP请求初始化了.当两端的中继连接都关闭的时候,隧道不再存在.

高速缓存(Cache)
一个程序应答信息的本地存储和控制此信息存储、检索和删除的子系统,一个高速缓冲存储器存储应答为的是减少对将来同样请求的应答时间和网络带宽消耗,任一客户或服务器都可能包含一个高速缓存,但高速缓存不能应用于一个充当隧道的服务器.

可缓存(Cacheable)
       如果一个高速缓存允许存储应答信息的一份拷贝运用于应答后继请求的拷贝,一个应答就是可缓存的.用来确定HTTP应答的缓存能力(cacheability)的规则在13节中有定义.即使一个资源是可缓存的,也可能对一个高速缓存能否将缓存拷贝用于某特定请求存在附加的约束.

直接(first-hand)
      如果一个应答直接到来并且没有缘于原服务器,或若干代理服务器的不必要的延时,那么这个应答就是直接的.如果它的有效性已经被原服务器直接认证,那么这个应答也同样是第一手的.

明确终止时间(explicit expiration time)   
原服务器预算一个实体在无需进一步确认的情况下不再被高速缓存返回的时间.

探索终止时间(heuristic expiration time)    
当没有外在的终止时间可利用时, 由高速缓存所指定的终止时间.

年龄(Age)
     一个应答的年龄是从它被发送,或被原服务器成功确认到现在的时间.

保鲜寿命(Freshness lifetime)
一个应答生成和过期之间的时间长度.

保鲜(Fresh)  
如果一个应答的年龄还没有超过保鲜寿命,它就是保鲜的.

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

语义透明(semantically transparent)
当它的使用除了改善性能外既未影响请求客户机也未影响原服务器时, 高速缓存对于某特定的应答就是工作于语义透明方式了.当高速缓存语义透明时,客户恰好收到与原服务器直接处理请求后得到的应答(除了逐段转接的报头部分)完全相同的应答。

有效性判别器(Validator)
  一个用来查找一个高速缓存记录是否是一个实体的等效拷贝的协议元素(例如,一个实体标记(entity tag)或最终更改时间(Last-Modified time)).

上游/下游(upstream/downstream)
     上游和下游描述了消息的流动:所有消息都从上游流到下游.

向内/向外(inbound/outbound)
向内和向外指的是消息的请求和应答路径:"向内"即"移向原服务器","向外"即"移向用户代理".
 Copyright  (2007).          All Rights Reserved.

1。4 总体操作

HTTP协议是一种请求/应答协议。 与主机建立连接后,客户以请求方法,URI和协议版本的形式向服务器发送请求,继以类MIME信息,其中包括请求修改,客户信息和可能的正文内容。
服务器用包括消息协议版本和成功或错误代码的状态进行应答,继以包括服务器信息,实体维护信息和可能的实体内容的类MIME消息。HTTP和MIME之间的关系如附录19.4节所阐述。

大部分的HTTP通信由用户代理引发,由应用到一些原服务器上资源的请求构成。最简单的情形,可以经用户代理(UA)和原服务器(O)之间的单一连接(v)完成。请求链------------------------>用户代理(UA)-------------------单一连接(v)-------------------原服务器(O) <-----------------------应答链

当一个或一个以上的中介在请求/应答链中出现的时候,会出现更复杂的情形。常见的中介形式有三种:代理,网关和隧道。代理是一种转送工具,它接收绝对形式的URI请求,重写全部或部分消息,然后把重新格式化后的请求发送到URI确定的服务器上。网关是一种接收工具,它充当其他服务器的上层,必要时将请求翻译为下层服务器的协议。隧道不改变消息而充当两个连接之间的中继点;它用于通信需要穿过中介(如防火墙),甚至中介不能理解信息内容的时候。
请求链-------------------------------------->UA-----v-----A-----v----- B-----v-----C-----v-----O <-------------------------------------应答链


上图显示了用户代理和原服务器之间的三个中介(A,B和C)。游历整条链的请求或应答消息需通过四个独立的连接。这个特性很重要,因为某些 HTTP通信选项只能应用于到最近的非隧道邻居,链的终点的连接,或者沿着链的所有连接。图表尽管是线性的,每部分可能都在忙于多路同时通信。例如,B可以接收来自不同于A的许多客户的请求,并且/或者转送到不同于C的服务器,与此同时,它还在处理A的请求。


任何非隧道的通信成员都可以使用内部的高速缓存来处理请求。高速缓存的作用是如果沿着链的一个成员对请求采用了高速缓冲的应答,请求/应答链就会大大缩短。以下图解作为结果产生的链,假定B拥有来自O(通过C)的一个从前应答的备份,请求尚未被UA或A缓存。
请求链---------->UA-----v----------A-----v-----B-----C----O <---------应答链

并不是所有的应答都能有效地缓存,一些请求可能含有修改量,对缓存动作有特殊的要求。缓存动作和缓存应答的HTTP要求将在第13节定义。

实际上,目前万维网上有多种结构和配置的高速缓存和代理被实验或使用。这些系统包括节省越洋带宽的全国代理层,广播或多点通信缓存接口,通过CD-ROM分配子缓存数据的机构,等等。HTTP系统应用在宽频带连接的企业局域网中,通过PDAs的低耗无线连接和断续连接的访问。 HTTP1.1的目标是支持各种各样的应用配置,引进协议结构满足那些需要较高可靠性,可以排除故障或至少指示故障的网络应用的要求。

HTTP通信在通常发生在TCP/IP连接上。默认端口是TCP 80,不过其它端口也可以使用。在互联网或其他网络上,这并不妨碍HTTP应用在其他协议的顶端。http仅仅期望可靠的传输;任何提供这种保证的协议都可以使用;协议传输数据单元的HTTP/1.1请求和应答结构的映象已经超出了本说明书的范围。

在http/1.0中,大部分的实现为每个请求/应答交换使用了新连接。而http/1.1中,一个连接可以用于一个或更多请求/应答交换,虽然连接可能会因为各种原因中断(见第8.1节)。

2 符号惯例和一般语法

2.1 扩充BNF

本文档规定的所有机制都用两种方法描述:散文体(prose)和类似于RFC 822的扩充Backus-Naur Form(BNF)。要理解本说明书,使用者需熟悉符号表示法。扩充BNF包括下列结构:

名字=定义
一条规则的名字仅仅是名字本身(没有任何"<"和">"),跟等于号"="后面的定义是分离的。仅当连续线的空格用来表示一条长于一行的规则时空白才是重要的。某些基本规则使用大写字母,如SP,LWS,HT,CRLF,DIGIT,ALPHA,等等。无论何时,只要它们的存在有利于识别规则名字,就可以在定义的范围内使用角括号。

“文字”
文字原文使用引号。除特殊情况,原文对外界不敏感。

规则1 | 规则2
由竖线("|")分开的元素是可选的,例如,"yes | no"表示yes或no都是可接受的。

(规则1 规则2)
围在括号里的多个元素视作一个元素。这样“(elem (foo | bar) elem)”允许标记序列“elem foo elem”和elem bar elem”。

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


[规则]
方括号里是任选元素;"[foo bar]"相当于"*1(foo bar)".

N 规则
特殊的重复:“(元素)”相当于“*(元素)”; 也就是说,(元素)正好出现了次。这样2DIGIT是一个两位数字,3ALPHA是一个由三个字符组成的字符串。

#规则
类似于"*",结构"#"是用来定义一系列元素的。完整的形式是"#元素,表示至少个元素,至多个元素,元素之间被一个或多个逗号(",")以及可选的线性白色空间(LWS)隔开了。这就使得列表的一般形式变得非常容易;像
( *LWS element) *( *LWS ","*LWS element ))
就可以表示为
1#element
无论在哪里使用这个结构,空元素都是元许的,但是不计入元素出现的次数。换句话说,“(元素), , (元素) "是允许的,但是仅仅视为两个元素。因此,在至少需要一个元素的地方,必须存在至少一个非空元素。默认值是0和无穷大,这样,“#element”允许任何数字,包括零;“1#element”至少需要1个元素;“1#2element”允许1个或2个元素。

;注释
用分号引导的注释,从规则正文的右边一段距离开始直到行尾。这是做注释的简单方法,注释与说明是同样有用的。

隐含 *LWS
本说明书所描述的语法是基于字的。除非特别注明,线性空白可出现在任何两个相邻字之间(标记或引用字符串),以及相邻字和间隔符之间,并不改变一个域的含义。任何两个标记之间(下面会对"token(标记)"进行定义)必须有至少一个分割符,否则将会被理解为单一标记。

2.2基本规则

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

 

       OCTET          = <任意八比特的数据序列>
       CHAR           = <任意ASCII字符(八进制 0-127)>
       UPALPHA        = <任意大写字母"A"..."Z">
       LOALPHA        = <任意小写字母"a"..."z">
       ALPHA          = UPALPHA | LOALPHA
       DIGIT          = <任意数字0,1,...9>
       CTL            = <任意控制字符(octets 0 - 31)及删除键DEL(127)>
       CR             =
       LF             =
       SP             =
       HT             =
       <">            =


HTTP/1.1将CR LF的顺序定义为任何协议元素的行尾标志,除了报文以外(宽松应用见附录19.3).报文内部的行尾标志是由它的关联媒体类型定义的,如3.7节所述。

       CRLF           = CR LF

如果延长线由空格或水平制表开始,HTTP/1.1 的报头域值可以折叠到到复合线上。所有的
线性空白,包括折叠,具有同SP一样的语义。接收者在解释域值或将消息转送到下游时可以用单个SP替代任何线性空白。

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

文本规则仅仅适用于描述域的内容和不会被消息语法分析程序解释的值。*TEST的字可以
包含ISO-8859-1[22]里的字符,也可以包含字符规定里的字符[14]。

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

一个CRLF仅仅在作为报头域延续的一部分时才在TEXT定义里允许使用。

十六进制数字字符用在数个协议元素里。

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


许多HTTP/1.1的报头域值是由LWS或特殊字符分隔的字构成的。这些特殊字符必须包含在引用字符串里,方可用在参数值(如3.6节定义)里。

       token  (标记)        = 1*<除CTLs与分割符以外的任意 CHAR >
       separators(分割符)    = "(" | ")" | "<" | ">" | "@"
                      | "," | ";" | ":" | "\" | <">
                      | "/" | "[" | "]" | "?" | "="
                      | "{" | "}" | SP | HT

用圆括号括起来的注释可以包含在一些HTTP报头域里。只有作为域值定义的一部分时注释才是允许的。在其他域里,圆括号视作域值的一部分。

       comment (注释)= "(" *( ctext | quoted-pair | comment ) ")"
       ctext          = <除"(" and ")"以外的任意TEXT >

一个文本字符若在双引号里,则当作一个字。

       quoted-string  = ( <"> *(qdtext | quoted-pair ) <"> )
       qdtext         = <除<">以外的任意TEXT >

反斜线("\")可以用作单一字符引用结构,但仅在引用字符串或注释里。

       quoted-pair    = "\" CHAR

 


3 协议参数

3.1 HTTP版本
 Copyright  (2007).          All Rights Reserved.

HTTP使用"<主要>.<次要>"的编号方案表示协议版本。协议的版本方针是希望允许发送者表示消息的格式和性能以便理解更深一层的HTTP通信,而不仅仅是当前通信获得的特征。消息构件的增加不影响通信动作,或仅仅增加了扩展域值,版本号并没有因此变化。协议的改变增加了一些特征,没有改变一般的消息解析规则,但是增加了消息的语义或者暗含了发送者新增的性能,这时<次要>数字便要增大。当协议的消息格式改变时,<主要>数字增大。

HTTP消息的版本在消息的第一行HTTP-版本域里表示。

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

注意主要和次要数字必须看作是两个分离的整数,二者都可以增加到比单位数还大。这样,HTTP/2.4的版本比HTTP/2.3低,依次HTTP/2.3的版本比HTTP/12.3低。首位的零必定被接收者忽视,一定不要发送。

一个发送包含HTTP版本"HTTP/1.1"的请求或应答消息的应用,必须至少有条件的服从本说明书。至少有条件服从本说明书的应用应该在消息里使用"HTTP/1.1"的HTTP-版本,任何与 HTTP/1.0不兼容的消息则必须这样做。关于何时发送特殊的HTTP-版本值,更多资料请参看
RFC 2145[36].

一项应用的HTTP版本是应用至少有条件服从的最高HTTP版本.

代理和网关转送的消息的协议版本与应用版本不同时,需要小心。既然协议版本表示发送者的协议性能,代理/网关一定不能发送标示版本高于它本身的实际版本的消息。如果收到更高版本的请求,代理/网关必须降低请求的版本,或者发出出错应答,或者切换到隧道动作。

由于自RFC 2068[33]发布后发现的HTTP/1.0代理协同工作问题,高速缓存代理必须,网关可以,隧道必须不将请求提升到它们支持的最高版本。代理/网关的应答的主要版本号必须同请求相同。

注:HTTP版本的转换可能会包含相关版本必需或禁止的头域修改。

3.2 统一资源标识符(URI)

URIs的许多名字已为人所知:WWW地址,通用文件标识符,通用资源标识符[3],以及最后统一资源定位器(URL)[4]和统一资源名称 (URN)[20]的结合。只要与HTTP相关,统一资源定位器只是格式化的字符串,它通过名称,地址,或任何别的特征确定了资源的位置。


3.2.1 一般语法


根据使用时的上下文,HTTP里的URI可以表示成绝对形式或基于已知的URI的相对形式。两种形式的区别是根据这样的事实:绝对URI总是以一个摘要名字作为开头,其后是一个冒号。关于URL更详尽的信息请参看"统一资源标识符(URI):一般语法和语义",RFC 2396 [42](代替了RFCs 1738 [4]和RFC 1808 [11]).本说明书采用那份说明书里关于"URI-索引","绝对URI","相对URI","端口","主机","绝对路径"和"权力"的定义.

HTTP协议不对URI的长度作事先的限制.服务器必须能够处理它们服务的任何资源的URI,并且应该能够处理无限长度的URI,如果它们提供可以产生这种URI的基于GET的形式.

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

3.2.2 http URL

http方案通过HTTP协议定出网络资源的位置.本节定义了这种方案-http URL特殊的语法和语义.
   http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]

如果端口为空或未给出,就假定为80.语义即:已识别的资源放在服务器上,在那台主机的那个端口上监听TCP连接,对资源的请求的URI为绝对路径 (5.1.2节). 无论什么可能的时候,URL里使用IP地址都是应该避免的(参看RFC 1900 [24]).如果绝对地址没有出现在URL里,它用作对资源的请求的URI时必须作为"/"给出.如果代理收到一个不是充分资格域名的主机名,一定不能改变主机名.


3.2.3 URI 比较

当比较两个URI是否匹配时,客户应该对整个URI进行区分大小写,以八字节为单元的比较.以下情况例外:

-一个为空或未给定的端口等同于那个URI索引里的默认端口;

-主机名的比较必须是不区分大小写的;

-方案名的比较必须是不区分大小写的;

-一个空绝对路径等同于绝对路径"/".

   Characters other than those in the "reserved" and "unsafe" sets are equivalent to their ""%" HEX HEX" encoding.
除了"保留"或"危险"集里的字符(参见RFC 2396 [42]) ,字符等同于它们的""%" HEX HEX"编码.

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

      ~smith/home.html
      ~smith/home.html
      ~smith/home.html


3.3 日期/时间格式

3.3.1 完整日期

历史上的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格式以在头域里表示HTTP日期值.

注:鼓励日期值的接收者在接受可能由非HTTP应用发来的日期值时要坚定,这种非HTTP应用有时是通过代理/网关到SMTP或NNTP检索或张贴消息.

所有的HTTP日期/时间印记都必须毫无例外的以格林威治平均时间(GMT)表示.为了HTTP,GMT完全等同于UTC(协调世界时间).这在前两种形式里用三个字母的时区缩写-GMT的蕴含来表示,并且读取ASC时间格式时必须先被假定.HTTP日期区分大小写,除了在语法中作为SP特别包括的 LWS外,一定不能包括额外的LWS.
       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对日期/时间印记格式的请求仅仅应用在协议流里.客户和服务器不必为了用户简报,请求记录及其他而使用这些格式.

3.3.2 Delta秒

一些HTTP头域收到消息后,允许以十进制整数秒表示的时间值.
       delta-seconds  = 1*DIGIT

3.4 字符集

HTTP使用的关于术语"字符集"的定义和MIME中所描述的一样.

本文档中的术语"字符集"指一种用一个或更多表格将一个八字节序列转换成一个字符序列的方法.注意另一方向的无条件转换是不需要的,在这种转换里, 并不是所有的字符都能在一个给定字符集里得到,并且字符集可能提供多个八进制序列表示一个特定字符.这个定义将允许各种字符编码方式,从简单的单表格映射如US-ASCII到复杂的表格交换方法如ISO-2022的技术里所使用的.然而,与MIME字符集名字相关联的定义必须充分说明从八字节变换到字符所实现的映射.特别的,使用外部轮廓信息来决定精确映射是不允许的.

注:这里使用的术语"字符集"更一般的被称作一种"字符编码".不过既然HTTP和MIME使用同样的注册表,共用术语是很重要的.

HTTP字符集用不区分大小写的标记表示.完全标记集合由IANA字符集注册表[19]定义.
       charset = token

尽管HTTP允许用任意标记作为字符集的值,任何在IANA字符集注册表里有预先确定值的标记必须表示该注册表定义的字符集.对那些IANA定义的字符集,应用应该限制使用字符集.

实现者应该注意IETF字符集的要求[38][41].

3.4.1 失踪字符集

一些HTTP/1.0软件将没有字符集参数的内容类型头错误的理解为"接收者应该猜猜."若发送者希望避免这种情况,可以包含一个字符集参数,即使字符集是ISO-8859-1;当知道不会使接收者混淆时,也应该这样做.

不幸的是,一些旧的HTTP/1.0不能适当处理详细的字符集参数.HTTP/1.1接收者必须重视发送者提供的字符集标注;当最初显示文档时,那些提供"猜"字符集服务的用户代理必须使用内容类型域中的字符集,如果它们支持那个字符集,而不是接收者的首选项。参看3.7.1节。

3.5 内容编码

内容编码值表示一种已经或可以应用于实体的编码变换。内容编码主要用来允许文档压缩,换句话说,有效的变换而不损失它的基本媒体类型的特性,也不丢失信息。经常地,实体以编码形式储存,直接传送,只能由接收者译码.

       content-coding   = token

所有内容编码值都是不区分大小写的.HTTP/1.1在接收译码(14.3节)和内容译码(14.11节)的头域里使用内容编码值.尽管该值描述了内容编码,更重要的是它指出需要什么编码机制
来除去编码.

互联网赋值机构(IANA)充当内容编码值标记的注册处.最初,注册表包含下列标记:

  gzip(压缩程序)
一种由文件压缩程序"gzip"(GNU zip)---如RFC 1952所描述---生成的编码格式.这种格式是一种32位CRC Lempel-Ziv编码(LZ77).   [译者注]CRC:循环冗余校验

   compress(压缩)
由通用UNIX文件压缩程序"compress"生成的编码格式.这种格式是一种具有可适应性的Lempel-Ziv-Welch编码.
对未来的编码来说,用程序名识别编码格式是不可取,令人气馁的.在这里他们的用处是作为历史实践的代表而不是好的方案.为了同以前的HTTP实现相兼容,应用应该将"x-gzip"和"x-compress"分别等同于"gzip"和"compress".
 
   deflate(缩小)
RFC 1950 [31]定义的"zlib"格式与RFC 1951 [29]描述的"deflate"压缩机制的组合.

   Identity(标识)
    缺省(标识)编码;无论如何,不进行转化的应用.这种内容译码仅被用于接受译码报头,并且不能被用在内容编码报头.

  新的内容译码值的标记应该注册;为了允许客户和服务器间的互用性,内容译码运算的规范需要实现一个可被公开利用并能独立实现的新值,并且与这节中内容译码定义的目的相一致.

3.6  传输编码

   传输编码值被用来表示一个已经,能够,或可能需要应用于一个实体的编码转化,为的是能够确保通过网络安全传输.这不同于内容译码,传输译码是消息的特性而不是原始实体的特性.
       transfer-coding = "chunked" | transfer-extension
       transfer-extension      = token *( ";" parameter )

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

       参数                   = 属性  "=" 值
       属性                   = 标记
       值                     = 标记  |   引用-串(quoted-string)

   所有传输译码值是不直观的.HTTP/1.1在TE头域(14.39节)和传输译码头域(14.41节)运用传输译码.

   无论何时一个传输译码都被应用于一个消息体,传输译码的设置必须包括"大块",除非消息被结束连接停止.当"大块"传输译码被应用时,它必须是应用于消息体的最后传输译码.这些规则允许接受从而确定消息的传输长度(4.4节)

   传输译码与MINE[7]的内容传输译码值相类似,它被定义能够实现传送服务器超过7位的二进制数据的安全传输.不过,安全传输对纯8位传输协议有不同的焦点.在HTTP中,消息体唯一不安全的特性是确定确切的体的长度的这个难点(7.2.2节),或在共享传输上加密的要求.

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

   新的传输译码值标记应和新的内容译码值标记以相同的方式注册(3.5节).

服务器接收到一个不能理解的传输译码实体时应返回501(不实现),并且切断联系.服务器不能向HTTP/1.0客户发送传输译码.

3.6.1 成块传输代码(Chunked Transfer Coding)

   成块编码更改消息主体,为的是将它以一系列大块的形式传送,每一个连同它自己尺寸的指示器,被一个包含实体头域的可随意选择的trailer跟随.这允许有力量的地生产同接受所必需的消息一起转化的内容,从而检验它已经获得全部消息.
       Chunked-Body   = *chunk(大块)
       大块-正文           last-chunk(最后-大块)
                        trailer(追踪者)
                        CRLF

       chunk          = chunk-size [ chunk-extension ] CRLF
        大块          =  大块-尺寸 [ 大块 -扩展]CRLF
                        chunk-data CRLF
                         大块-数据 CRLF
       chunk-size     = 1*HEX
       大块数据
       last-chunk     = 1*("0") [ chunk-extension ] CRLF
        最后-大块     = 1*("0") [大块-扩展]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)
        追踪者        = * (实体-领先 CRLF)

   大块尺寸域是用16进制表示大块尺寸的一串数字.成块编码以任一尺寸为0的大块结束,后缀以trailer,以一个空行终止.

   trailer允许发送者在消息末尾包含附加的HTTP头域.trailer头域可被应用于简要说明包含trailer的头域 (14.40节)

   一个服务器在应答中运用传输译码时不能在任何头域使用trailer,除非以下至少一条为真:
   a)        请求包括一个TE头域时表明"trailer"在应答的转移译码中是可被接受的,就像14.39节中描述的那样;或者
   b) 服务器是为了应答的原始服务器,trailer的域完全由随意的元数据构成,这个接收者可以在不接受这个元数据的情况下使用消息(在一个原始服务器可接受的方式中).另一方面,原始服务器愿意接受trailer域可能会在通往客户的通道上被默默放弃的这种可能性.

   当消息被一个HTTP/1.1代理人接受并且8转寄至一个HTTP/1.0接受器时,这种需求防止了一个互用性的失误.它避免了一个依据协议将使在代理者上安置一个可能无限大的缓冲器成为必要的情形发生.

   对一个大块主体进行解码处理的例子已在附录19.4.6中作过介绍

  所有HTTP/1.1应用程序必须能接受和解码"大块"传输译码,并且必须忽略它们不理解的大块扩展扩展名.

3.7 媒体类型

   为了提供公开的,可扩展的数据输入和规范流通,HTTP在目录类型(14.17节)和认可(14.1节)头域中运用网络媒体类型.

       媒体类型       = 类型 "/" 亚类型*(";" 参数  )
       类型           = 标记
       亚类型       = 标记

   参数可能在属性/值的形式上遵循类型/亚类型.(如3.6节定义)

   类型,亚类型,和参数属性名称是不直观的.参数值直观与否,取决于参数名称的意义.
线性的白色空间(LWS)不能被用于类型和亚类型之间,也不能用于一种属性及他的值之间.一个参数存在与否对媒体类型的处理有着重要的意义,取决于它在媒体类型注册中的定义.

  注意一些旧的HTTP应用软件不能识别媒体类型参数.向一个旧的HTTP应用软件传送数据时,只有当类型/亚类型精确度需要时,才能实现媒体类型参数.

   媒体类型值已经在网络分配数码权威(IANA[19])注册.媒体类型的注册程序在RFC 1590[17]中略述.使用未经注册的媒体类型是不会得心应手的.

3.7.1 规范化和原文缺省

   网络媒体类型以语言的语音典型形式注册.一个通过HTTP通讯传输的实体必须被以先于传送的适当的规范的形式描绘,除'text'类形以外,就像下段定义的那样.

   当在规范的形式中,'text'类型的媒体亚类型运用GRLF作为全文行的间断.HTTP放松了这个要求,当一个完整实体被间断完成时,允许全文媒体以简单的GR或LF独立作为一行的隔断的传输. 在通过HTTP承认的原文媒体中,作为一个行的间断的代表,HTTP应用程序必须接受CRLF,空的CR,和空的LF. 而且,如果原文在一个特性设置中被表现,没有分别用8位字节13和10表示CR和LF,就像某种多重字节特性设置,HTTP允许使用任何被为了表现CR和 LF在行间断中的等同的特性设置所定义的任何8位字节次序.这个关于行间断的伸缩性仅仅应用于再一个实体中的原文媒体;一个空的CR或LF在任意HTTP 控制的结构中都不能代替CRLF.(例如头域和多部边界)

   如果一个实体把一个目录译码译成电码,在下面的译码必须被定义成在上面先被译码的形式.

   "charset"参数和一些媒体类型一起使用用来定义数据的特性设置(3.4节).当发送者没有提供清楚的charset参数,通过HTTP接受时"text"类型的媒体类型就被定义成有一个为"ISO-8859-1"的默认charset值.特性设置的数据不同于"ISO-8859-1"或它的子集必须被标以适当的charset值. 参见3.4.1节中兼容性问题.

3.7.2 多部分类型(Multipart type)

   MIME提供了一系列"多重部分"类型---在单个消息体内一个或多个实体的包装.所有的多重部分类型共享一个公共的序列,就像RFC 2046的5.1.1节中定义的那样.
   必须包括一个作为媒体类型值一部分的边界参数.这个消息体自成为一个要素协议,因此在两部分间只能用CRLF来表现行的间断.不同于RFC 2046,任一多重消息的末尾必须为空;HTTP应用程序不能传送末尾(即使原始的多重部分包含一个末尾).存在这些制约为的是保护一个多重部分消息实体的固有本质,结束多重部分边界已经在消息体的"结尾"加以表明.

   通常,HTTP将一个消息体视为与任何其他媒体类型无异:严格如有效负载.当消息体出现在206应答时,有一个例外就是"多重部分/字符串"类型(附录 19.2),将会被一些HTTP隐藏装置打断,就像13.5.4和14.16节中描述的那样.除此情况外,一个HTTP用户代理应该遵循与一个MINE用户代理相同或相似的行为,在多重部分类型收据之上.MIME头域在一个多重部分消息体的每一个部分里,对超过MIME意义的定义的HTTP没有任何意义.

  通常, 一个HTTP用户代理应该遵循与一个MINE用户代理相同或相似的行为,在多重部分类型收据之上.如果一个应用程序收到一个不能识别的多重部分亚类型,这个应用程序必须将它视为与"多重部分/混合"相等.

  注:"多重部分/形态-数据"形式已被在适合于通过POST请求方法处理的传送形式数据明确定义,就像在RFC 1867[15]中描述的那样.

3.8 产品标记

   产品标记被用来承认通过软件名和译本识别它们自己的通讯应用软件.很多域还把产品标记用于认可次级产品,专业产品构成应用软件中有重要意义的部分被一一列出,用白色间隔分开.按照惯例,按产品对于识别应用软件的重要性的顺序列出它们.

       产品           = 标示  ["/" 产品 -版本]
       产品-版本       = 标示

   例:
        用户-代理:   CERN-LineMode/2.15 libwww/2.17b3
      服务器: Apache/0.8.4
   产品标示应言简意赅.它们不能用来做广告或其他不重要的信息.虽然任一标示可能出现在产品-版本上,但这个标示仅能被用来做一个版本标识(i.e., 同类产品中成功的版仅区别在产品值的产品版本部分)

3.9 质量值(Quality Values)

  HTTP内容流通(12节)运用简短的"浮点"数字来表明不同可流通参数之间的重要联系("重要性").一个重要性从0到1规格化了一个真实的数字,0是最小值,是最大值.如果一个参数为0的质量值,那么这个参数的内容不被客户接受.HTTP/1.1应用软件不能产生多于小数点后三位数字.这些值的用户配置也应受限于这种方式.
       qvalue         = ( "0" [ "." 0*3DIGIT ] )
                      | ( "1" [ "." 0*3("0") ] )

   "质量值" 是一个不当的用词,因为这些值仅仅表现想要得到的质量中的降级关系.

3.10 语言标记

   一个语言标记和自然的语言一样说,写,或被人类用于与其他人传递信息.计算机语言明显不包括在内.HTTP在认可语言和目录语言域内运用语言标记.

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

        语言标记      = 主要标记    *("_"  下标签)
        主要标记   = 1*8ALPHA
      
        下标签        = 1*8ALPHA
      
    标签中不允许出现空格,标签对个例不敏感(case-insensitive).由IANA来管理语言标记中的名字间隔.典型的标签包括:

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

   任何两个字母的主要标签是一个ISO-639语言的缩写,两个大写字母的下标签是一个ISO-3166的国家代码.(上面的最后三个标签是未经注册的标签;除最后一个之外所有都是可在将来注册的例子标签).

3.11 实体标签

   实体标签用来从相同请求资源中比较两个或更多实体.HTTP/1.1在Etag(14.19节),If-match(14.24节),If-None- match(14.26节),和If-rang(14.27节)头域中运用实体标签.关于它们怎样像高速缓冲存储器确认一样使用和比较的解释在 13.3.3节中.一个实体标签由一个给定的不透明的一行组成,可能加上一个虚弱指示器的前缀.

      entity-tag = [ weak ] opaque-tag
      weak       = "W/"
      opaque-tag = quoted-string

   一个"坚固的(strong)实体标签"在两个实体八位子节相等时可能会被一个资源里的两个实体共享.

   一个"虚弱(weak)的实体标签",由"W/"前缀表示,在实体相等且可以互相替代而在语义上不发生重大的变动时,可能会被一个资源力的两个实体共享.一个虚弱的实体标签只能在虚弱对比时使用.

   一个实体标签必须在所有与一个特殊资源相连系实体的译本中是独一无二的.一个给定的实体标签值可以被不同的URI请求用来获得实体.相同实体标签值在不同URI请求获得实体的联合中的运用不意味着那些实体的等同.

3.12 范围单位(Range Units)

    HTTP/1.1允许一个客户要求单独部分的应答实体被包括在应答内.HTTP/1.1在范围(14.35节)和目录范围头域(14.16节)运用范围单位.一个实体可根据不同的结构单位分解成子区域.

       范围-单位       = 字节-单位 |  其他-范围-单位
      字节-单位        =  "字节"
      其他-范围-单位   = 标记

   HTTP/1.1中定义的唯一的范围单位是"字节".HTTP/1.1实现时可能忽略其他单位指定的范围。
   HTTP/1.1的设计允许应用软件不依靠有关范围的知识而实现


4 HTTP消息

 Copyright  (2007).          All Rights Reserved.

4.1  消息类型

      HTTP消息由从客户到服务器的请求和从服务器到客户的回答组成.
              HTTP-消息 = 请求|回答 ;HTTP/1.1 消息
       请求(第五节)和回答(第六节)的消息是用一般的消息格式RFC 822[9]来传输实体的(消息的有效载荷).这两种消息都是由开始行,零或者更多的头域(也叫做头),象征头结束的空行(譬如说一个只有回车字符的行)组成,有时可能会有一个信息体.
       一般的消息=开始行
                  *(消息头 CRLF)
                  CRLF
                   [消息的内容]
       开始行    =请求行|状态行
       为了健壮性,服务器必须在期望收到要求行的地方忽略任何接收到的空行.换句话说,如果服务器在读一条信息开始的协议流时先收到了CRLF,它必须忽略这个CRLF.
       一般一个有问题的HTTP/1.0客户端在POST请求后会产生额外的CRLF.为了重述什么是BNF明确禁止的,一个HTTP/1.1客户端没有必要开始和跟随一个额外的CRLF的请求.

4.2 消息头
     HTTP头域包括常规头(4.5节)请求头(5.3节),应答头(6.2节)和实体头(7.1节)域,它们遵循RFC822[0]3.1节中给出的同一个常规的格式.每一个头域由一个紧跟":"的名字和域值构成.域名是大小写不敏感的.域值可能在任何LWS的前面,尽管单个的SP是首先的.头域能通过把各个额外行(至少有一个SP或HT)前置来扩展成多行.当产生HTTP结构的时,应用必须遵循"共同格式",那儿它被知道或定义,即使有时存在一些不能接受任何东西的操作.

  共同的格式.

消息-头=域名":"[域值]
域名=记号
域值=*(域的内容|LWS)
域的内容=<由八位的字节构成域值,它由文本或组合标记,分割符,和引用的字符串组成>

这个域的内容不包括任何引导的或连接的LWS:位于域内容属性的第一个不是空白的地方的前面或最厚的布是空白的地方的后面.去掉这些引导或连接的LWS可能不会影响域内容的意思,任何位于域内容之间的LWS在解释域的内容或传送消息的下载流的时候可以用单个的SP替换.
用不同域名收到的头域的顺序不是重要的.但是,一个好的习惯是先送常规头,接着是请求头或应答头,最后是实体头域.

多个消息头域使用同一个域可能会出现在一些消息中,在这些消息中,可能也只可能是整个域用逗号分割的列表定义(例如,#(值)).这些必须有可能在没有改变消息的情况下被组合成一个"域名:域值"对,在这些被逗号隔开的域中后面的域植被添加到第一个域中.那些用同一个域名组成一个头域的顺序是重要的,因此当一个消息在传输的时候代理一定不能改变这些域值的顺序.

4.3 消息体

  HTTP消息的消息体备用用来传输由要求和应答组成的实体.这些消息体仅仅当传输译码被应用的时候才和实体不同,这用传输编码的头域标明(14.41节).

     消息体=实体|<编码的实体>

传输编码常用来表示那些应用程序为了安全和保证消息的正确传输的传输码.传输编码是一种消息的属性而不是实体,因此沿着请求/应答链它可以被任何应用程序加上或去掉.

   当一个消息中允许有消息体时的规则和请求应答时的不一样.

   一个请求的消息体是用来传达内容长度或请求传输编码头的传输编码头域的信息.如果请求方式的规范不允许请求中加入实体则一个请求中也必须不能包括消息体. 一个服务器必须读和处理任何请求的消息体;如果请求方法没有定义一个实体的表述,则当处理这个请求是必须忽略消息体.

   对于应答消息,一个消息是否包括消息体依赖于请求的方法和应答的状态代码(6.1.1节).对于所有头请求方法的应答都不能包括消息体,即使有时实体头域的存在让人相信它们包括了.所有1XX(信息的),204(无内容的),和304(没有修改的)的应答都不能包括消息体.所有其他的应答必须包括消息体, 虽然它可能长度为零.

4.4 消息的长度

     一条消息的传输长度是消息体出现在消息中的长度,也就是说,当传输代码被处理以后.当一条消息包含消息体,实体的输长度有以下几条决定(以先后顺序):

     1。任何回应信息不应包含在信息体中,如1xx,204,304回应和任何对头请求的回应。这种情况都是在头域结束后第一行为空白行,不管实体域是否出现。

     2。传输代码头域(属于general-header域)出现的话而且有值而不是身份,那么传输长度就可以使用chunked大块来确定,除非信息由于连接关闭而中断了.

     3。如果Content-Length头域(属于实体头)出现,那么它的值是信息体传输长度。如果传输头域和Content-Length头域都出现了,而长度不一致,那么Content-Length头域中的值就不该传。

     4。如果被1.0代理传送的范围头域不能理解多部份/位范围;服务器必须采用1,2,3的方式界定信息体长度。

     5。当服务器正在关闭连接.(正在关闭连接不能用来说明应答体的结束,因为它将导致服务器没有可能送回一个应答信号.)

为了与HTTP/1.0应用程序兼容,HTTP/1.1请求包含的消息体必须包括一个有效内容长度的头域,除非知道服务器适应HTTP/1.1.如果一个请求包含一个消息体并没有给出内容长度,那个服务器会应答400(错误的请求)如果他不能判断消息长度的话,或者应答411(要求成都)如果它坚持想要收到一个有效内容的长度.

所有的HTTP/1.1应用程序必须接受"CHUNKED"传输代码(3.6节),因此允许这种机制来处理消息当消息的程度不能被决定.

消息没有必要都不包括内容长度头域和non-identity传输代码.如果消息包括了一个non-identity传输代码,传输长度必须忽略.

当一个内容的长度在消息体允许的地方给出时,这个域值必须和消息体中八进制数一致.HTTP/1.1用户代理必须通报使用者当一个无效的长度被接受和发现.

4.5 常规头域

   这儿有一些头域能适应一般的请求和应答消息,但是它没有应用渔船树种的实体.这些头域只应用于那些被发射的消息.

     常规的头域=高速缓存控制         ;14.9节
                |连接         ;14.10节
                |数据         ;14.18节
                |程序         ;14.32节
                |追踪         ;14.40节
                |传输编码     ;14.41节
                |升级         ;14.42节
                |路由         ;14.45节
                警告          ;14.46节

   常规头域的名字的真正扩展必须和协议版本的变化相结合。然而,新的或实验性质的头域可能被赋予常规头域的意义,如果信息传输中的所有部分都承认它们为常规头域的话,未被承认的头于一般当实体头域看待。


5 请求

从客户机到服务器的请求,其首行包括利用资源的方式,区分资源的标识,以及协议的版本号
请求   =请求行                       ;  5.1节
       *((常规报头                    ;  4.5节
         |请求报头                    ;  5.3节
         实体报头)CRLF)              ;  7.1节
           CRLF       
         [消息正文]                   ;  4.3节

5.1 请求行

   请求-行的开头是方法标识,接下来是请求URL和协议版本号,以回车换行结束.各部分之间用空格符(SP)分隔,除了最后的回车换行外,不允许有回车(CR)和换行(LF).

       请求-行  ==方式(空格) 请求URI(空格)  HTTP版本号(回车换行)

5.1.1方法

  方法标记指的是在请求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)

扩展方式=   标记

资源允许的方法列表能由允许(Allow)报头域详细指定.既然被允许方法的设置可以动态的改变,返回的应答码总是通知客户机当前方法是否被允许. 如果原服务器知道方法,但方法不被请求的资源允许,原服务器应当返回状态码405(方法不允许).如果方法不被原服务器承认和实现,原服务器应当返回状态码501(没有实现).获取(GET)和报头(HEAD)方法应当被所有的多功能服务器支持.其他所有的方法是可选的,然而,假若以上的方法没有实现,则他们必须被在第九章里所说明的同一种语法定义所实现.

5.1.2 请求URL

  请求URL是一种全球统一的应用于资源请求的资源标识符(3.2 节).
 
    请求URL   ="*"|绝对URL|绝对路径|主机authotity

请求URI的四个选项在一般情况下是互相关联的,星号"*"表示请求不是应用于某种特别的资源,而是服务器本身,只有当所用的方法不是资源必要的方法才是允许的.举例如下

             选项(OPTIONS)*HTTP/1.1

当代理服务器产生请求时,绝对URI地址是不可缺少的.代理服务器被要求转寄来自高速缓冲存储器有效的请求或服务,返回应答.注意到代理服务器可以把请求转发给另一台代理服务器或直接转发给绝对URI地址说明的服务器.为了避免请求循环,代理服务器必须识别所有的服务器名字,包括任何别名,本地变异名,数字IP地址.请求行举例如下:
     
     GET  HTTP/1.1

为了在未来的HTTP版本的所有请求中转换绝对URL地址,所有基于HTTP/1.1的服务器必须接受绝对URL地址的组成,虽然基于HTTP/1.1的客户机将只产生请求发给代理服务器

主机(authority)组成部分只是在连接方法(CONNECT)中用到(9.9节).

最通用形式的请求URI用于标识在原服务器或网关上的资源.这种情况下,绝对URL路径必须作为请求URL传送(看3.2.1节,绝对路径),URI局域网地址(authority)(必须输入主机报头域.例如,希望直接得到原服务器顶层资源的客户机将在"www.w3.org"主机的端口80建立TCP连接发送以下行:
  
   GET /pub/WWW/TheProject.html HTTP/1.1
      Host:

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

请求URL用在3.2.1节里说明的格式传输.如果用"%HEX HEX"[42]码编码,为了正确的翻译请求,原服务器必须译码.对于有适当状态码的无效的请求,服务器必须给予应答.

当透明的代理服务器转发收到的请求URL地址给下一台网内的服务器时,禁止其重写 "绝对路径"部分,上面提到的用"/"代替空的绝对地址不在此例.

注:当原服务器不恰当的用非保留URL字符作保留用时,"禁止重写"规则防止
代理服务器更改请求的含义,实现程序将了解前面的一些HTTP/1.1代理服务器就将知道改写了请求URI.

5.2请求定义的资源

一个INTERNET请求所定义的精确资源由请求URL和主机报头域所决定.

当决定HTTP/1.1协议标识的资源时,不允许资源与请求主机不同的原服务器可以忽略主机报头域的值,(但看19.6.1节了解支持HTTP/1.1主机上的另一种需求).

基于主机的请求区分资源的服务器(有时指虚拟的主机或空白的主机名)必须用以下的规则决定HTTP/1.1请求所请求的资源.

1. 如果请求URI是绝对地址,主机是请求URI的一部分.任何主机报头域应当忽略.
2. 假如请求URI不是绝对地址,且请求包括一个主机报头域,则主机由该域的值所决定.
3. 假如由规定1或规定2定义的主机是无效的主机,则应答当是一个400出错信息

为了找出真正被请求的资源,一个缺乏主机标识域的HTTP/1.0请求接收者可以尝试使用试探的方法(例如检测URI路径对于特定的主机是唯一的这个性质).

5.3请求报头域

请求的报头域允许客户传递关于请求,客户自己的附加信息给服务器.这些域作为请求修饰成分,和程序语言中方法调用的参数有差不多的含义.

   请求报头 = 接收(Accept)                          ;14.1节
                   |接收Charset (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节

随着协议版本的变化,请求报头域的名字可以可靠的扩展.然而新的或扩展的报头域可以给出请求报头域的语法,其前提是通信中所有部分承认它们是请求报头域.不被承认的报头域被当作实体报头域.

6 应答

接收和翻译一个请求信息后,服务器发出一个HTTP应答信息.

     应答   =状态行                                  ;6.1节
           *((常规报头(general-header)                ; 4.5节
                       |应答报头(response-header)            ;6.2节
                       |实体报头(entity-header)CRLF)          ;7.1节
                             CRLF
                      [应答正文]                             ;7.2节

6.1 状态行

应答信息的第一行是状态行,由协议版本以及数字状态码和相关的文本说明组成,各部分间用空格符隔开,除了最后的回车或换行外,中间不允许有回车换行.
     
   状态行 = HTTP版本 SP状态码 SP 原因短语 CRLF

6.1.1状态码与注解

状态码是试图理解和满足请求的三位数字的整数码,这些码的完整定义在第十章.注解短语是特意给出的关于状态码的文本描述.状态码用于自动控制而注解短语是面向用户的.客户机不需要检查和显示注解短语.

状态码的第一位数字定义应答类型.后两位数字没有任何类型任务.第一位数字有五种值:

-1xx: 报告的                - 接收到请求,继续进程.
-2xx  成功                  - 操作成功的收到.
-3xx  重发              - 为了完成请求,必须采取进一步措施.
-4xx  客户端出错            - 请求包括错的顺序或不能完成.
-5xx  服务器出错            - 服务器无法完成显然有效的请求.

为HTTP/1.1定义的状态码单独的值,和一个相应的一系列注解短语的例子,介绍如下,这儿列出的注解短语只是建议――它们可以被相当的没有感情色彩的协议取代.

  状态码 =
               "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版本不支持
              |扩展码 

扩展码 =3DIGIT
注解短语=*

HTTP状态码是可扩展的.HTTP应用程序不需要理解所有已注册状态码的含义,尽管那样的理解显而易见是很合算的.但是,应用程序必须了解由第一位数字指定的状态码的类型,任何未被识别的应答应被看作是该类型的X00状态,有一个例外就是未被识别的状态码不能缓存.例如,如果客户机收到一个未被识别的状态码431, Copyright  (2007).          All Rights Reserved.
则可以安全的假定请求有错,且其对待应答的情况是仿佛客户端收到的是400状态码.在这种情况下,用户代理应当把实体和应答一起提交给用户,因为实体很可能包括说明不平常状态的人认可读的信息.

6.2应答报头域

应答头允许服务器传送应答的附加信息,这些信息不能放在状态行里.这些报头域给出有关服务器的信息以及请求URI指定的资源的下一步的通路.

   应答报头  =  接收范围                        ; 14.5节
                   |生存时间         ; 14.6节
                   |Etag            ; 14.19节
                   |位置                 ; 14.30节
                   |代理认证            ; 14.33节
                   |等会再试            ; 14.37节
                   |服务器             ; 14.38节
                   |变化               ; 14.44节
                   |WWW认证                ; 14.47节

随着协议版本的变化,应答报头可以可靠的扩展.而且,如果通信的所有组成部分都把它当作应答报头域,新的或试验性的应答报头域可以被给定应答报头域的含义,未被承认的报头域被当作实体报头域.


7。 实体。

在未经特别规定的情况下,请求与应答的报文也可以传送实体。 实体包括实体报头域与实体正文,而有些应答只包括实体报头。在本节内,接收者与发送者既可以指用户端,也可以指服务器,视由谁收发实体而定。

7。1 实体报文域

实体报文域定义了关于实体正文的维护信息(参数),或在无正文情况下定义了请求的资源。其中一些参数是可选的,一些则是由技术指标规定必须的。

实体报头 = 允许(Allow);                        14.7节
                        |内容编码;                                14.11节
                        |内容语言;                                14.12节
                        |内容长度;                                14.13节
                        |内容位置;                                14.14节
                        |内容-MD5;                                14.15节
                        |内容范围;                                14.16节
                        |内容类型;                                14.17节
                        |过期(Expires);                        14.21节
                        |上次修改;                                14.29节
                        |扩展报头

扩展报头=报文报头

扩展报头机制允许在不改变协议的前提下定义额外的实体报头域,但不保证这些域在收端能够被识别。未被识别的域应当被接收者忽略,且必须被透明转发。


7。2 实体正文。

经由HTTP请求或应答发送的实体正文部分(如果存在的话)的格式与编码方式应由实体报文域决定。
    
       实体正文= *八位字节

如4。3节所述,实体正文只有当报文正文存在时才存在。实体正文是通过对报文正文按某种保证安全性且便于传输的传输编码进行解码得到的。

7。2。1。 类型。

对于报文中的实体正文而言,其数据类型由报头中的"内容类型"与"内容编码"域决定。也即定义了一个双层有序的编码模型:

    实体正文=内容编码(内容类型(数据))

"内容类型"规定了基本数据的媒体类型。
"内容编码"则可用来指明对数据施加的任何附加的,通常以数据压缩为目的的编码方式,并将其作为所请求资源的一项属性。 没有缺省的编码方式。

任一包含了实体正文的HTTP/1。1报文都应包括"内容类型"报头域,以定义正文的媒体类型。当且仅当"内容类型"域未给出媒体类型时,接收者才可以通过查看资源的内容,扩展名或URL来猜测其媒体类型。若媒体类型仍然未知,接收者应将其作为"应用/八位字节流"类来处理。

7。2。2 实体长度

报文的实体长度指的是在对报文进行传输编码前报文正文的长度。4。4节定义了确定报文正文传输长度的方法。


8。连接

8。1 持续连接。

8。1。1 目的

在持续连接之前,为获取每一URL都建立了独立的TCP 连接,这就加重了HTTP服务器的负担,易引起INTERNET阻塞。嵌入式图片与其它相关数据通常使用户在短时间内对同一服务器提交多个请求。目前已有针对这些性能问题的分析以及原型实施的结果[26],[30]。 实施的具体过程和对实际HTTP/1。1(RFC 2068)的测试均显示了良好的结果[39]。 对其他方法也有了初步探究,如T/TCP [27]。

持续HTTP 连接有着诸多的优点:

--- 通过建立与关闭较少的连接,不仅节省了路由器与主机(客户机,服务器,代理服务器,网关,隧道或高速缓冲存储机)的CPU时间,还节省了主机用于TCP协议控制块的内存。

--- HTTP请求与应答可以进入连接流水线。 流水线方式使得客户无须挨个等待应答即发起多个请求,从而更充分的利用了单个的TCP连接,减少了崩溃时间。

--- 在减少TCP连接中数据包个数的同时,使TCP有了充裕的时间来确定网络的拥塞状况,缓解了网络拥塞。

--- 因为无须在创建TCP连接握手上耗费时间,而使连续请求造成的延迟现象得到改善。

--- 由于出错不会导致TCP连接的关闭,HTTP可以更好的实现自我完善。使用较新版HTTP的用户会乐于尝试一些新功能,与旧版服务器通信时,则会在接到出错报告后用旧模式重试。

HTTP的实现应当采用持续连接。

8。1。2 总体操作

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

持续连接提供了一种可以由客户机或服务器发信号终止TCP连接的机制。终止连接的信号利用了"连接"报头域(14.10节)。一旦出现了终止连接的信号,客户机便不可再向此连接提出任何新请求。

8。1。2。1 谈判

除非请求的连接报头域中包括了"终止连接"的符号,HTTP/1。1服务器总可以假定HTTP/1。1 客户机想要维持持续连接。如果服务器想在发出应答后立即终止连接,它应当发送一个含有终止要求的连接报头域。

无论是客户机或服务器发起终止连接,这都是本次连接的最后一个请求。

除非经明确指出,客户机与服务器不应假定低版HTTP会自动采用持续连接方式。请参见19。6。2节关于与HTTP/1。0客户机后向兼容性的有关内容。

为了维持持续连接,连接中的报文都必须有如4。4节所述的自定义报文长度(即不是由连接终止定义的长度)。

8。1。2。2 流水线

支持持续连接的客户机可以以流水线方式发送请求(即无须等待应答而发送多个请求)。服务器则必须将其应答按接到请求的顺序发出。

建立连接后立即采用持续连接与流水线方式的客户机应作好初次流水线尝试失败后重试的准备,而不可在持续连接尚未确定时就连续发送请求。客户机还必须为服务器在发出所有应答之前就结束连接的情况作好重发请求的准备。

客户机不应该用非等幂方法或非等幂方法序列(参见9。1。2节)连发请求。否则,过早终止的传输层连接会导致不确定的结果。

8。1。3 代理服务器

使代理服务器正确地实现14。10节所规定的连接报头域的属性是非常关键的。

代理服务器必须独立于它所连接的客户机,原服务器(或其它代理服务器)而发出持续连接的信号。每一持续连接仅针对传输层链接。

代理服务器不可与一台HTTP/1.0客户机建立HTTP/1。1持续连接(请参见RFC 2068 [33] 中关于HTTP/1。0客户机上实现"维持活跃态"报头问题的探讨及资料)

8。1。4 实际的考虑

服务器通常有一个时限值,超过一定时间即不再维系处于非活跃态的连接。代理服务器会选一个较高的值,因为客户机很可能会与同一服务器建立多个连接。持续连接方式的采用对于客户机与服务器的时限均未提出任何要求。当客户机或服务器希望超时终止时,它应按规范终止传输连接。客户端与服务器端应始终注意对方是否终止了连接,并适当的予以应答。若客户机或服务器未能及时检测到对方已终止了连接,将会造成不必要的网络资源浪费。

客户机,服务器,或代理服务器可能在任意时刻终止传输连接。比如,客户机可能正想发出新的请求,而此时服务器却决定关闭"闲置"的连接。在服务器看来,连接是在闲置状况下被关闭的, 而客户机却以为请求在进行中。

这表明客户机,服务器与代理服务器必须有能力从非同步的连接终止事件中恢复。只要请求序列是等幂的(参见9。1。2节),客户端软件就应自动重新发起传输层连接并重传被废弃的请求序列。对非等幂方法或序列不可自动重试,但用户代理可以向手工操作员提供重发请求的机会。用户代理软件对应用程序基于句法理解的确认可以用来代替人工方式。若重试失败,则不应允许再试。

服务器在每次连接中只要有可能,总应至少应答一个请求。除非出于网络或客户端的故障,服务器不应在传送应答的中途断开连接。

使用持续连接的客户机应限制与某一服务器同时连接的个数。单用户客户机不应与任一服务器或代理服务器保持两个以上的连接。代理服务器与其它服务器或代理之间应维护2*N个连接,其中N是同时在线的用户数。设定这一规则是为了改进HTTP应答时间且避免拥塞。

8。2 报文传输要求、

8。2。1 持续连接与流量控制

HTTP/1。1服务器应当保持持续连接并使用TCP的流量控制机制来解决临时过载,而不是在终止连接后指望客户端的重试。后一方法会恶化网络阻塞。

8。2。2 监视连接中出错状态的报文

发送报文正文的HTTP/1。1(或更新)客户机应在传输请求的同时监视连接是否处于出错状态。若客户机发现了错误,它应当立即停止正文的传送。若正文是以块编码方式发送的(3。6节),可以用一长度为零的块和空报尾来提前标记报文结束。若正文前有"内容长度"报头,则客户机必须关闭连接。

8。2。3 100号状态的用途

100号状态的目的在于帮助那些发送含有请求正文的请求报文的客户机在发送请求正文之前推测服务器看到请求报头后是否愿意接收请求。有些时候,如果服务器不看正文就弃置报文的话,客户机对正文的发送就多此一举了。

对HTTP/1。1 客户机的要求:

--- 若客户机在发送请求正文之前等候100(继续)应答,则它必须发送填有"100--继续"期望的"期待请求"报头域(14。20节)。

--- 若客户机不需要发送请求正文,则它不得发送填有"100--继续"期望的"期待请求"报头域(14。20节)。

由于存在旧的实现方法,协议允许出现诸如客户机发出了"期望:100-继续" 却没接到417(期望失败)或100(继续)状态的混乱局面存在。因此,当客户机将这一报头域发给它从未接到100(继续)状态的原服务器(通常是通过代理)时, 客户机不应在发送请求正文前无限期地等待。

对HTTP/1。1原服务器的要求:

--- 在接到"期望"请求报头域填有"100-继续"期望的请求时,原服务器必须以100(继续)状态应答并继续读入数据流,或者以终止状态码应答。原服务器在发送100(继续)应答之前不得等待。若以终止状态码应答,它既可关闭传输层连接,也可继续读入数据而丢弃请求的剩余部分。但此时它不得按客户机所请求的方式运行。

--- 如请求报文不含填有"100-继续"的"期望"报头域,原服务器不应发送100(继续)应答。当请求来自HTTP/1。0(或更早)客户机时也不得发送100(继续)应答。对此规定有一例外:为了与RFC 2068兼容,服务器对于未含填有"100-继续"的"期望"报头域的PUT或POST 请求可以应答100(继续)状态。这一例外的目的在于尽量减少由100(继续)状态的未申明等待引起的客户机处理延迟,仅适用于HTTP/1。1请求,和其它HTTP 版本的请求无关。

--- 若已经接到相应请求的部分或全部请求正文,原服务器可以免发100(继续)应答。

--- 一旦请求正文被收到处理,发出100(继续)应答的原服务器除非过早切断传输层连接,否则最终必须发送终止状态码。

--- 若原服务器接到不含填有"100-继续"的"期望"报头域的请求,该请求含有请求正文,而服务器又在从传输层连接读入正文之前就应答了终止状态码,则服务器不应在读完全部请求或客户机终止连接前关闭连接。 否则,客户机可能无法可靠地接收应答报文。然而,这一要求在阐释中不应阻止服务器防卫拒绝服务的攻击或有严重缺陷的客户程序。

对代理服务器的要求:

--- 若代理服务器接到包含填有"100-继续"的"期望"报头域的请求,且代理服务器要么知道下一站服务器遵循HTTP/1。1或更高版协议,要么不知下一站服务器的HTTP版本,则它必须连同"期望"报头域一起转发此请求。

--- 若且代理服务器知道下一站服务器版本是HTTP/1。0或更低,则它不得转发此请求,而应应答以417(期望失效)状态。

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

--- 若接到的请求来自于版本是HTTP/1。0(或更低)的客户机,不含填有"100-继续"的"期望"报头域的请求,则代理服务器不得转发100(继续)应答。 这一要求可覆盖1xx应答转发的一般规则(参见10。1节)。

8.2.4 服务器过早关闭连接时客户机的行为

如果HTTP/1。1 客户机发出一条含有请求正文但不含填有"100-继续"的"期望"报头域的请求,并且客户机直接与HTTP/1。1原服务器相连,在从服务器处接到任何状态信息之前就发现连接被关闭,那么客户机应当重试请求。在重试时,客户机何以采用如下所述的"二进制指数后退算法"以确保获得可靠应答:

1. 向服务器发起一新连接。
2. 发送请求的报头。
3. 初始化变量R为通往服务器的往返时间的估计值(比如基于建立连接的时间),或在无法估计往返时间时设为一常数值5秒。
4. 计算T=R*(2**N),N为此前重试请求的次数。
5. 等待服务器发来的出错应答或是T秒(两者中时间较短的)。
6. 若没等到出错应答,T秒后发送请求正文。
7. 若客户机发现连接被提前终止,转到第1步,直到请求被接受,接到出错应答,或是用户因不耐烦而终止了重试进程。

在任意环节上,客户机如果接到出错状态,
--- 不应再继续, 并且
--- 如完成请求报文的发送则应终止连接


9 方法定义

HTTP/1.1常规方法的定义如下.虽然这个定义可以展开,但附加的方法不能被假定分享和个别扩展的客户机和服务器同样的语义.

主机请求应答报头(14.23节)必须符合所有的HTTP/1.1请求.

9.1 安全和等幂(Idempotent)方法

9.1.1 安全方法

实现程序应当知道软件通过在Internet上的交互来扮演用户,且应该仔细的允许用户知道任何它们可能采取的行动,这些行动可能给他们自己或他人带来无法预料的结果.

特别的.这样的惯例已经形成,就是GET和HEAD方法除了补救外不应该有别的采取措施的含义.这些方法应该被看作"安全".这允许用户代理描绘其他方法,像POST,PUT,DELETE,在某种意义上,用户知道某种不安全的行为被请求的事实.

自然, 随着GET请求的实现,不可能保证服务器不产生副作用;事实上,一些动态的资源考虑到那样的特征.在这里重要的区别是用户没有请求副作用,因此不应该为此承担责任.

9.1.2 等幂方法

方法也可以等幂的性质,这种情况下(除了出错或终止问题)N>0个同样请求的副作用和单个请求一样.方法 GET,HEAD,PUT,DELETE都有这种性质.而且,方法OPTIONS和TRACE不应该有副作用,等幂就是这样的含义.然而,有可能几个请求的序列是不等幂的,即使在那样的序列中所有方法单独实现都是等幂的(如果整个序列整体的实现结果总是相同的,即不因序列整体,部分的重新实现而变化,则序列是等幂的).例如,如果一个序列实现的结果依赖一个序列中后来可以修改的值,则该序列不是等幂的.

没有副作用的序列是等幂的(倘若在同样的资源配置下不同时操作)

9.2  OPTIONS(选项)

OPTIONS方法描述了在请求URI确定的请求/应答过程中通信条件是否可行的信息.该方法允许客户机确定条件或设备,其与资源或服务器的没有暗示资源操作或初始化资源重建的情况下的性能有关,

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

如果OPTIONS请求包括一个实体(用来指示内容长度或传输码的存在),接着媒体类型应该有一个内容内型域来确定.虽然这种规定对那样的主体没有定义任何功能,未来HTTP的扩展可以用OPTIONS域来安排更多细节性的有关服务器的询问.一台不支持扩展的服务器可以抛弃请求正文.

如果请求URI是一个星号("*"), OPTIONS请求特意应用于总的服务器而不是特定的服务资源.既然服务器的通信条件取决于资源,"*"请求只是作为"ping" 或 "no-op类型的方法才有用;它只能允许客户机测试服务器的性能.例如,这能被用来检测一台代理机即是否支持HTTP/1.1.

如果请求URI不是一个星号("*"), OPTIONS请求只是当和资源通信时应用于条件是否可能.

应答200应当包括表示服务器实现和可应用于资源的可选择的特征报头域,.可能包括这种规范定义未定义的扩展.规范没有定义正文,但未来HTTP的扩展可能会定义,商议内容可能会用于选择适当的应答格式.如果没有应答体被包括进来,应答必须包括一个值为零的内容长度域.

最大转发请求报头域可以用于请求过程中特定的代理机.当代理机收到可以继续传播的绝对URI的OPTIONS请求时,代理机必须检测最大转发域.如果最大转发域的值是零,代理机禁止转发信息.相反的,代理机将回答它自己的通信条件.如果是大于零的整数,当代理机转发请求时,该域的值将逐渐减小.如果请求中没有该域,则转发请求当中也会没有.


9.3 GET(获取)

GET方法重建信息的内容(正文的形式)由请求URI来确定.如果请求URI指数据产生的过程,它是在应答中产生,被当作正文返回的数据,而不是过程的源文本,除非文本碰巧是过程的输出.

如果请求信息包括 If-Modified-Since, If-Unmodified-Since,If-Match, If-None-Match, or If-Range报头域, GET的语义将变成"条件(conditial) GET". 只有在条件报头域(conditional header)所描述的环境下, 条件GET方法请求实体被传输. "条件GET"方法用于减少不必要的网络使用,这种使用允许在没有多种请求或客户机已经获传输数据的情况下刷新缓存实体.

如果请求信息包括范围(Range)报头域, GET方法的语义将变成"部分(partial)GET","部分GET"请求只要求传输部分实体,如14.35节指定的那样. 部分GET方式通过允许当客户端没有得到全部的传输数据时部分的重建数据来减少不必要的网络使用.

只有当GET请求碰到13章里所描述的支持HTTP缓存的设备时,应答才是可缓存的.

当使用表格形式时.请参看15.1.3节关于安全的考虑.


9.4 HEAD(报头)

除了应答中禁止返回消息正文外,HEAD方法与GET方法一样.包含在HTTP报头以后应答报头头请求的信息与POST去应答GET请求的信息是相同的.这种方法能用于获得关于实体更多的信息,没有传输实体正文本身的请求暗示了这种信息.这个方法常用来检查超文本链接的有效性,可到达性和最近的修正.

当包含在应答中的信息可以用来更新以前缓存的来自资源的实体时,对HEAD请求的应答是可缓存的.如果新域的值显示缓存的实体不同于当前的实体时(这将在内容长度,内容-MD5,ETAG或最后更新时间中表现出来),缓冲区就抛弃缓存的实体.


9.5 POST(张贴)
在POST 方法适用的请求中,原服务器接收附加在请求后的实体,该实体后作为请求行里请求URI指定的资源的次要部分,. POST 被设计为具有如下的功的统一的方法:

- 已有资源的注解.
- 在电子布告版,新闻组,邮箱或类似的主题组贴一些信息.
- 提供数据块,像确认表单数据处理的结果.
- 通过附加的操作扩充数据库.


POST方法实现的实际功能取决于服务器,且往往取决于请求URI.POST实体属于URI,就像文档属于包括它的目录,新闻主题属于它所在的新闻组,或纪录属于数据库.

POST方法实现的操作不会作用于URI可以鉴识别的资源.在这种情况下,无论2000(OK)还是2004(无目录)是合适的应答状态,取决于应答是否包括描述结果的实体.

如果原服务器上已经建立了资源,应答将是201(建立)且包括描述请求状态,指向新的资源的实体和一个本地报头(看14.30节).

这种方法的应答是不可缓存的,除非应答包括合适的缓冲控制或终止报头域.然而,303(看别的)应答可直接用于用户代理重建可缓存资源.

POST 请求必须像8.2节所描述的那样服从消息传输的需要.

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

9.6 PUT(放置)

PUT方法要求所附实体存储在提供的请求URI下.假如请求URI指的是已经存在的资源,所附的实体应当被当作原服务器中已修改的版本. 假如请求URI指的不是已经存在的资源,而URI可以被客户代理定义成新的资源,原服务器可以建立该URI资源.假设建立了新资源,原服务器必须通过 201(建立)应答通知用户代理.如果修改了已有资源,将发送200(OK)或204(无内容)应答表示请求的成功完成.如果对于该URI资源不能创建或修正,将给出合理的出错应答来反映问题所在.实体容器不能忽视任何不被理解或实现的内容-*(例如内容范围)报头,这时必须返回501(未实现)应答.

如果请求经过高速缓冲存储器和请求URI标识一个或多个当前缓存的实体,这些实体将被抛弃.这个方法的应答是不可缓存的.

POST和PUT请求基本的不同点反映在请求URI的不同意义.POST方法中的URI标识将处理附加实体的资源.资源可以是数据接收过程,一个网关和一些协议,或一个接收注解的分散的实体.与之相对照的是, PUT请求中的URI标识请求所附的实体-用户代理了解什么URI是有意的和服务器禁止试图应用请求于别的资源.假如服务器希望请求应用于不同的URI,

它必须是301(永久移动)应答;用户代理可以自己决定关于是否改变请求路由.

单个的资源可以被许多不同的URI确定.例如,一个主题可以有一个URI识别当前版本,这从URI识别每一个特定的版本分离开来.在这种情况下,PUT请求中一般的URI导致服务器,而其他的URI由原服务器定义.

HTTP/1.1没有定义PUT方法如何影响原服务器的状态.

PUT请求必须服从8.2节描述的信息传输需要.

除了特定的实体报头说明,POST方法中的实体头应该应用于POST方法创建或修改的资源.

9.7 DELETE(删除)

DELELE方法要求原服务器释放请求URI指向的资源.这种方法可以通过原服务器上人的强行干涉而制止(括其他手段).客户机不能担保操作已经实现了,即使从原服务器返回的状态码说明操作已经成功的完成.但如果当时应答未给出的话,服务器不应该表示成功,它打算释放资源或移到不能访问的位置.

假如应答包括描述状态的实体,成功的应答是200(OK),如果操作仍未制定,则应答为202(接收),如果操作已制定但应答不包括实体,则应答为204(无内容).

如果请求经过缓存和请求URI识别一个或多个当前缓存的实体,这些实体将被抛弃.这个方法的应答是不可缓存的.

如果请求经过缓存和请求URI识别一个或多个当前缓存的实体,这些实体将被抛弃.这个方法的应答是不可缓存的.

如果请求经过高速缓冲存储器和请求URI标识一个或多个当前缓存的实体,这些实体将被抛弃.这个方法的应答是不可缓存的.

9.8 TRACE(跟踪)

TRACE方法用于调用远程的,应用层循环请求消息.请求最终的接收者应当反射从客户机作为200应答的实体正文收到的信息.最终的接收者也是原服务器或在请求中收到最大转发数量值第一个代理服务器或网关 (看14.31节).TRACE请求不包括实体.

TRACE允许客户端了解在请求的另一端收到的内容和用数据测试或诊断信息.经由报头域的值尤其重要,因为它表示请求过程的路径.最大转发数域的使用允许客户端限制请求链的长度,这对在无限循环中找出前向路径的代理服务器是很有用的.

如果请求有效,在实体正文中应答包括整个请求信息,具有"消息/http"的 内容-形式.这种方法的应答禁止缓存.

9.9 CONNECT(连接)
本说明中保留CONNECT方法用于能动态建立起隧道的代理服务器(例SSL 隧道[44]).

 

10.状态代码定义

   每一段状态代码在下面被描述,包括他所能遵循的方法的描述和在应答中所必需的维护信息.

10.1 信息 1xx

状态代码的类简单描述了一个临时的回答,只是由状态行和可选择的报头所组成,并且由空行所决定,状态代码类没有所需的报头.自从HTTP/1.0没有定义任何1xx状态代码,在实验的条件下服务器严禁发送一个1xx应答给HTTP/1.0客户.
客户必须准备在接受通常应答之前接受一个或者多个1xx应答,甚至客户并不期待一个100状态的报文。不被期待出现的1xx状态应答也许会被用户端的代理所忽略。
   
代理服务器必须转寄1xx应答,除非代理服务器和客户之间的联系被切断,或者除非代理服务器本身请求1xx应答的发生。(举例说明如果一个代理服务器在它转寄一个请求时会加上一个"期望:100-----继续区域",它接下来就不需要转寄100回答应答).

10.1.1   100 继续

  客户应该和他自己的请求继续。中间的应答被用于告知客户请求的初始部分已经收到并且还没有被服务器所拒绝。客户应该继续发送剩下的请求,或者如果请求早已完成,那就忽略请求。服务器必须发送一个初始回答应答当请求完成时。如果想知道这部分状态代码用法及操作处理的详细讨论,那么请看8.2.3章节。

10.1.2 101转换协议

    服务器了解并且愿意顺从客户的请求,经过升级的报文报头区域,为的就是一个应用协议的变化使之能够在连接中使用。服务器会转换协议使之成为那些通过应答升级报头的区域定义的立即在决定101应答的空行之后的协议。

    协议应该仅仅在这样做有利的时候实行转换。比如,转换成为一个新版本的HTTP协议与老版本相比更加有利,转换成为一个实时同步的协议也许会有利,当被传送的资源需要利用这样的特征

10.2 成功 2xx

这种状态代码类简要的说明了客户的请求被成功的接收,理解,和接受

10.2.1 200 OK

     请求已经成功。连同应答一起返回的信息是依赖于在请求中使用方法的。例如:

GET                    与被请求的资源相应的实体在应答中一起发送。
HEAD          与被请求资源相对应的没有报文正文的报头区域在应答中发送。
POST           描述或者包含行动结果的实体。
TRACE          底端服务器已经接收的包含请求报文的实体

10.2.2  201 创建

请求已经完成同时导致新的资源被创造.新创造的资源和地址报头区域给出资源的最专业的URI可以被随应答实体返回的URI参考.应答应该包含用户或者用户代理可以从中选择出的一系列最最合适资源的特征和地址.实体的格式通过在内容形式报头区域给出的媒体形式来详细说明.最初的服务器必须在返回201 状态代码以前创造资源.如果行动不能马上执行,服务器应该以202接受应答来应答它.

一个201应答可以由一个为了刚刚创造出的请求变量而显示出来的当前实体标记符的值的Etag应答报头区域,参见14.19节。.

10.2.3 202 接受.

为了处理,请求被接受,但是处理并没有完成.请求最终有可能或者不可能遵照行事,因为在处理过程实际发生时,它有可能被不允许.没有什么设备可以从如此的异步操作中重新发送状态代码

202应答是故意无委托的.它的目的就在于为了其他一些过程,在没有要求用户代理直到过程执行结束还坚持连接到服务器的情况下,允许服务器接受请求 (也许是一批有所指向的一天只处理一次).实体和应答返回应该包括当前的请求状态,和或者一个指向状态监听器的指针或者关于什么时间用户期待请求完成的估计.

.
10.2.4 203  非权威信息
在实体报头中返回的维护信息并不是原服务器可用的最终的设置,但是他们是从一个本地的或是第三方的拷贝.提出的设置也许是原始版本的子集或是父集.举例来说,包括有关于也许导致被原服务器识别的维护信息的父集的本地注解信息.这种应答代码的用法并不必需,而且只有当应答为200时才适用.


10.2.5 204 没有内容

服务器完成请求并不需要返回实体的正文,并且也许想返回升级过的维护信息.应答也许包含新的或者是升级过的的实体报头形式的维护信息,如果这些当前的可以与请求的变量相关联.

如果客户是个用户代理,她就不应该改变它的文件观点以区别于那个导致请求被发送的文件观点.这样的应答主要是故意允许为了行动的输入发生在没有导致对用户代理主动的文件观点改变的情况下,尽管任何新的或者是升了级的维护信息应该是适应于用户代理现在的主动观点的.

204应答严禁包含报文正文,并且这样总是由在报头区域之后的第一个空行决定的.

10.2.6 205 重置内容
 
服务器已经完成了请求,用户代理应该重新设置导致请求被发送的文件观点.这种应答主要是故意允许输入行动通过用户输入发生,伴随而来的是对给出形式的清理为了让用户可以轻松开始另一个输入行动.应答严禁包含任何实体.

10.2.7 206  局部内容

   服务器对于资源已经完成了部分GET请求.请求必须包含一个范围报头区域(14.35节),
   指出了想要的范围,而且也有可能包含一个使请求条件化如果-范围报头区域

   应答必须包含以下的报头区域:

或者是一个内容范围报头区域指出包含此现应答的范围,或者是对每个部分来说一个多部分的/字节范围的内容形式都包含内容范围报头.如果内容长度报头区域在当前应答中,那么它的值必须和实际在报文正文重传送的OCTET相匹配.

     -日期
     -Etag或者内容位置,如果能够在一个200应答中对于同一个请求发送报头.
     -终止,缓存控制,和/或者变化,如果区域值与对于同一个变量以前发送的应答中的区域值不一样.
 
如果206应答是一个使用强缓存确认的的如果范围请求的结果,那么应答不应该包含其他实体报头. 如果应答是一个使用弱缓存确认的的如果范围请求的结果,那么应答严禁包含其他实体报头,这么做是为了防止缓存实体正文和升级报头之间的矛盾性.否则,应答必须包含所有对同一个请求返回的200应答中的实体报头.

如果Etag或者上次更改的报头不严格匹配,缓存严禁将一个206请求与其他以前缓存的内容连接起来

一个并不支持范围和内容范围的缓存严禁缓存206(部分)应答.

10.3 重新定向 3xx.

这种状态代码类指出了为了完成请求用户代理而所需要做的更进一步的行动.必需的行动          可以被没有与用户发生交互作用的用户代理执行并且在当且仅当在第二个请求中所需的方法是GET 或者是HEAD.客户应该侦察最终的重新定向环路,因为对于每一个重新定向来说这样的环路产生网络交通.

注解:老版本的规范推荐最大数量为5的重新定向.内容开发者应该知道也许有贯彻这样复杂限制的客户.

10.3.1 300 多样选择.
  
被请求的资源符合任何一套表示法之一,每种资源和她自己的特定地址,并且为了使用户可以选择一个首选的表示法和依照那个地址重新定向, 代理驱动的协商信息可以被提供出来.
除非它是一个HEAD请求,应答都应该有包含一系列用户或者用户代理可以从中选择的最最合适的资源特性和地址.实体格式被在内容形式报头区域给出的煤体形式详细说明.依靠用户代理的格式和容量,最最合适的那个选择有可能自动完成.不管怎样,这种规范并没有定义自动选择的标准.如果服务器有了一个陈述的首选, 那么它应该包含为了关于那个陈述的特定的URI;用户代理为了自动重新定向可以使用地址区域值.除非指出另外的那么应答就可以缓存.

10.3.2 301 永久移动

被请求的资源已经分配了一个新的永久的URI,任何对资源的未来参考应该使用返回的URI中的一个.有编辑连接能力的客户应该对于被请求的URI从可能的服务器中返回的一个或者多个参考中实现自动连接参考.这种应答是可以缓存的除非它指出其他的.

新的永久的URI应该在应答中的地址区域给出.除非请求方法是HEAD,应答的实体应该包括一个段指向新的URI的超文本文本注解

如果301状态编码在对应于HEAD或者GEI方法中收到,用户代理严禁自动的重新定向请求除非它可以被用户确认,因为这样可能会改变请求发生的条件.

注解:当在接受到一个301状态编码后自动重新定向某一邮政请求,一些现存的HTTP/1.0用户代理将错误的将它改成GET方法.

10.3.3 302 创立

被请求的资源已经分配了一个新的永久的URI,任何对资源的未来参考应该使用返回的URI中的一个.有编辑连接能力的客户应该对于被请求的URI从可能的服务器中返回的一个或者多个参考中实现自动连接参考.这种应答是可以缓存的除非它指出其他的.

对临时的URI应该给予地址区域.除非请求的方法是HEAD,相应的实体应该包含一个短的指向一个新的URI的超级连接的超文本提示

如果302状态代码在一个应答非GEI或者HEAD请求中的过程中被接收到,那么用户代理严禁自动重新定位除非它可以被用户证实,因为它可能变化它的请求实现的条件.

注解: RFC 1945 和 RFC 2068 详细说明了客户不被允许改变在重新定位请求使用的方法.但是大多数存在的用户代理将302视为一个303应答, 不管最初的请求方法而在位置区域值实现一个GET方法.状态代码303和307被加在服务器上以希望它能够清楚客户所期待的那种反作用.

10.3.4 303 观察别的部分

对请求的应答可以在不同的URI中找到,并且应答应该在对资源的GET方法中重新得到.这种方法存在主要是为了允许邮政活性的输出脚本重新定向用户代理于一个选择的资源.新的URI不是一个最初请求资源的替代参考.303应答严禁缓存,但是对于第二个请求(重新定向)可以缓存.

不同的URI应该在相应的位置区域给出除非请求的方法是HEAD,相应的实体应该包含一个短的指向一个新的URI的超级连接的超文本提示.

注解: 许多HTTP/1.1以前的用户不理解303状态.当客户之间的协同工作能力被关注时,302状态代码也许会作为替代而使用,因为大多数用户代理就向这里描述的303那样反作用于302应答.

10.3.5 304 只读

如果客户提出一个条件的GET请求并且访问也已经允许,但是文档并没有修改,服务器应该应答这些状态编码.304应答严禁包含报文正文,并且总是由报头区域之后的第一个空行决定的.

应答必须包括以下报头区域:
-日期,除非数据亢长是14.18.1部分必须的.

如果一个无时钟原服务器遵守这些规则,并且代理服务器和客户将自己的日期加入任何成标准的应答中去,缓存会工作正常.

-Etag或者内容位置,如果能够在一个200应答中对于同一个请求发送报头.

-终止,缓存控制,和/或者变化,如果区域值与对于同一个变量以前发送的应答中的区域     
   值不一样.

如果条件化的GET使用了强的缓存??(请参阅13.3.3部分内容),那么应答中就不应该有其他实体报头.否则,应答中严禁包含其他实体报头,这样子保护了缓存实体正文和升级报头之间的矛盾性

如果304应答指出了当前尚未缓存的实体,那么缓存就必须忽视应答并且无条件的重复请求

如果缓存使用成为标准的204应答取胜疾缓存的入口,缓存就必须升级自己的入口以反映在应答中给出的任何新的区域值.

10.3.6 305 使用代理服务器

地址区域的被请求的资源必须通过代理服务器.地址区域给除了代理服务器的URI. 期望容纳者通过代理服务器重复这一单一请求.305应答必须由原服务器产生.

注解: RFC2068并不清晰于305有意于重新定向一个单一请求,并且此请求还只能由原服务器产生.不留心这些限制会产生相当严重的安全后果.

10.3.7 306(没有用的)

306状态编码在以前的规范中使用,现在已经不再用了,代码也保留了下来.

10.3.8 307临时重发.

  请求的资源临时存在在另一个不同的URI下.由于重新定位有时可能变化,客户应该继续使用请求URI以备将来用途.这个应答只有当被缓存控制或是终止报头区域指出时才是可以存储的.

临时的URI应该在应答中的地址区域给出.除非请求的方法是HEAD,应答的实体应该包括一个短的指向一个新的URI的超文本提示, 许多HTTP/1.1以前的用户不理解307状态.因此,提示应该包括用户在新的URI中为了重复原始请求所必需的信息.

如果307状态代码作为应答不仅仅是GET或者HEAD等方法而接收,那么用户严禁重新定向请求除非它可以被用户确认,这也是可能的.


10.4 客户错误 4xx

状态代码4xx类是专门使用在客户看上去错误的情形下的.除非当应答一个HEAD请求时,服务器因该有一个包括错误情形的解释的实体,以及它是否一个临时或者终了的条件.这些状态编码可以应用于任何请求方法.用户代理应该向用户显示任何包括的实体.

如果客户在发送数据,使用TCP的服务器的实现应该小心以保证在服务器关掉了所有的输入连接时客户承认收到包含应答的包.在关掉之后如果客户继续发送数据给服务器,服务器TCP堆会发送一个重制包,也许这样子会在服务器开始被访问以及HTTP应用程序被解释的情况下,会擦掉客户不知道的输入缓冲.

10.4.1 400 坏请求

请求由于畸形的语法而不被服务器所理解.客户不应该重复自己的请求在没有改变的情况下.

10.4.2 401 未授权的

请求需要用户的鉴定.应答必需有用于对被请求资源的挑战的包含WWW鉴定报头区域.如有合适的认证报头区域,客户可以重复请求.如果请求已经包含了认证的信任书,那么401应答就指出了认证由于这些信任书而被拒绝.如果401应答包括和上一个应答同样的挑战并且用户代理已经尝试认证了至少一次,那么应该给用户在应答中给出的实体,因为实体中可能包含相应的诊断信息.HTTP访问认证在"HTTP Authentication: Basic and Digest Access Authentication" 中有所解释.

10.4.3 402 必需的支付
 
这种代码被保存下来以便将来使用.


10.4.4 403 禁用

服务器理解了请求,但是拒绝实现它.认证不会帮助,请求也不应该重复.如果请求的方法不是HEAD并且服务器愿意将请求为什么没有实现告诉大家,它应该在实体中描述拒绝的理由.如果服务器并不想将这条信息告诉客户,状态代码404(没找到)可以替代使用之.


10.4.5 404 没有找到

服务器并没有找到任何可以匹配请求URI.条件是永久的还是暂时的也没有任何的迹象.410状态编码应该在服务器知道老的资源是永远不可以得到的并且没有以前的地址的情况下,通过一些内在的可配置的机构,才应该使用.这种状态编码当服务器不想精确展示为什么请求被拒绝或者何时没有其他的应答可以利用的时候被广泛的应用.

 

10.4.6 405 不被允许的方法

在请求行中特殊指定的方法不允许访问由请求URI指定的资源.应答必需有一个包括一些对于被请求的资源有效的方法的允许报头.


10.4.7 406 不接受

请求指定的资源只可能产生依照在发送请求中的接受报头有不接受的内容特性的应答实体.

除非它是一个HEAD请求,应答应该有包括一系列可兹利用的实体特性和位置,从中用户和用户代理可以找出最最适合的.实体的格式由在内同形式报头区域给出的媒体形式所指定.依靠此格式和用户代理的性能,最佳的选择可能自动的完成.然而,这中规范并没有定义任何针对此自动选择的标准

注解: HTTP/1.1服务器允许返回依照在请求中发送的接受报头不被接受的应答.在某些情况下,发送一个406应答甚至更加有利.用户代理被鼓励去检查输入应答的报头以判断是否可以接受.

如果应答不被接受,那么用户代理应该暂时停止接收更多数据并且向用户查询是否需要更进一步的行动决定.


10.4.8 407 代理服务器认证所必需

这种代码很相近于401,但是它指出了客户必须和代理服务器之间认证自己.代理服务器必需返回一个代理服务器----认证报头区域,该区域包括是为了被请求的资源而用于代理服务器的挑战.客户可能随着一个合适的代理服务器认证报头区域一起重复它的请求.  HTTP访问认证在" HTTP Authentication: Basic and Digest Access Authentication"中有解释.


10.4.9 408 请求超时

在服务器准备等待的时间段内,客户并没有产生请求.客户也许会在以后的任意一时间内重复请求.

10.4.10 409 冲突

由于与资源的现在状态的冲突请求游客能不能完成.代码只有在用户被期待有可能解决冲突和提交请求的地方的情况下允许使用.应答体应该包括对于用户认识冲突来源的足够多的信息.理想的,应答体应该有对于用户和用户代理可以解决问题的足够多的信息量.然而,这也许是不可能的或者是不必需的.

冲突通常会发生在应答PUT请求的时候.例如,版本正在被使用而且正在PUT的实体有和以前请求(第三方)冲突的资源的变更的话,服务器会使用409应答来指出它不能完成请求.在这种情形下,应答实体可能会包括一系列在内容形式应答中定义的两种版本的区别之处.
10.4.11 410 停止
服务器上的被请求的资源不再可用,而且不知道以前的地址.我们期望此条件被认为是永远的.有连接编辑能力的客户在用户同意的情况下,应该删掉对请求URI的参考.如果服务器并不知道,或者没有设备去决定是否条件是永久的,状态代码404(未找到)此时应该使用.这种应答是不可被缓存的除非另外指出.

410应答主要是通过通告请求者资源有意不可获得和服务器主人希望那些远方连接到资源的连接都被请除掉这两条信息用于援助WEB维护.这样的事情很普通发生在时间受限,增加的服务和不再服务器端工作的的属于私人性质的资源这些情况下.我们并不需要标注所有的永久不可用的资源"没了"或是标注上任意一段长度的时间-----这些交给那些服务器的主人自己去判断吧.


10.4.12 411 必需的长度

服务器拒绝接受没有定义的内容长度的请求. 如果加上了一个有效的"包含有请求报文正文中的长度"的内容长度报头区域,那么客户可能重复请求.


10.4.13 412 预处理失败

在一个或者多个请求中给出的预处理在被服务器验证的时候会被评价为错误的.这种应答代码允许客户将预处理放在当前资源维护信息(报头区域数据),并且这样作以防止有其他的适应资源请求的法的而非所要的那一个.


10.4.14 413 请求实体太大

服务器拒绝处理一个请求因为请求比服务器所能和所愿处理的还要大.服务器可能关掉连接以防止客户继续请求.

如果条件是暂时的,服务器应该有一个重新试-在之后报头区域以便于指出这是暂时的在什么时间以后客户可以再试一次.
10.4.15 414 请求的URI过长

服务器拒绝请求的服务因为请求的URI比服务器所愿意解释的要长.这种比较珍稀的条件之可能发生在党课互补恰当的将POST请求变为有长查询信息的 GET请求的情况下,或是客户落到了一个重新定向的URI黑洞中时,再或者是在一些使用固定长度缓冲区用以读或者处理请求的URI的服务器遭到钻安全漏洞的黑客的攻击的时候.


10.4.16 415 不被支持的媒体类型

服务器拒绝提供服务给请求因为请求的实体所请求的方法是在一种不被请求资源支持的格式下.

10.4.17 416 请求范围不满足

如果请求包括范围请求报头区域,或者是在区域内没有范围说明符的值溢出当前选择资源的延伸,再或者是请求没有包含如果--范围请求--报头区域,服务器应该返回连同状态代码的一个应答.(对于字节-范围,它意味着所有的字节范围说明中的第一字节???的值比当前选择资源的长度要大)

当状态代码返回一个字节范围请求时,应答应该包含一个详细说明选择资源的长度的内容范围区域.(请参阅14.16).应答严禁使用多部分/字节范围的内容形式.

10.4.18 417 期望失败

在请求报头区域给出的预料不可能被服务器实现,或者,如果服务器是代理服务器,服务器有请求不可能被下一个??服务器实现的模糊的证据


10.5 服务器错误 5xx

应答状态代码用阿拉伯数字"5"表示服务器知道它自己有错误或者自己不能实现请求等这些情况.除了当应答一个HEAD请求,服务器应该有一个包括错误形式的解释的实体和它是否暂时或者永久的条件的解释的实体.用户代理应该显示任何包括的实体给用户.这些应答代码对于任何请求的方法都是适用的.


10.5.1 500 服务器内部错误

服务器遇到预料到的防止它完成请求的情况.


10.5.2 501 不能实现

服务器不支持完成请求所必需的功能性. 当服务器并不认识请求的方法并且没有能力对于任何资源支持时,这是合适的应答


10.5.3 502 坏网关

服务器,当被用作一个网关或者是代理服务器时,就会从上流的服务器收到无效的应答以试图完成请求的访问.


10.5.4 503 难以获得的服务.

由于暂时的过载或者服务器维护,服务器此时不能处置请求.这说明了这是一个暂时的条件过一些耽搁会减轻.如果知道,耽搁的长度应会在重新试-在之后报头中指出.如果没有重新试-在之后给出,客户应该处理处置应答就像处理一个500应答一样。

注解:503状态代码的存在并不暗示着服务器必需使用它当它变得过载时。有些服务器只想简单的拒绝连接。

10.5.5 504 网关超时

服务器,当被用作是网关或者是代理服务器时, 由于URI指定的上游服务器或者其他一些辅助服务器以有资格尝试完成请求,并没有收到及时的应答.

注解:设备注解:一些展开的代理服务器都知道返回400或者500当DNS查找时间过长时.

10.5.6 505 HTTP版本不支持

服务器并不支持,或者拒绝支持,在请求信息中用到了HTTP协议版本.服务器指出它不能或是不愿完成使用与客户端一样的版本的请求,就像在章节3.1中描述的那样,???????.应答应该包含描述为什么那个版本不为支持而为什么其他协议被服务器支持的实体..


11.入口验证

HTTP提供了一些可以选择的用于服务器挑战用户请求和用户提供验证信息的的挑战-应答验证机制.入口验证的大体框架,和基础及分类验证的规范在" HTTP 规范:"基础及分类入口验证"中详细说明.这份说明从规范中采用了"挑战"和"外交国书"的定义


12.内容谈判

大多数HTTP应答都有一个包括人类用户解释信息的实体.自然地,相对于请求它需要提供给用户"最佳利用"的实体.很不幸的是,对于服务器和存储器来说,不是所有的用户都有同样的关于"什么是最好的"的判断准则,并且并不是所有的用户代理有相同的解释实体形式的能力.为此,HTTP为了"内容谈判" 提供了一些机制-----当有很多种可能的表示时如何选择对于一个请求的最佳的表示.

注解: 这不是所谓的"格式谈判,因为变化的表现也许是相同的媒体形式,但是使用那种型号的不同性能的,还也许是使用了不同的语言.
任何包含一个实体正文的的应答都有可能受配于谈判,甚至包括那些错误的应答.

在HTTP中有两种可能的内容谈判:服务器驱动的和代理驱动的谈判.这两种谈判是相互正交的,这样他们可以单独或者混合使用.混合使用的一种被称为透明的谈判的方法,发生在当缓存使用由最初的为了后来的请求而提供服务器驱动谈判的服务器提供的代理驱动谈判信息时.

12.1 服务器驱动谈判

如果对于一个请求的最佳表示的选择由服务器提供的运算法则来完成,我们就叫它是服务器驱动谈判.选择是基于应答中可行的解释和在请求报文的特定报头区域的内容或是其他一些适合请求的信息(如客户的网络地址).

服务器驱动在从所有可行的表示法中挑选最佳的运算法则对于客户很难描述时是有利的,或者是当服务器要求将它的"最佳估计"和第一应答一起送给客户端时有利.为了提高服务器的估计能力,用户代理可以包含为了这样一个应答描述自己参数选择的请求报头区域.


服务器驱动谈判有这些缺点:

1. 对于任何用户来说决定什么是最佳的实际上是不可能的,因为那样需要有关于用户代理能力和应答所想要发挥的用途的所有完整的信息.
2. 让用户代理在每一个请求中描述自己的能力也是很低效的并且对于用户的隐私也是潜在的威胁.
3. 它复杂了原服务器的实现和相对于请求的运算法则.
4.它可能会限制一个公共缓存的能力,因为缓存对于不同的请求将使用同样的应答.

HTTP/1.1 包含以下通过描述用户代理的性能和用户的参数选择使服务器驱动谈判成为可能的请求报头区域: 接受(章节14.1),???(章节14.2),接受编码(14.3),接受语言(14.4),以及用户代理(14.43).然而,原服务器并不受限于这些尺寸,并且可能会基于请求的各各方面而变化不同的应答,包括在请求报头区域之外的信息或者在此规范中没有定义的扩展报头区域.

不同的报头区域可以用作表达
服务器用作选择服从服务器驱动谈判的表示法的变量.请查阅章节13.6关于缓存中不同报头区域的用法和章节14.44关于服务器不同报头区域的用法.

12.2 代理驱动谈判
在代理驱动谈判中,对于一个应答的最佳表示法的选择是在代理从原服务器端收到最初的应答后实现的.选择是基于一系列可用的应答的通过自己URI鉴定的表示法,其中包括初应答的报头区域和实体正文.从表示法中的选择可以自动实现(如果用户有能力这么做)或者人工的用户从产生的菜单(可能是超文本)中选择.

代理驱动的谈判,当应答有可能不同于普通使用的尺寸时或者是原服务器不能够从检查请求中决定用户代理的性能时,并且一般说来当公共的缓存被用作分散服务器负载和减少网络用法.

代理驱动的谈判也有需要二次请求以获得最佳替换表示法这样一个缺点.只有当缓存在使用时二次应答才有效.作为补充,规范中并没有定义支持自动选择的任何机制,虽然它也没有阻止任何机制被发展如像在HTTP/1.1中的扩展那样.

在当服务器不愿或是不能提供不同的使用服务器驱动谈判的应答时,HTTP/1.1定义了300(多种选择)和406(不接受)这两种状态编码以使代理驱动谈判成为可能.

12.3 透明的判断

透明的判断是服务器驱动和代理驱动谈判的结合体.当缓存被供给了一系列可兹利用的应答的表示法并且变量的尺寸被缓存充分理解时,缓存可以执行代表为了资源的后来请求的原服务器服务器驱动的判断.

透明的谈判有分散这样的优点, 否则是原服务器必需的谈判工作,以及当缓存可以正确估计应答时可去除用户代理二次请求的沿时.

此规范没有定义任何关于透明判断的机制,虽然它也没有像在HTTP/1.1中使用的扩展那样阻止发展机制.
13 HTTP中的缓存
    HTTP典型应用于能通过采用缓存技术而提高性能的分布式信息系统。HTTP/1.1协议包括的许多元素都尽可能的进行缓存操作。因为这些元素与协议的其他方面有着千丝万缕的联系,而且他们相互作用、影响。因此,独立于算法、报头、响应代码等的细节描述来讲述HTTP中缓存的基本设计是大有裨益的。
    如果不对缓存技术做明显改善,他将一无用处。HTTP/1.1中缓存的目的是降低在众多情况下发送请求的需要,同时降低在其他情况下发送完整响应的需要。前者使众多操作中往返流程减少,我们用"过期" 机制来达到这一目的(见13.2节);后者使网络带宽需求降低,我们用"认证"机制来达到这一目的(见13.3节)。

 
    对性能,可用性和分离操作的需要要求我们能放宽语义透明度的要求.HTTP1.1协议允许源服务器,缓存和代理客户在必要时明确降低透明度.然而,因为不透明操作会迷惑不专业的用户,而且可能同某些服务器应用不兼容(如).在下列情况下,协议需要透明度被降低:
    仅当代理或源服务器提出明确的协议层次的放宽请求.
    仅当缓存或代理向终端用户提出明确的放宽警告.

因此,HTTP1.1协议满足如下要素:
      1.当各部分都提出要求时,协议提供完全的语义透明度.
      2.协议允许源服务器或用户代理明确请求且控制不透明操作.
      3.协议允许缓存对未达到要求的语义透明度的响应发出警告.      
说明:服务器,缓存,或代理设备可能面临的设计决策不在本说明书讨论范围之内.如果有关于语义透明度的决策,此设备应尽力保持语义透明度除非有仔细而完整的分析表明破坏透明度将有重大好处.

13.1.1缓存 正确性
   在如下列情况下,一个正确的缓存必须从他所存储的内容中选出最新者来响应请求. (参见13.2.5,13.2.6,13.12节)
   
1. 经过检验,源服务器对收到响应重新确认生效返回的结果与原来相同.(参见13.3节)

2.."足够保鲜"(参见13.2节).在缺省值情况下,它表示对代理,源服务器和缓存
的最低的保鲜性要求(参见14.9节);如果源服务器详细说明,那么保鲜性要求仅是对源服务器本身而言有效.如果某一存储的响应对代理和源服务器的最低保鲜要求仍不满足,慎重考虑,缓存应返回响应并加入适当警告报头(参见13.1.5,14.46节),除非这种响应是被禁止的(参见14.9节).

3.  304(未修改),305(代理人重寄),或 错误(4xx,5xx)响应信息.

 
        如果缓存无法与源服务器通信,则当响应能正确的从缓存发出时,缓存应
如上响应;如果不能,则缓存应发出错误或警告信息以说明存在通信故障.
        如果缓存收到响应(不论是一个完整响应还是一个304响应),它会将其转寄
给请求客户,当收到的响应被刷新时,缓存应该转寄给请求客户而不须加入新的警告
信息(且无需去掉已经存在的警告报头).缓存不能仅仅因为某一响应在传送过程中
"过时"了而令响应重新生效,这将引入一个死循环.一个用户代理收到没有警告的过
时响应应对用户显示警告.  


13.1.2 警告信息
        当缓存器返回响应既不是第一手的也不是最保鲜(fresh)的,此响应必须附加警告,
使用一般警告报头.此警告报头信息和刚刚定义的警告在14.46中有详述,此警告允许
客户采取适当行动.
        警告信息可以被用作他途,不论是否与缓存有关.警告的使用,而非错误状
态代码区分了前述响应和实际错误.
        警告信息由三类阿拉伯数字代码表示.第一个数字表明当重发成功后警告信
息是否必须或必须不被删除.

   See section 14.46 for the definitions of the codes themselves.
1xx 这是描述响应刷新或重发状态的警告信息,因此在重发成后功必须被删除掉
    1xx警告信息仅当确认一个缓存实体时才由缓存器产生.它不能由代理端产生.
2xx 一个描述实体内容或报头的警告信息,它不因重新确认而被矫正,而且在成功的
     重新确认后也不能被删除.

代码定义见14.46

        HTTP1.0 缓存器存储响应中的所有警告信息,且不会删除第一类警告.
传给HTTP1.0的警告信息带有一个附加的警告数据区,它阻碍了未来的HTTP1.1兼
容错误缓存警告.
        警告信息也传送一个警告文本.此文本可以使用任何自然语言,而且可以
随意选择准用的字符.

        响应可以附加多重警告,包括属于同一类代号的警告.例如,服务器可能
提供同样的错误而文本包括英语和巴斯克语两种.
        当响应附加了多重警告信息时,把所有的信息都显示给用户是不合理的
也是不现实的.此版本的HTTP并未指定严格规定警告显示的优先权和顺序,但却
给出了一些提示.

13.1.3 缓存控制机制
在HTTP1.1协议中的基本缓存机制是隐含指示给缓存器.在某些情况下,
一服务器或代理可能需要给缓存器以明确的指示,我们用缓存器控制报头来达到
这一目的.
          缓存器控制报头允许代理或服务器传送多种指示,既可以是请求,也可
以是响应.这些指示代替缺省的缓存算法.作为一般规律,当出现明显的报头内
容冲突时,最根本的协调办法是实用性原则(即为,选择能最好保持予以透明度
的报头),可是,在某些情况下,缓存控制指示明显的削弱了语义透明度.

        缓存器控制指示详述于14.9节

13.1.4直接的用户代理警告
        很多用户代理允许用户覆盖基本缓存机制.例如,用户代理可能允许用户
指定缓存实体是无效的。或者,用户代理还可能习惯于加上缓存控制:对任何请
求最大值=3600。用户代理不应该默许非透明的行为或造成明显低效率的行为,但
可以由用户的明确行动来外在配置。
        如果用户已经覆盖了基本缓存机制,用户代理应向用户明确指出,一旦
此改变作用于信息显示,可能与透明度要求发生冲突。协议通常允许用户代理来
决定响应是否已经失效,当实际发生时,该指示需要单独显示。该指示不必是对
话框,它可以是一个图标。
        如果用户对缓存机制的覆盖使缓存器效率反常降低,用户代理应连续的
将这一状态提示给用户以防止用户无意中占用了额外资源或面临过长的延迟。

13.1.5 规则和警告的例外情况
           在某些情况下,缓存操作员会选择设置缓存当用户未提出请求时发出过时
的响应。这一决定不应草率作出,但有时为了提高性能,尤其当缓存与源服务器
不良连接时,又是必须的。一旦缓存器返回一个失效的响应,这一定标明(使用
警告报头)令代理端软件生效来警告用户,可能存在潜在的问题。

        协议还允许用户代理采取措施来获得第一手的或最新的响应。因此,
如果用户代理明确请求第一手的或最新的,缓存器不能返回过时响应,除非由于
技术上或政策上的原因而无法实现。
13.1.6 由客户控制的行为
           当源服务器是满期信息的最初来源,在某些情况下,客户将需要控制
缓存器决定是否回复缓存的响应而不使其生效。客户需要使用缓存器控制报头的
几项指示来作此工作。
 
        一个客户的请求可以指定它能接受的未确认响应的最长时限;指定一个
零点控制确认所有响应。一客户还可以指定响应期满前的最小时限。所有这些操
作增强了对缓存行为的控制,所以将不能放宽缓存器的语义透明度。
 
        一客户也可以指定它接受失效响应,直到达到最大值。这放松了对缓存
器的控制,也就可能与源服务器对语义透明度的限制发生冲突。但对不良连接
时支持分离操作和提高性能来说又是必须的。


13.2          过期(Expiration)模型
13.2.1         服务器指定模型
           当缓存器能完全避免向源服务器发送请求时,它工作于最佳状态。
避免请求的根本机制是源服务器给出一个明确的未来过期时间,这样响应信
息或许可以满足后来的请求。换句话说,缓存器不必首先联系服务器就能回复
一个最新响应。
 
        我们期望服务器能指定一个对响应的明确预期过期时间,以确保在到达期
限之前,实体没有发生变化。当过期时间仔细选择时,这通常可以保持语义透明度。
   此过期机制仅应用于缓存器作出的响应,而不针对直接传递给请求客户的
第一手响应。
 
        如果一源服务器要强制一个语义透明的缓存器来确认每一个请求,它可
以指定一个明确的已过去过期时间。这表明响应总是失时效的,因此缓存器应在用
其答复后来的请求之前确认之。(见14.9.4)      

 
        如果源服务器想强制HTTP1.1缓存器无论如何配置都确认每条请求,则应
该使用"必须再确认"缓存器控制指示.(见14.9)

        服务器指定明确的过期时间既可以使用过期报头,也可以使用最大期限(Max_age)
报头.
        过期时间不能用来强制用户代理刷新其显示或重载其资源;它只应用于缓
存机制,当一个对某资源的新请求发出时,此机制仅须检测该资源的过期状态。
(见13.13)

13.2.2         启发式过期
        由于源服务器并不总是提供明确的过期时间,HTTP缓存器典型设置为启发
式过期时间,采取使用其他报头值的算法来估计一个近似的过期时间。HTTP1.1说明
书中并未给出详细算法,但却利用最坏情况来限制其结果。由于启发式过期次数可
能影响语义透明度,故应慎重使用,而且我们鼓励源服务器提供尽可能大的过期
次数。

13.2.3 年龄(Age)计算
           为了解缓存实体是否为最新,缓存器需要知道其年龄是否已超过保鲜时
限。我们在13.2.4节中讨论如何计算后者,本节讨论如何计算响应或缓存实体的
年龄。
        在此讨论中我们用“NOW”来表示“主机进行计算时时钟的当前值”。
使用HTTP协议的主机,除了运行源服务器和缓存器的主机,应当使用NTP[28]
或其他类似协议来将其时钟同步到一个全球性的精确时间标准上来。

        HTTP1.1协议要求源服务器尽可能在发送每条响应时都附加一个日期
报头来标明此响应产生的时间.(见14.18)我们用"日期值"这一短语来表示日期报
头的值----一种适于算术操作的形式.

        当从缓存获得响应消息时,HTTP1.1用年龄响应报头来传达其年龄信息.
年龄值是缓存器估计的源服务器生成或重新确认响应的时间值.
        本质上,年龄值是响应信息在从源服务器开始的所有缓存器驻留的时间
加上其在网络路径上传输的时间.
        我们用年龄值("age_value")来标明年龄报头的值----一种适于算术操作的表示方法.
        一个人的年龄可以通过两种完全独立的途径来计算:
        1.如果本地时钟与源服务器时钟同步的相当好,则用"NOW"-日期值,若结果
为负,则取零.
        2.如果从源服务器开始的所有缓存器均执行HTTP1.1则就取年龄值(age_value).

        如上我们有两种方法计算响应的年龄,我们合并二者如下:
矫正后接收到的年龄值=MAX(NOW-DATA_VALUE,AGE_VALUE)
        而且无论那种方法都能得到可靠的结果.

        由于网络附加延时,一些重要时隙会在服务器产生响应和下一个缓存器或客
户收到它之间被忽略.如果不经修订,这一延迟会带来不正常的低年龄.      

      corrected_initial_age = corrected_received_age
                            + (now - 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;
        以上段落英文更明白一些。

        缓存实体的当前年龄是从缓存实体最后被服务器确认的时间(以秒记)
加上校正初始年龄。当缓存实体产生一条响应,它必须包含一个年龄报头区:与缓
存实体当前年龄一样的值。

        响应中存在年龄报头区意味着这不是第一手响应。但反之未必,因为那仅
当所有缓存器均使用HTTP1.1时才成立。
13.2.4         过期计算:
           为了确定一条响应是新是旧,我们需要将其保鲜期限和年龄进行比较,年龄的计算见13。2。3节,本节讲解怎样计算保鲜期限,以及一条响应是否已经被排出。在下面的讨论中,数值可以用任何适于算术操作的形式表示。
        我们用“过期数值”("expires_value")来标明过期报头,我们用“最大年龄值”来标明缓存控制报头的秒数。(question?)
 
最大年龄在过期之前指示,所以一旦响应中出现最大年龄,计算将变得非常简单。

      freshness_lifetime = max_age_value

  否则,若缓存中出现“Expires”,计算如下:
      freshness_lifetime = expires_value - date_value

        注意上述运算不受时钟误差影响,因为所有信息均来自源服务器。
   如果 Expires, 缓存控制: max-age, 或 缓存控制: s-maxage (见 14.9.3) 均未在响应中出现,且响应对缓存没有其他限制,缓存可以用启发式算法计算freshness lifetime。缓存器必须对年龄大于24小时又不带警告的响应附加113号警告。

而且,如果响应有最后修改时间,启发式过期值应不大于时间片。典型设置为片断的10%
   计算响应是否过期非常简单:

      response_is_fresh = (freshness_lifetime > current_age)

13.2.5 澄清过期值
        由于过期值不是严格制定的,所以可能两个缓存器对相同资源制定的刷新值不同。
 
        如果客户对一个在其缓存中以刷新的请求作出一个恢复的非第一手响应,而且缓存实体中的日期值比响应中的新。,则客户可以忽略此响应。如果这样,将要求“缓存控制”:max-age=0 来强迫检查源服务器。
           如果缓存器有两个描述相同而确认器不同的响应,它必须使用有最近日期报头的那个。
13.2.6 澄清多重响应
        因为客户可能收到经多重路径来的响应,所以有些响应流经一簇缓存器,而另一些响应流经另一簇缓存器,客户收到响应的顺序可能与源服务器发响应的顺序不同,我们希望客户能选用最新的响应。
        实体标签和过期值都不能影响响应顺序,晚一点的响应可能带有早的过期时间。日期值的精度也只有一秒。
        当缓存器要重新确认一个缓存实体,而且受到响应的日期报头晚于已存在的实体,则客户应无条件的重复请求。

       Cache-Control: max-age=0

强制任何中间缓存器确认它们的副本。

       Cache-Control: no-cache

或者强制它们从源服务器获取一个新的副本。
如果日期值相同,可以使用任何一个响应。

13.3        确认模式
           当缓存器想要用一个失时效的条目来相应客户的请求,他首先必须向源
服务器(如果可能则向一中间缓存器)检验这一缓存条目是否仍然可用.我们称之为
"确认"缓存条目.由于我们不想当缓存条目为可用时必须为再传送整条响应而付出
代价,而且不想当缓存条目不可用时也必须多传一圈,HTTP1.1协议支持使用条件反应方法.

          协议支持条件响应方法的关键特征围绕"缓存确认器"展开.当源服务器
生成一个完整响应时,它同时传送一类确认器一直伴随着缓存条目.当一客户(用户
代理或代理缓存器)对含有缓存条目的资源做出条件请求时,他同时在请求中包含有相互关联的确认器.

          服务器则核对此确认器和当前确认器,如果他们匹配(见13.3.3),则返回
一个特定状态码(通常为304)且不含条目内容.否则,返回整个响应(包含条目内容)
这样,我们避免了在确认器匹配时传送整条响应,同时也避免了在不匹配时往返传输.

        在HTTP1.1协议中,一个条件请求除了带有特别的报头(包含确认器)来暗中
的将它转入条件算法以外,和普通报头没有差别.

        协议中包括缓存确认机制的主动和被动两种状态.具体说来,请求可以在
当且仅当又匹配确认时执行,也可以在当且仅当没有匹配确认时执行.

        说明:没有确认器的响应也可以缓冲存储且接受服务直至被排出,除非这是
被缓存控制指令明确禁止的.可是,如果没有确认器,则缓存不能有条件的恢复它,这表明无法刷新除非被排出.
      
13.3.1 最后修改日期        (Last-Modified Dates)
        最后修改报头值经常被用作确认器.简言之,一缓存条目在最后修改期后
未经修改则被认为是有效的.
13.3.2         标签缓存确认器(Entity Tag Cache Validators)
           标签响应报头值,一个实体标签,提供了一个"模糊"缓存确认器.这将允许
在不便存储修改信息的情况下进行可靠的确认,包括HTTP日期数据不充足和源服
务器不想因使用修改日期而带来麻烦的情况.
          实体标签描述见3.11节,有关其报头的描述见14.19,14.24,14.26,14.44.
13.3.3         强,弱确认器
        由于源服务器和缓存器会比较两个确认器来确定他们是否代表相同的条目,所以通常希望实体发生任何变化,确认器也相应变化,这样的确认器为强确认器.
        同时还会有这样的情况,服务器倾向于仅在发生重要的语义变化时才改变确认器.在资源变化时确认器未必变化的称为弱确认器.
实体标签通常是强确认,但协议提供一种机制来标志弱 Copyright  (2007).          All Rights Reserved.
确认.可以认为,强确认在实体的每一字节变化时均变化,而弱确认仅在实体含义变化时才变化,强确认是某一特定实体的标志,而弱确认是某一类同义实体的标志.
注: 强确认的例子:一个整数,他随着每次实体发生变化而定值增长.
        一个实体的修改时间(以秒计算)可以作为弱确认器,因为实体可能在一秒内变化两次.
        对弱确认的支持是可选的.支持弱确认可带来等价体的高效缓存.
        当客户生成一个在确认报头中包含确认器的请求或服务器进行比较时均要用到确认器.
        强确认可在任何情况下使用,而弱确认仅在不依赖严格相等时才可用.
        客户可以发出简单GET请求,伴随强,弱确认器均可.客户在发其他请求时,不能用弱确认.
HTTP1.1协议定义确认的唯一功能是比较.有两种比较功能,这依赖于是否允许弱确认.
        -- 为了同等考虑,两确认器必须完全一样且均非弱确认.
        -- 两确认器必须完全相同,且至少有一个被标明为"弱".

        除非被明确标清,实体标签是强的.
        最后修改时间被用作请求的确认器时默认为弱的,除非从下列规则导出强的结论.
        确认器不会在一秒内变化两次.
或者
    
      -确认器可能被用户用于If-Modified-Since 或者 If-Unmodified-Since报头。
      -此缓存实体包含一日期值,他给出源服务器发出响应的时间。
      -最后修改时间至少比日期值早六十秒。
或者
      -确认器已经被中间缓存器同缓存实体比较过
      -此缓存实体包含日期值,给出源服务器发出响应的时间。
      -最后修改时间至少比日期值早六十秒。

        此种方法基于以下事实:如果两条响应在同一秒内被发出但有相同的最后修改时间,则至少有一条响应日期值和最后修改时间是相同的.
        如果客户在仅有最后修改时间没有模糊确认器的情况下执行子范围修复,
则仅当最后修改时间是强确认时才可以.
        若缓存器或源服务器收到一个条件请求,而不是完整GET响应,则必须使用强比较函数.
          此规定允许HTTP1.1协议下,缓存器和客户可以对从HTTP1.0中得到的值安全的进行子域恢复.

13.3.4         关于何时使用实体标签和最后修改时间的规则
           我们对源服务器,客户和缓存器采用一套规则和建议来规定在何时,出
于何种目的,应采用何种确认器。
   HTTP/1.1 源服务器:
        -应该发送一实体标签除非它做不到。
        -可以发送弱实体标签如果其满足性能要求或不能发送强确认。
        换句话说,对http1.1服务器来说,比较好的做法是同时发送强实体标签和最后修改值.
        说明:为保证语义透明缓存,服务器必须避免两个不同实体重复利用同一
强实体标签值或者两类不同语义的实体重复使用同一弱实体标签值.
   HTTP/1.1 客户:
        -若服务器用实体标签,则必须对任何缓存条件请求都使用此实体标签.
        -仅当服务器提供最后修改值时,它应该在非子域条件请求中使用该值.
        -仅当HTTP1.0服务器提供了最后修改值时,他可以在子域缓存条件请求
        中使用该值.
        -若两者均被提供,则两者均应使用.

        当一服务器收到的请求既包括最后修改时间也包括一个或多个实体标签,
则它一定不能发出304代码,除非这是协调好的.
        当一个HTTP1.1缓存代理收到上述请求时,一定不能返回一个本地缓存响
应给客户,除非它对所有请求都是一致的.
        说明:一般规律是传送尽量多的非冗余信息.
        HTTP1.0客户和缓存器忽略实体标签.
13.3.5 不确认条件
           其他报头的比较不被用于确认缓存实体.
13.4 缓存能力响应
             除非被明确限制,缓存系统可以将一成功的响应作为缓存实体一直存储,如果它是保鲜的可以不确认而返回它,如果成功确认,也可以返回它.

        说明:某些HTTP1.0缓存器可能违反这一条而不提示警告.
        还有,某些情况下可能不便保留一实体,或将其返回给后续请求.
   注意14.8节防止共享缓存存储和回复一个早先的包含授权报头的请求.      
          包含状态码200,203,206,300,301或410的响应可能会被用于回复后面的响应.
        带有其他一些状态码的响应不能用于回复后面的请求,除非有明确的缓存控制
或其他报头允许之.

13.5 从缓存器构造响应
           缓存器的目的是存储响应请求的信息来响应后面的请求.再很多情况下,缓
存器仅返回响应的适当部分给请求者.如果缓存器保有一个基于前面请求的实体,它
可能必须将其与新响应合并.

13.5.1 端到端和Hop-by-hop报头
        为定义缓存器行为,我们将报头分成两类:
        端到端报头和hop_by_hop报头(仅对简单的传输层连接有意义,不被缓存,
                                    也不被代理服务器向前传递)
            
    hop-by-hop 报头:

      - Connection                   连接
      - Keep-Alive                保活      
      - Proxy-Authenticate        代理人鉴别
      - Proxy-Authorization        代理人授权
      - TE
      - Trailers                轨迹
      - Transfer-Encoding        传输编码
      - Upgrade                        升级

所有其他均为端到端报头
13.5.2         不可更改报头
           HTTP1.1的某些特征,如分类鉴定,基于某一端到端报头值.一透明代理不能
修改端到端报头除非报头要求或明确许可.
 
传输代理不能修改下列各项,如果他们不存在,也不能添加。
      - Contents location
         目录区
      - Content-MD5
      
      - ETag

      - Last-Modified
        最后修改时间

              - Expires

        但它可以添加这些区域.如果排除报头被添加,则必须赋值来标明次响应的
日期报头.
     
        包括不变形缓存控制指示或有请求.
      - Content-Encoding
        内容编码
      - Content-Range
        内容区
      - Content-Type
        内容类型
        警告:对端到端报头的不必要修改可能导致在今后高版本协议引入更强的鉴
定机制后鉴定失败
        内容长度区的去留规则见4.4节.
13.5.3         联合报头(Combining Headers)
        但缓存向服务器发出确认请求,若服务器回复304或206响应,则缓存器构
造响应回复给请求客户.      
        若状态码为304,则缓存器使用缓存实体的报文构造响应,若状态码为206
且标签和最后修改时间恰好匹配,则缓存器可以将存储的和刚收到的实体和并作为
新响应的报文(见 13.5.4).

缓存实体中的端到端报头用于构造响应,排除以下内容:
        -1xx警告报头被删除
        -2xx保留
        -304或206响应中的报头代替缓存实体中的相应部分。
除非要删除缓存实体,缓存器必须用收到的响应报头取代端到端报头。换句话说,
接收到的端到端报头覆盖缓存实体中已有的端到端报头。
    
注意:此规则允许源服务器用304或206响应来刷新缓存器中的相应实体。


13.5.4 联合字节范围
        一条响应可能仅传送一条正文的一部分,经过几次这种传送,一缓存器可能会
收到同一条正文的好几部分。
 
        如果缓存器已经收到正文的一部分,且又收到了另一部分,缓存器可以
将新收到的内容与已有内容合并,当所有收到的响应及缓存实体含有强确认时。

13.6 缓存谈判响应
     使用服务器驱动内容转让(见12.1),由响应中的变化报头区说明, 改变了缓存器能用响应回复后续请求的条件和过程.(服务器使用变化报头区见14.44)    
 
     服务器要用变化报头区告知缓存器在众多可缓存响应类型用什么样的请求
报头区来用服务器驱动转让.变化区命名此类报头区为"选择"请求报头.
 
        当缓存器收到指定一个或 Copyright  (2007).          All Rights Reserved.
更多包含变化报头区的缓存实体的后续请求,缓存器不能用这样的缓存实体来构造新请求的响应,除非新请求中所有选中的请求报头与初始请求相应部分匹配. 
 
        当且仅当两个请求中的选择请求报头可以从前一请求变形为后一请求时称为匹配.变形指,在相应的BNF允许的位置增加或删除LWS,或者按照4.2节中的消息报头规则合并合并同名的多个消息报头区.

 
        一个变化报头区数值"*"一般不能匹配而且对该资源的后续请求,服务器只能粗略解释.
 
        如果旧的请求报头不能匹配新的,缓存器不能用相应缓存实体来回复响应
除非它第一个将请求发给服务器且服务器回复304,包括实体标签或内容地址说明
实体可用.
 
        如果一实体标签用于标志缓存的代表,向前传递的请求应该是条件的且包
括实体标签.这给服务器揭示了缓存器刚刚缓存的所有实体,所以如果其中任何实体与请求实体匹配,服务器可以用304响应中的ETag报头区来稿置缓存实体可达.如果新请求中的实体标签与已存在实体匹配,则新响应应该用于刷新存在实体的报头区, 并将结果返回给客户.
 
        如果任何已存在缓存实体仅包括相关实体的部分内容,它的实体标签不能
包含于If-None-Match报头区中, 除非此请求是对一个被该实体完全满足的区域.
 
        如果缓存器收到一个成功响应,已存在实体不能回复将来的响应且应该被删除.
 
13.7 共享和非共享缓存

        出于安全和保密考虑,有必要区分共享和非共享缓存。非共享缓存是仅
供一个用户使用的缓存器,此种情况下,可用性由适当的安全机制控制。其它缓
存器均被认为是共享缓存。此协议的其它部分给出了其它的一些限制以防止隐私
的丢失和可达控制的失败。

13.8 错误和不完全响应缓存行为

        缓存器收到不完整响应时也可以存储它,但是必须把它看作部分响应。
部分相应可以合并(见13.5.4);合并结果可能是完整的或仍是部分的.缓存器
不能把部分相应回复给客户,除非有明确要求.
        如果缓存器在试图重新确认一实体时收到5xx响应,它既可以将其传送给
客户也可以认为服务器响应失败。后一种情况,它可以回复一个以前接收到的响应
除非缓存实体明确要求“必须确认”

13.9  GET 和 HEAD 的副作用:

        除非服务器明确禁止缓存它们的响应,对任何资源应用GET和HEAD算法,
如果响应曲子缓存器,都不会引起能导致错误的副作用。他们确实有副作用,但
缓存器在决定缓存时不必考虑。缓存器总是“看源服务器的脸色行事”。
 
一个例外:有些应用习惯于在query URLs时使用GET和HEAD,从而带来显著的副作用,
缓存器不能认为对他们的响应是刷新的,除非服务器明确给出过期时间。这说明不能
从缓存器取出HTTP1.0服务器对URIs的响应。

13.10 刷新或删除后的无效性
        某些算法对源服务器资源的操作将使一个或多个已存在的缓存实体不可
用,即为,虽然他们还是“新鲜”的,但却不能准确反映源服务器想回复给请求
的信息。

        HTTP协议无法保证所有此类实体均被标明无效。例如,引起源服务器变
化的请求可能没到达存贮缓存实体的代理服务器,但是,有一些规则帮助减少类
似的错误。

 
        本节中,“使一个实体失效”表示缓存器或者删除该实体的所有instances,或者标明其为不可用,而且在重新用于回复后面的响应前必须有重新确认命令。

        某些HTTP算法必将导致缓存器使一个实体失效。这是实体被URI请求或内
容区域报头提到。这些算法是:

      - PUT
      - DELETE
      - POST

        为了防止服务器拒绝处理,基于URI或内容区域报头的失效处理仅当主机
部分与URI请求相同时才进行。

          缓存器向它不理解的算法传递请求时令所有被URI请求指明的实体失效。

13.11 强制写通过( Write-Through)
        所有可能对源服务器资源进行修改的算法都要写给源服务器。这通常包括
所有算法除了GET和HEAD。缓存在将此种请求转给内地服务器并获得相应答复前不
能对请求客户做出响应。

        相反情况(write-back)在HTTP1.1中是不允许的,这是由于提供一致更新
非常困难且服务器缓存和网络的故障比“write-back”早。


13.12 缓存替换
        如果收到一个新的响应,它的同源响应均已被缓存,缓存器就要用新响应
回复当前请求,且将其插入缓存器存储区,并用其回复所有被退回的旧响应。
        说明:一个日期报头比已存响应旧的新响应是不可缓存的。


13.13 历史纪录

        用户代理经常使用历史体制来重新获得以前的实体。
        历史机制和缓存是不同的,尤其历史对资源的当前状态是不透明的,更准
确地说就是历史纪录明示用户在获得资源时看到了什么。
        默认情况,过期时间不用在历史机制中。若实体仍然在存,即使它过期
历史机制仍可以显示它,除非用户明确提出要代理刷新过期纪录。
           这并不能解释为禁止历史体制告诉用户事情已经过时。

    
        说明:如果历史纪录未必阻止用户看过时资源,这将强制服务提供者避免
使用HTTP过期控制和缓存控制。

                             
14 报头域定义
  本节定义了所有HTTP/1.1种标准头域的语法和语义。对于实体头域,发送者和接收者指的是客户端和服务器,它是由实体的发送和接收者来定义的。
阅读(1751) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~