HTTP超文本传输协议-HTTP/1.1中文版
摘要
超文本传输协议(HTTP)是一种为分布式,合作式,多媒体信息系统服务,面向应用层的协议。它是一种通用的,不分状态(stateless)的协议,除了诸如名称服务和分布对象管理系统之类的超文本用途外,还可以通过扩展它的请求方式,错误代码和报头来完成许多任务。HTTP的一个特点是数据表示方式的典型性和可协商性允许独立于传输数据而建立系统。在1990年WWW全球信息刚刚起步的时候HTTP就得到了应用。HTTP的第一个版本叫做HTTP/0.9,是一种为互联网原始数据传输服务的简单协议。由RFC 1945定义的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,NNTP,FTP,Gopher和WAIS协议支持。这样,HTTP允许不同的应用程序对资源进行基本的超媒体访问。
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)
向内和向外指的是消息的请求和应答路径:"向内"即"移向原服务器","向外"即"移向用户代理".
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节)。
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消息
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://www.w3.org/pub/www/TheProject.html 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:www.w3.org
接下来是请求的其他部分,注意绝对路径不能是空的;假如没有初始的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, 则可以安全的假定请求有错,且其对待应答的情况是仿佛客户端收到的是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节所描述的那样服从消息传输的需要.
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 强,弱确认器
由于源服务器和缓存器会比较两个确认器来确定他们是否代表相同的条目,所以通常希望实体发生任何变化,确认器也相应变化,这样的确认器为强确认器.
同时还会有这样的情况,服务器倾向于仅在发生重要的语义变化时才改变确认器.在资源变化时确认器未必变化的称为弱确认器.
实体标签通常是强确认,但协议提供一种机制来标志弱确认.可以认为,强确认在实体的每一字节变化时均变化,而弱确认仅在实体含义变化时才变化,强确认是某一特定实体的标志,而弱确认是某一类同义实体的标志.
注: 强确认的例子:一个整数,他随着每次实体发生变化而定值增长.
一个实体的修改时间(以秒计算)可以作为弱确认器,因为实体可能在一秒内变化两次.
对弱确认的支持是可选的.支持弱确认可带来等价体的高效缓存.
当客户生成一个在确认报头中包含确认器的请求或服务器进行比较时均要用到确认器.
强确认可在任何情况下使用,而弱确认仅在不依赖严格相等时才可用.
客户可以发出简单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)
服务器要用变化报头区告知缓存器在众多可缓存响应类型用什么样的请求
报头区来用服务器驱动转让.变化区命名此类报头区为"选择"请求报头.
当缓存器收到指定一个或更多包含变化报头区的缓存实体的后续请求,缓存器不能用这样的缓存实体来构造新请求的响应,除非新请求中所有选中的请求报头与初始请求相应部分匹配.
当且仅当两个请求中的选择请求报头可以从前一请求变形为后一请求时称为匹配.变形指,在相应的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种标准头域的语法和语义。对于实体头域,发送者和接收者指的是客户端和服务器,它是由实体的发送和接收者来定义的。
14.1接受(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/*"指出了某种形式的图表类形.媒体范围可能包含适用于那个范围的媒体形式参数.每个媒体范围可能跟随着一个或者多个接受-参数.开始为字母"q"的参数指出相关质量的因素.任何一个开头字母为"q"将媒体范围参量和接受参量区分开来.质量要因素允许用户或者是用户代理使用从零到一的值来指出对于此媒体形式来说喜欢
的相关程度,缺省时q的值是1.
注释:q参数名字可以用来将媒体形式从接受扩展参量中分辨出来,这是由于以前的练习.虽然这保护了任何任何首字母为q的参量被煤体范围一起使用,这样的事件被
认为不太可能在LANA注册中被给与缺少的"q"参量或者在Accept中任何媒体形式的
珍稀用法.未来的媒体形式从注册和"q"参量中气馁了.
例子:
Accept: audio/*; q=0.2, audio/basic
该例应该被解释作"我喜欢audio/basic,但是如果在质量中€标记向下之后是最佳可利用的话,就给我发送任何音频形式.如果当前没有接受报头区域,那么可以认为是客户接受了所有的媒体形式.如果当前有接受报头区域并且如果服务器不能发送根据组合接受区域的值可以接受的响应的话,那么服务器应该发送一个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/plain实体."
媒体范围可以不被更多特定媒体范围或者特定媒体形式考虑.如果多余一个的媒体范围适用于一个给出的形式的话,那么最最特定的参考优先.
比如"Accept: text/*, text/html, text/html;level=1, */*"就有以下的优先:
1) text/html;leve=1
2) text/html
3) text/*
4) */*
和一个给出的形式相关联的媒体形式质量要素就是由寻找有和形式相匹配的的最最优先的媒体形式来决定的,比如:
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
注释:一个用户代理可能会被提供一套默认的针对于特定媒体范围的值.然而,除非用户代理是个关闭的系统并且不可以和其他翻译代理相互作用,这套缺省可以由用户自己来配置.
14.2 接受-字符集(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
特殊的值"*",如果在接受-??区域显示的话,则可以与每一个并没有在接受??中其他什么地方提起的特性装置相匹配.如果没有'*'在当前接受-??区域,那么所有没有明确提出的特性装置都回得到一个为零的质量值,除去在相同情况下可以得到1的iso-8859-1.如果没有接受-??报头在当前,那么缺省设置就是任何特性装置都是可接受的.如果当前存在接受-??报头并且服务器不能发送根据接受-??报头可以接受的响应的话,那么服务器就会发送一个错误响应和406状态代码,在不可接受响应在发送过程中时也是允许的,
14.3 接收编码(Accept-Encoding)
接收编码(Accept-Encoding)请求报头域和接收(Accept)相似,但限定响应中可接收的内容码(content-codings)(3.5节).
Accept-Encoding = "Accept-Encoding" ":"
1#( codings [ ";" "q" "=" qvalue ] )
codings = ( content-coding | "*" )
Examples of its use are:
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
根据接收编码(Accept-Encoding)域测试内容码(content-coding)是否可接受的服务器采用这些规则:
如果内容码(content-coding)是接收编码(Accept-Encoding)域中列出的一系列内容码(content-codings)中的一种,则它是可接受的,除非它跟着 a qvalue of 0.(定义在3.9节, a qvalue of 0.意思是不可接受的)
接收编码(Accept-Encoding)域中的特殊符号”*”匹配任何报头域中没有明确列出的可利用的内容码(content-coding).
如果多种内容码(content-codings)是可接受的,则具有最高非零qvalue的内容码(content-codings)是优先的.
"identity"内容码(content-codings)总是可接受的,除非特定的说明其是不可接受的,因为接收编码(Accept-Encoding)域包括"identity;q=0"或者因为域中包括"*;q=0"和不明确的包括"identity"内容编码.如果接收编码域的值为空,则只有"identity"编码是可接收的.
如果接收编码域出现在请求中,且根据接收编码报头服务器不能发送可接收的响应,则服务器应当发送带有406(Not Acceptable)状态码的出错响应.
如果请求中没有接收编码域,服务器可以假定客户机将接收任意的内容编码.在这种情况下,如果"identity"是可利用的内容编码之一,则服务器应该采用"identity"内容编码,除非有额外的信息说明别的内容编码对客户机更有用.
注意:如果请求中没有包括接收编码域,且"identity"内容码是不可利用的,则能被HTTP/1.0客户机解读(i.e."gzip" and "compress")的内容码一般是优先的.当发送别的内容码是,一些老的客户机显示不正确的信息.服务器也许会以关于用户代理或客户机的信息为基础做出决定.
注意:大多数HTTP/1.0应用程序不承认或遵守域内容码相关的qvalues.这意味着qvalues将不工作或被x-gzip or x-compress允许.
14.4 认可术语
The Accept-Language request-header field is similar to Accept, but restricts the set of natural languages that are preferred as a response to the request. Language tags are defined in section 3.10.
认可术语请求报头区与认可是相近的,但规定了一套自然语言用来响应请求.术语
标识在3.10节说明.
Accept-Language = "Accept-Language" ":"
1#( language-range [ ";" "q" "=" qvalue ] )
language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
每个语言范围均被赋以一个品质因数,它代表用户用这种语言的钟爱程度.品质因
数默认值为一.例如:
认可语言: da, en-gb;q=0.8, en;q=0.7
表示:我喜欢丹麦语,但也接受不列颠英语和其它种英语.一种语言范围对应一种术语标识如果它正好等于标识,或者如果它正好等于标识的前缀,例如第一个跟在前缀后面的标识符是'-'.特殊范围"*",如果在认可术语区中出现,对应所有标识符。
说明:使用前缀匹配规则并不表示如果用户理解一戴又标识的术语,他就也理解所有代前缀标识的术语。
认可术语区指定给语言标识的语言品质因数是匹配标识的最大语言范围的品质数值。如果在此区内没有语言范围匹配此标识,则品质因数制定为0。如果请求中没有认可术语报头,服务器应假设所有语言被等同接受。如够出现了认可术语报头,则所有品质因数大于0的语言均是可接受的。
在每个请求中发送认可术语报头说明可接受语言与保护用户隐私识背道而驰的,对此问题的专门讨论见15.1.4
鉴于可理解性高度依赖于个别用户,推荐客户应用用户理解的语言.如果选择用户不理解的,则请求中不能加入认可术语报头区.
说明:当选择用户可接受语言时,我们提醒实现者如下事实,用户并不熟悉术语匹配的细节,所以应给出适当提示.
14.5接收范围(Accept-Range)
接收范围(Accept-Range)响应报头域允许服务器给出对资源请求的接收范围:
Accept-Ranges = "Accept-Ranges" ":" acceptable-ranges
acceptable-ranges = 1#range-unit | "none"
接收byte-range请求的源服务器可以发送
Accept-Ranges: bytes
但没必要那样做.客户机可以产生byte-range请求,即使是它没有收到相关的报头域.Range units定义在3.12节.
不接收任何种类对资源的范围(range)请求的服务器可以发送
Accept-Ranges: none
来建议客户机不要尝试范围(range)请求.
14.6 年龄(Age)
Age响应报头域表示发送者对传输时间的估计,既然响应是由源服务器产生的.假如缓存的响应没有超过它的寿命,则认为它是有活力的(fresh).13.2.3节说明了Age值的计算.
Age = "Age" ":" age-value
age-value = delta-seconds
Age值是十进制非负整数,以秒为单位.
如果高速缓存存储器收到一个大于它所能表示的上限整数的值,或它的Age计算溢出,它必须传送值为2147483648 (2^31)的Age报头域. 带有高速缓存存储器的HTTP/1.1服务器产生的每一个响应(从它本身的高速缓存存储器中)都必须包括Age报头域. 高速缓存存储器应当采用至少31位的算法.
14.7 允许(Allow)
允许 (Allow)实体报头域中列出了由请求指定资源支持的几种方法--URI。这一报头域的目的严格限于通知接收者与资源相联系的方法有哪些。允许报头域必须出现在405(方法不被允许)应答中。
允许="允许"":" #方法
使用示例:
允许: GET, HEAD, PUT
这一报头域不能阻止用户使用其他方法。然而允许域给出的指示应予以执行。由原服务器在处理每一请求时定义允许的方法集。
允许域可由PUT请求提供,以建议新资源支持某些方法。服务器不必一定支持这些方法,且应在允许域中给出实际支持的方法。因为用户有其他与原服务器通信的渠道,故代理服务器即便不理解域中指明的所有方法,也不得修改允许报头域
14.8 授权(Authorization)
用户代理往往希望服务器自我验证,但在收到401响应后则没有必要了.用户代理通过包括Authorization请求报头域的请求那样做. Authorization请求报头域的值由包含用户代理验证信息的信任状所组成,这些用户代理处于请求资源的领域.
Authorization = "Authorization" ":" credentials
HTTP Authentication中描述了HTTP访问的身份鉴定: Basic and Digest Access Authentication" [43].假如请求在特定的领域中通过了验证,则同样的信任状对该领域内所有其它请求都是有效的(假定验证方案本身不需要,否则信任状依照亟待解决的问题或用同步时钟而不同)
当共享的高速缓冲存储器(看13.7节)接收具有验证(Authorization)域的请求时,必须返回相应的响应作为其他请求的应答,除非是接下来的特殊情况之一.
如果响应包括s-maxage缓存控制指示信息,高速缓存可以用响应来应答并发的请求.但(如果已超过了特定的最大生存期)代理服务器的高速缓存首先必须重新生效,用来自新请求的请求报头允许源服务器验证新的请求.(这是为s-maxage定义的行为.)假如响应包括"s-maxage=0",代理服务器必须在重新利用之前使之生效.
如果响应包括must-revalidate缓存控制指示信息,高速缓存可用响应来应答并发请求.但如果响应失去时效,所有缓存首先必须使它重新生效河源服务器一致,用来自新请求的请求报头允许源服务器验证新的请求.
假如响应包括public缓存控制指示信息,它可以被返回来应答并发请求.
14.9 缓存-控制(Cache-control)
缓存-控制通用-报头域用于标明请求/应答链上所有缓存机制必须遵守的指令。这些指令规定了一些意在预防缓存对请求或应答造成不良影响的行为。它们通常覆盖了缺省的缓存算法。 缓存指令是单方向的,因为请求中指令的存在并不意味着应答中也会有同样的指令。
请注意HTTP/1。0缓存机可能并不实现缓存-控制,而是只实现Pragma:无-缓存(参见14。31节)。
代理服务器或网关的应用程序必须不顾缓存指令对其本身的意义,毫无例外的让它们通过,因为这些指令可能对请求/应答链上的所有接收者都适用。
缓存-控制="缓存-控制"":" 1#缓存-指令
缓存-指令="缓存-请求-指令|缓存-应答-指令
缓存-请求-指令=
"无-缓存" ; 14.9.1节
| "无-存储" ; 14.9.2节
| "最大-时限""=" delta-秒 ; 14.9.3, 14.9.4节
| "最大-陈旧" ["="delta-秒] ; 14.9.3节
| "最小-保鲜"["="] delta-秒 ; 14.9.3节
| "不传输" ; 14.9.5节
| "仅当缓存时" ; 14.9.4节
| 缓存-扩展 ; 14.9.6节
缓存-应答-指令=
"公共" ; 14。9。1节
|"私有"["="<"" 1#域名〈"〉]; 14。9。1节 |"无缓存" ["="<"" 1#域名〈"〉]; 14。9。1节
|"不存储" 14。9。2节
|"不传输" 14。9。5节
|"必须经重新确定有效" 14。9。4节
|"代理服务器重新确定有效" 14。9。4节
|"最大时限""="delta-秒 14。9。3节
|"s-最大时限""="delta-秒 14。9。3节
|缓存-扩展 14。9。6节
当指令不伴有1#域名参数出现时,该指令适用于整个请求或应答。
当指令伴有1#域名参数出现时,它仅适用于被命名的域,而不适于请求或应答的其他部分。这一机制支持可扩展性;HTTP协议将来的版本可以通过将指令应用于HTTP/1。1中未定义的域来实现。
缓存-控制指令 可分为如下几类:
-- 对可缓存的范围的限制;这可能只由原服务器指定。
-- 对缓存内容的限制;这可由原服务器或用户代理指定。
-- 对基本过期无效机制的改进;这可由原服务器或用户代理指定。
-- 对缓存重新确认有效及重载的控制;这可能仅由用户代理指定。
-- 对实体传输的控制
-- 缓存系统的扩展。
14.9.1 何谓可缓存的
缺省情况下,若请求方法,请求报头域和应答状态指明了应答为可缓存的,则它就是可以缓存的。 13。4节总结了这些可缓存性的缺省情况。 下列缓存-控制应答指令允许原服务器覆盖缺省的应答的可缓存性:
公共
指明应答可被任意高速缓存机缓存,即便在该应答通常是不可缓存的或只可由不共享的高速缓存机缓存的情况下也是如此。(参见14。8节,关于认证的附加详述)
私有
表明应答报文的所有部分都是为单一用户准备的且不得被共享缓存机缓存。
这使原服务器可以申明应答的特定部分是针对单一用户的,对其他用户的请求而言并非有效应答。 私有(不共享)缓存可以缓存应答。
注:私有一词仅用来控制应答在何处可被缓存, 而不能保证报文内容的私有性。
不缓存
若指令"不缓存"没有指定域名,则缓存机不得应答那些未经原服务器重新确认有效的后继的请求。
这使得原服务器即便对设置为回送陈旧应答给客户请求的高速缓存机也能防止缓存。
若指令"不缓存"确实指定了一个或多个域名,则高速缓存机可以在其他的缓存要求限制下应答后继请求。 然而,指定的域名不得在用于应答那些未经原服务器重新确认有效的后继请求。这使得原服务器防止了应答中某些报头域重复使用,同时又允许缓存应答的剩余部分。
注:大多数HTTP/1。0高速缓存机不会认出或遵守这一指令。
14.9.2 哪些可被高速缓存机保存
不保存
"不保存"指令的目的在于防止无意中泄露或滞留了敏感信息(比如存在备用磁带上了)。
"不保存"指令适用于整个报文,可在请求或应答中发送。 若由请求方发送,则高速缓存机不得保存该请求或其应答的任何部分。若由应答方发送,高速缓存机不得保存该应答和相应请求的任何部分。该指令对非共享与共享高速缓存机都适用。 "不得保存"在这里意味着缓存机不得有意地将信息保存在非易逝存储器上,且必须尽最大努力将信息在转发后尽快从易逝存储器上转移。
即使这一指令是与应答相联系的,用户也可能明言要在缓存系统之外保存该应答(比如通过"另存为"对话框)。 历史缓存区可作为例行公事保存这些应答。
这一指令地目的在于满足某些在意信息经未知渠道偶然泄漏到缓存数据区的用户与服务程序作者提出的要求。虽然这一指令的使用可能改善了保密性,但值得提醒的是,它又绝非保证保密性的充分的或可靠的机制。
14.9.3 对基本过期失效机制的改进
实体的过期时间可由原服务器的"过期"报头(参见14。21节)指定。 或者,它也可由应答中的"最大-年龄"指令说明。当被缓存的应答含有"最大-年龄"缓存-控制指令时,应答若现有年龄大于出现对同一资源的新请求中所给年龄值(以秒为单位)则被视为陈旧。应答中的"最大-年龄"指令意味着该应答是可缓存的(如,"公共"),除非存在其他更严格的缓存指令。
若应答同时含有过期报头与"最大-年龄"指令,最大-年龄指令覆盖过期报头,即便过期报头中的描述更严格也不例外。这一规则使原服务器可就给定应答为HTTP/1。1(或更新的版本)缓存机提供比HTTP/1。0缓存机更长的过期时间。这在某一HTTP/1。0缓存机出于诸如类似同步时钟的原因错算了年龄或过期时间的情况下可能有用。
许多HTTP/1。0缓存机会按照与缓存-控制应答指令"不缓存"等价的方式来处理小于或等于应答日期值的过期值。若HTTP/1。1缓存机接到这种应答,且应答不含缓存-控制报头域,则它应视应答为不可缓存,从而保持与HTTP/1。0服务器的兼容性。
注:在兼有不懂新特性的旧版缓存机的网络上,一台原服务器可能愿意采用较新的HTTP缓存控制功能,如"私有"指令。这样,原服务器就需要将新特性与其值小于等于日期值的过期报头域结合起来。这将防止旧版缓存机误缓存应答。
s-最大年龄
若应答包含s-最大年龄指令,则对共享缓存机(而非私有缓存机)而言,由该指令指定的最大年龄覆盖其他最大年龄指令或过期报头的指定。 S-最大年龄指令也暗示了代理服务器-重新确定有效指令的句法(参见14。9。4节),也就是说,在首先经原服务器重新确认为有效之前,共享缓存机不得用那些变得陈旧了的目录来应答后继请求。 私有高速缓存机忽略此s-最大年龄指令。
请注意,大多数与此规范不相适的旧版缓存机并不执行任何缓存-控制指令。 想要使用缓存-控制指令来限制而非避免遵守HTTP/1。1的缓存机进行缓存得原服务器可以利用最大-年龄指令覆盖过期报头的条件以及早于HTTP/1。1的缓存机不检查最大-年龄指令这一事实。
其他指令允许用户代理修改基本过期失效机制。 这些指令可由请求指定:
最大-年龄
表明客户机愿接受其年龄不大于指定时间(以秒计算)的应答。除非也含"最大-陈旧"指令,否则客户机不愿接受陈旧应答。
最小-保鲜
表明客户机愿接受其保鲜寿命不小于现有年龄与指定时间之和(以秒计算)的应答。也就是说,客户机想要一至少在一定时间内保持保鲜的应答。
最大-陈旧
表明客户机愿接受已经过期的应答。 若指定最大-陈旧为某值,则客户机愿接受过期时间不超过给定秒数的应答。若未指定最大-陈旧的值,则客户机愿接受任意年龄的陈旧应答。
若缓存机或出于请求的最大-陈旧指令,或出于缓存机被设置为覆盖应答过期时间的原因,最终返回了一个陈旧的应答,缓存机都必须在旧应答上添加一警告报头,采用警告110(应答是陈旧的)。
高速缓存机可被设置成不经确认就返回陈旧应答,但这不应与任何"必须"等级的关于缓存重确认的要求(如"必须-重新确认有效"缓存-控制指令)冲突。
若新请求与缓存的条目均包括"最大-年龄"指令,则取两者间较小值来决定该请求的缓存条目的保鲜程度。
14.9.4 缓存重新确认有效和重载控制
有时用户代理可能希望或出于需要坚持让缓存机与原服务器之间重新确认缓存条目的有效性(而不只是通向原服务器的传输路径中的下一高速缓存机),或是从原服务器处重载缓存条目。端到端的重新确认有效手续在缓存机或原服务器高估了缓存应答的过期时间时可能需要。端到端重载在缓存条目由于某些原因被侵蚀时可能需要。
如果客户机没有自己的本地缓存拷贝,即所谓"未指明的端到端重新确认有效",或客户机没有本地的缓存拷贝,即所谓"经指明的端到端重新确认有效", 都有可能要求端到端的重新确认有效。
客户机可用缓存-控制请求指令来指明三种行动中的一种:
端到端重载
请求包括"不缓存"缓存-控制指令,或是与HTTP/1。0客户机兼容的"Pragma:不缓存"。
请求的"不缓存"指令中不得含有域名。服务器应答这种请求时不得使用缓存的拷贝。
经指明的端到端重新确认有效
请求包括"最大-年龄=0"缓存-控制指令,从而迫使通向原服务器路径上的每一高速缓存机都与下一缓存机或服务器之间重新确认自身条目的有效性。初始请求包括由客户机现有的确认模块决定的缓存有效性确认过程。
未指明的端到端重新确认有效
请求包括"最大-年龄=0"缓存-控制指令,从而迫使通向原服务器路径上的每一高速缓存机都与下一缓存机或服务器之间重新确认自身条目的有效性。初始请求中不包括缓存条件有效性确认过程。沿途第一个含有此资源缓存条目缓存机(如果存在的话)包括决定于现有的有效性确认模块的缓存-有效性确认。
最大-年龄
当中转缓存机被"最大-年龄=0"的指令迫使重新确认其缓存条目有效性,且客户机在请求中提供了自己的有效性确认器时,所供的有效性确认器可能不同于缓存条目中现存的有效性确认模块。在这一情况下,缓存机可以在不影响句法透明性的前提下将其中的任一有效性确认模块用于自己的请求。
然而,对有效性确认器的选择可能影响性能。 最好的方法是让中转缓存机采用自己的有效性确认模块来构造请求。若服务器应答以304(未经修改),则缓存机可以将自己的确认后拷贝连同200(OK)应答一起发回给客户机。但若服务器发回新的实体和有效性确认器,则中转缓存机可使用强比较函数比较返回的有效性确认器与客户机请求中提供的有效性确认器。若客户机的有效性确认器与原服务器的一致,则中转缓存机仅需发送回304(未经修改)。 否则,它就发回新的实体和200(OK)应答。
若请求含有"不缓存"指令,则它不得包括最小-保鲜,最大-陈旧或最大-年龄指令。
仅当经缓存时
在某些情况下,如网络连接极为糟糕时,客户机可能想要缓存机只返回它现存的应答,而不要与原服务器之间进行重载或重新确认有效性。为实现这一点,客户机可以在请求中包括"仅当经缓存时"指令。若它收到这一指令,缓存机应该应答以符合请求其他限制的缓存条目,或是应答以504(网关超时)状态。 然而,当一组缓存机是作为呢部内部联系良好的同一系统来操作的话,这样的请求可能会在那组缓存机内部转发。
必须-重新确认有效性
由于缓存机可能被设置为忽略服务器指定的过期时间,且客户机请求可能包括最大-陈旧指令(与前者效用相似),协议还包括了一种由原服务器要求后继使用中重新确认缓存条目有效性的机制。
当缓存机接到的应答中有必须-重新确认有效性指令时, 该缓存机不得在条目变得陈旧后不经与原服务器重新确认有效性就用来应答后继请求。(也就是说, 若仅由原服务器的"过期"报头或"最大-年龄"取值确定缓存的应答已陈旧,缓存机就每次都必须执行端到端有效性重新确认。)
"必须重新确认有效性"指令对支持某些协议特性可靠运作是必要的。在所有情况下,HTTP/1。1缓存机必须遵守"必须重新确认有效性"指令;特别是,若缓存机出于任何原因无法到达原服务器,则它必须产生504(网关超时)应答。
当且仅当对实体的请求的有效性重确认的失败会导致错误的操作(比如未申明但未被执行的最终事务)时,服务器应该发送"必须重新确认有效性"指令。 接收者不得采取任何违背该指令的自动行动,也不得在重确认失败时自动提供未经确认的实体拷贝。
虽不提倡如此,但受到严格的连接限制的用户代理还是可以违背这一指令,但在这么做的同时必须明确警告用户提供的是未经有效性确认的应答。每一未确认的访问都必须伴有警告,且应要求明确的用户许可。
代理服务器-重新确认有效性
除了不适于非共享用户代理缓存机之外, "代理服务器-重新确认有效性"指令与"必须重新确认有效性"指令含义相同。 它可用于对经认证的请求的应答,以允许用户的缓存机保存应答,并在稍后无须重新确认就返回应答(因为它已经被该用户认证了),同时仍然要求服务于多个用户的代理每次都重新确认有效性(从而确保每一用户都通过认证)。 请注意这种经认证的应答还需要"公共"缓存-控制指令,使得它们可以被缓存。
14.9.5 不得转换指令
不得转换
中转缓存机(代理服务器)的实现者们发现转换某些实体正文的媒体类型是很有用的。 比如,一台非透明的代理服务器可以在图象格式之间进行转换,以节省缓存空间或减少慢速链路上的数据通信量。
然而,当这些转换应用于某些应用的实体正文时,会引发严重的操作方面的问题。比如,医学图象应用,科学数据分析和端到端认证都依赖于接收到与原实体正文一比特都不差的实体正文。
所以,如果报文包括了"不得转换"指令, 中转缓存机或代理服务器就不得改变13。5。2节中列出的受"不得转换"指令影响的报头。这意味着缓存机或代理服务器不得改变由这些报头定义的实体正文的任何方面,包括实体正文值本身。
14.9.6 缓存控制扩展
缓存-控制报头域可通过一个或多个缓存-扩展标志的使用来实现扩展。其中每一标志都赋予一可选的值。 信息性的扩展(那些无须改变缓存机行为的)可以不经改变其他指令的句法而添加。
行为性扩展被设计为现有基本缓存指令的修正。 新指令与标准指令都有提供,于是不理解新指令的应用程序会缺省地按采用标准指令规定的行为,而理解新指令的应用程序则将其认作标准指令提出的要求的修正。这样,缓存-控制指令可以无须改变基本协议就得到扩展。
这一扩展机制依赖于HTTP缓存机对所有初始HTTP版本中缓存-控制指令和某些扩展方式的遵守,以及对所有它不理解的指令的忽略。
例如,考虑一个假想中的名为"共同体"的新应答指令,作为"私有"这里指令的修正。我们定义这个新的指令以表明除了非共享缓存机之外,任何只可被同一共同体成员共享的缓存机都可以缓存此应答。原服务器若想允许UCI共同体在它们的共享缓存机之间使用本来是私有的应答,只需在该应答中添入:
缓存-控制:私有, 共同体="UCI"
见到这一报头域的缓存机即便不理解"共同体"缓存-扩展也能正确操作,因为它还见到并理解"私有"指令,就会按缺省的安全方式行事。
未经认出的缓存-指令必须被忽略;按照假定,任何可能未被HTTP/1。1高速缓存机认出的缓存-指令都与标准指令(或应答的缺省可缓存性)相结合使用,从而是缓存机的行为即便在它不理解扩展指令时也尽可能保持正确。
14.10 连接
连接这一概括报头域允许发送者指定某一特定连接中的选项设置,且不得由代理服务器在以后的连接中传送。
连接报头遵循如下语法:
连接="连接"":" 1#(连接-标志)
连接-标志=标志
HTTP/1。1代理服务器必须在转发报文之前即解析连接报头域,针对域中每一连接-标志,从报文中移开所有与连接-标志同名的报头域。 连接选项是由连接报头域中的连接-标志指明的,而非任何附加的报头域,因为这些附加报头在缺少与连接选项相关的参数时无法被传送。
连接报头中列出的报文报头不得含有诸如缓存-控制之类的端到端报头。
HTTP/1。1定义了"close"选项,以供发送者宣布连接在完成应答后将被关闭。例如
连接:close
无论是出现在请求或应答的报头域中,都表明连接不应被视为在完成现有请求/应答后是"持续的"(参见8。1节)。
不支持持续连接的HTTP/1。1应用程序必须在每一报文中都添上"close"连接选项。
接收到含有连接报头的HTTP/1。0(或更低版本)报文的系统必须为每一连接-标志都去除或忽略报文中与之同名的报头域。这样做避免了早于HTTP/1。1版本的代理服务器误转发这些报头域。
14.11 内容编码
"内容编码"实体报头域是作为媒体类型的修正。此域存在时,其值表明对实体正文采用了何种附加的内容编码,从而须采用何种解码机制以获取"内容类型"报头域中指出的媒体类型。"内容编码"的主要目的是使文件可以在不丧失其基本媒体类型身份的同时被压缩。
内容编码="内容编码" ":" 1#内容译码
内容译码由3。5节定义。其应用示例为:
内容编码:gzip
内容译码是由请求定义(URI)的实体特性。通常,实体正文以编码方式存储,只在翻译或类似使用前才解码。然而,非透明代理服务器在确知新译码可被接受者认可的情况下可能会改变内容译码,除非报文中含有"不得转换"的缓存控制谓词。
若实体的内容译码不具备同一性,则应答必须包含列有所用非同一内容译码的内容编码实体报头(14。11节)。
若请求报文中的实体内容编码对原服务器而言不可接受,则服务器应以415(不被支持的媒体类型)状态码应答。
若实体采用多种编码,则内容译码应按它们的使用顺序列出。
关于编码参数的其他信息和由未被此说明定义的实体报头域给出。
14.12 内容语言
内容语言实体报头域描述了实体面向的受众的使用语言。请注意,这不一定等同于实体正文中用到的所有语言。
实体语言="实体语言"":"1#语言标记
语言标记由3。10节定义。内容语言的主要目的在于让用户根据自己喜用的语言确认并区别众实体。由是,若正文内容只是针对懂荷兰语的人的话,相应的域应为:
内容语言:da
若未指明内容语言,缺省值为内容针对所有语种的受众。这既可能指发送者认为内容与任意自然语言无关,也可能指发送者不知此内容应面向何种语言。
要面向多种听众,可列出多种语言。例如,同时用毛里土语和英语发行的"Waitangi之约"就可以用:
内容语言:mi,en
然而,实体中有多个语种并不代表它一定是为多语种的观众准备的。比如"初学拉丁文"之类的语言启蒙教程,显然是针对英语观众的。这里,恰当的"内容语言"应只包括"en"。
内容语言可用于任意媒体类型 -- 它不限于文本式文件。
14.13 内容长度
内容长度实体报头域按十进制或八位字节数指明了发给接收者的实体正文的大小,或是在使用HEAD方法的情况下,指明若请求为GET时将发送实体正文的大小。
内容长度="内容长度"":"1*DIGIT
示例:
内容长度:3495
除非按4。4节的规则被禁用,应用程序应使用此域指明报文正文的传输长度。
任何不小于零的内容长度均为有效值。 4。4节描述了如何在未知内容长度时测定报文长度的方法。
请注意此域的含义域MIME中的相应定义迥异。MIME中,它是"报文/扩展正文"内容类型的可选域;在HTTP中,除非按4。4节的规则被禁用,一旦报文长度在传送前被确定,就应发送此域。
14.14 内容位置
内容位置可用来在从一独立于请求资源的URI的位置访问实体时提供报文中实体的资源位置。服务器应根据应答实体为此变量提供一内容位置;尤其是在资源和多个实体相联系,而这些实体各享独立位置,可被分别访问时,服务器应为特定的返回变量提供内容位置。
内容位置="内容位置"":"(绝对URI|相对URI)
内容位置的值也决定了实体的基础URI。
内容位置值并非原请求URI的替代;它只是申明了请求中对应特定实体的资源位置。
此后的请求若想确定特定实体的来源,可以指定内容位置URI为请求的URI。
缓冲存储机不能以为若实体的内容位置URI异于访问URI就可用此实体来应答那一内容位置URI下的后续请求。但如13。6节所述,内容位置可用于区分从同一请求资源得到的多个实体。
若内容位置是相对URI,则此相对URI是相对于请求URI来解释的。
PUT或POST请求中内容位置报头的含义未定;服务器可自由忽略。
14.15 内容-MD5
如RFC 1864[23]中所定义的,内容-MD5实体报头域是实体正文的MD5摘要,以期提供端到端的实体正文的报文完整性检验(MIC)。(注:MIC有利于检测实体正文传送中的偶发改动,但不一定能防范恶意袭击。)
内容-MD5="内容-MD5"":" MD5-摘要
MD5-摘要=< 由RFC 1864 定义的的 基64的128比特MD5摘要>
内容-MD5报头域可由原服务器或客户机生成,用作实体正文的完整性检验。只有原服务器或客户机可生成内容-MD5报头域;不得由代理服务器和网关生成,否则会有悖于其作为端到端完整性检验的价值。任何实体正文的接收者,包括代理服务器和网关,都可检查此域中摘要值与实体正文是否相符。
MD5摘要的计算基于实体正文的内容,包括任何所用的内容译码,但不包括任何对报文正文进行的传输编码。若接到的报文有传输编码,则必须在核对内容-MD5与所收正文之前解除编码。
这样造成的后果是:摘要完全按照它们若未经传输编码而被发出的顺序进行逐字节计算。
HTTP 将RFC 1864拓宽到允许对MIME组成的媒体类型(如multipart/*,message/rfc822)计算摘要,但这并不改变如前所述的摘要计算方法。
由此产生了一系列影响。组件类型的实体正文可能会包括多个正文部分,每一部分都有自己的MIME和HTTP报头(包括内容-MD5,内容-传输-编码,和内容编码报头)。如果正文部分有内容-传输-编码或内容编码报头,则被假定为正文部分的内容已经过编码处理,且正文部分依样包括在内容-MD5摘要中。 正文部分不得含有传输编码报头域。
不可在摘要计算或核对之前就将任何断线转换为CRLF:实际传输的文本中使用的断线转换协定必须原封不动的参与摘要计算。
注:虽然HTTP的内容-MD5定义和RFC 1864中关于MIME实体正文的完全一样, 但HTTP 实体正文在对内容-MD5的应用上仍然有几处与MIME实体正文有所区别。首先,HTTP不象MIME会用内容-传输编码,而是使用传输编码与内容编码。 其次,HTTP比MIME更多地使用二进制内容类型,故值得提出的是: 在此种情况下,用于计算摘要的字节序也即由类型定义的传输字节顺序。最后,HTTP允许文本类传输时采用数种断线协定,而不只是规范的使用CRLF的形式。
14.16 内容-范围
内容-范围实体报头与部分实体正文一起发送,用于指明在全部实体正文中,那一部分正文应该应用于何处。 范围的单位在3。12节中有定义。
内容-范围 = "内容-范围"":"内容-范围-说明
内容-范围-说明 = 字节-内容-范围-说明
字节-内容-范围-说明 =字节-单位 SP
字节-范围-方面-说明 "/"
(实例-长度|"*")
字节-范围-方面-说明 =(首字节位置 "-" 末字节位置) |"*"
实例-长度 =1*DIGIT
除非无法或很难测定,报头应指明全部实体正文的总长度。星号"*"表示生成应答信息时实例长度未知。
与字节-范围-指定符的值(参见14。35。1节)不同的是,字节-范围-方面-说明仅可指明一个范围,且必须包含首末字节的绝对位置。
其字节-范围-方面-说明的末字节值小于首字节值或实例-长度值小于等于末字节值的字节-内容-范围-说明是无效的。收到无效的字节-内容-范围-说明值时接收者必须忽略此值与随其传输的任何内容。
应答时发送状态码416(请求的范围无法满足)的服务器应在内容-范围域中填上字节-范围-方面-说明为"*"。实例-长度项指明被选资源的现有长度。状态码为206(部分内容)的应答不应将内容-范围域的字节-范围-方面-说明填为"*"。
假定实体共含1234字节,字节-范围-方面-说明项的示范值为:
头500字节: 字节0-499/1234
次500字节: 字节500-999/1234
除头500 字节外的所有: 字节500-1233/1234
末500字节: 字节734-1233/1234
当HTTP报文包含单一范围的内容时,(比如,对单一范围请求,或对一组互有覆盖但无遗漏的请求的应答)此内容在传输时内容-范围报头与内容-长度报头会显示实际传输的字节数。例如:
HTTP/1。1 206 部分内容
日期: 星期三, 1995年11月15日 06:25:24 (格林威治时间)
上次修改时间:星期三, 1995年11月15日 04:58:08 (格林威治时间)
内容-范围:字节21010-47021/47022
内容-长度: 26012
内容-类型:image/gif
当HTTP报文包含多个范围时(比如,对多个未重叠范围请求的应答),它们会被当作多部分报文来传送。
用于此目的的多部分媒体类型如附录19。2节中所述定义为"multipart/byteranges"。 其兼容性问题述于附录19。6。3中。
对单一范围请求的应答不得使用multipart/byteranges媒体类型。若对多范围请求的应答结果为单一范围,可以采用只有一个部分的multipart/byteranges媒体类型发送。无法对multipart/byteranges报文解码的客户机不得在单一请求中申请多个字节范围。
当客户机在单一请求中申请多个字节范围时,服务器应按请求中出现的顺序发回信息。
若服务器出于句法无效的原因忽略了字节-范围-说明,它应视无效的范围报头域不存在来处理请求。(正常情况下,这意味着发回含有全部实体的200应答。)
如果服务器接到请求报头域中含无法满足的范围(也即,所有字节-范围-说明值的首字节值大于所选资源现有长度)的请求(含条件-范围请求报头域的除外),则它应应答以代码416(请求的范围无法满足)(参见10。4。17节)。
注: 客户机对无法满足范围的请求报头不能指望服务器一定发回416(请求的范围无法满足)而非200(OK)的应答,因为不是所有服务器都处理这一请求报头。
14.17 内容-类型
内容-类型实体报头域指明发给接收者的实体正文的媒体类型,或在HEAD方法中指明若请求为GET时将发送的媒体类型。
内容-类型="内容-类型"":"媒体类型
媒体类型有3。7节定义。 此域的示例如下:
内容-类型:text/html; charset(字符集)=ISO-8859-4
7.2.1节提供了关于确定实体媒体类型方法的进一步论述。
14.18 日期
日期头域描述消息产生的日期和时间,它和RFC822中的ORIG-DATE语义一样。域值是一个在3。3。1描述的HTTP日期;它必须用RFC1123[8]数据格式发送。
Date="Date"":"HTTP-date
举个例子
Date:Tue,15 Nov 1994 08:12:31GMT
原服务器在所有的应答中必须包括一个日期头域,除了这些特例:
1 如果应答的状态代码时100(继续)获101(选者协议),相应可以在服务的选项中包括日期头域。
2 如果应答状态代码传送服务器错误,如500(internet服务器错误)获503(服务器不可达),它没有困难或不可能产生有效的日期。
3 如果服务器没有时钟,不能提供合理的当前时间的近似值,这个应答没必要包括日期头域,但在这种情况下必须遵照14.18.1节中的规则。
一个收到的消息没有日期头域的话会被接收者加上一个,如果这条消息将被那个接收者或网关储存并进由一个需要日期的协议。一个没有时钟的http执行不能缓存没有重新使之关于每一个使用有效的应答。一个http缓存,特别是一个共享的缓存,必须使用一种机制使它与外界可靠的时钟保持同步。
客户端秩序在包括实体的消息中发送日期头域,正如在PUT和POST请求的过程,甚至它是随意的。一个没有时钟的客户端不能在请求中发送日期头域。
一个日期头中的http-date没必要描述一个后续消息的产生的日期和时间。它必须描述消息产生的最有用的日期和实践的近似值。除非执行没有方法产生一个恰当的相当精确的日期和时间。理论上说,日期必须是实体产生之前的那一刻,实际上,日期能是消息产生的任何时候的时间而不会影响其语义。
14.18.1 没有时钟的原服务器的运作
一些原服务器的执行可能没有可用的时钟。一个没有时钟的原服务器不能指定一个应答断开或维持修改的值除非这些值是和系统或用户可靠的时钟资源相关联的。它可以指定一个知道的终止值,在服务配置的时间或以前,这是过去的(这允许应答的预终止而不保存每个资源分离的分割值)。
14.19 ETag
Etag应答报头域提供了请求变量的当前实体标签。与实体标签一起使用的报头由14。14,14。26,14。44节描述。
实体标签可用于比较来自同一资源的不同实体。(参见13。3。3节)
Etag="ETag" "Etag"":" 实体-标签
例:
ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""
14.20 期望
期望请求报头域用于指明客户机需要特定的服务器行为。
期望="期望"":"1#期望值
期望值="100-继续"|期望值-扩展
期望值-扩展=标号["="(标号|引用-字符串) *期望-参数]
期望-参数=";"标号["="(标号|引用-字符串)]
对请求的期望域中期望值不理解或与其不相容的服务器必须应答以相应的出错状态。 如果所有期望都无法满足,服务器必须应答以417(期望失败)状态。 若请求有其他问题,则应应答以其他4xx状态。
本报头域依照可扩展语法定义,以满足将来扩展需要。若服务器接到的请求含有它不支持的期望-扩展,则它必须应答以417(期望失败)状态。
期望值的比较对于未经引用的标号(包括"100-继续"标号)是而言对个例敏感的,对引用字符串的期望-扩展而言是对个例不敏感的。
期望机制是逐站进行的:即HTTP/1。1代理服务器在无法满足请求期望时必须.回送417(期望失败)状态。 然而,期望请求报头本身却是端到端的;它必须随请求一起转发。
许多旧版的HTTP/1。0和HTTP/1。1应用程序不理解期望报头。
参见8。2。3节中100(继续)状态的使用。
14.21 过期(Expire)
"过期"实体报头域给出了在何日何时之后应答即被视为陈旧。除非首先经原服务器(或含有此实体较新拷贝的中介代理服务器缓存)确认为有效,缓存一般不会返回陈旧的缓存目录值。 请参见13。2节中对过期模型的深入论述。
其格式为由3。3。1节中HTTP-日期定义的绝对日期与时间; 它必须遵照RFC 1123的日期格式:
过期="过期"":" HTTP-日期
使用示例为:
过期: 星期四,1994年12月1日, 16:00:00 格林威治时间
注:若应答包含填有最大时限谓词(参见14。9。3节)的缓存-控制域,则谓词作用覆盖过期域。
HTTP/1。1客户机和缓存必须把其它无效的,尤其是含有"0"值的日期格式按过去值(即"已经过期")处理。
要将应答标为"已经过期",原服务器须发送和日期报头值相等的过期日期值。(参见13。2。4节的过期计算规则)
为标记应答为"永不过期",原服务器须发送过期日期晚于发送应答的时间一年左右的过期日期。HTTP/1。1服务器不应发送超过将来一年的过期日期。
对于原本不可被缓存的应答而言,除非缓存控制域中另有指定,否则
过期报头域中填有将来的某一日期和时间值即是表明该应答允许缓存,
14.22 From
From请求报头域,如果给定的话,应该(SHOULD)包括控制请求用户代理的人的互联网E-MAIL地址。这个地址应该(SHOULD)是适用于机器的,就像在RFC 822 [9]里定义的“mailbox"以及在RFC 1123 [8]修订的:
From = "From" ":" mailbox
例如:
From: webmaster@w3.org
报头域可以(MAY)用作记录日志的目的和作为认证无效或者多余请求源的方法。他不应该(SHOULD NOT)用作不安全形式的访问保护。这个域的解释是请求正在为某个给定的人执行,它承担这个方法执行的责任。特别的,自动控制代理应该(SHOULD)包括这个域这样一来如果接收端出现问题的话,对运行这个自动控制程序有责任的人能够得到联系。
这个域的互联网E-MAIL地址可以(MAY)从发出请求的互联网主机中分离出来。例如,当一个请求通过一个代理服务器是应该(SHOULD)使用原发出者的地址。
客户机不应该(SHOULD)发出没有得到用户批准的From域,因为它可能和用户的个人利益或者他们站点的安全政策冲突。强烈建议用户在任何一次请求之前能够取消,授权,和修改这个域的值。
14.23 主机(Host)
主机(Host)请求报头域说明了正在请求的资源的互联网主机和端口号,就包括在用户或者提交的资源指定的源URI中(一般是一个HTTP URL,就像在3.2.2部分描述的)。Host域的值必须(MUST)代表源URL给定的源网关或者服务器的授权命名。这允许源服务器或网关区分内部不明确的URL,例如单个IP地址上有多个主机域名的服务器的根“/”URL.
Host = "Host" ":" host [ ":" port ] ; 3.2.2节
一个没有任何追踪端口信息的“主机”暗示使用请求服务的缺省端口(例如,“80”对应HTTP URL)。例如,源服务器上对<http://www.w3.org/pub/WWW/>的请求将完全包括:
GET /pub/WWW/ HTTP/1.1
Host: www.w3.org
在所有的HTTP/1.1请求信息中客户机必须(MUST)包括Host报头域。如果被请求的URI不包括被请求服务的互联网主机域名,那么Host报头域必须(MUST)是空值。
一个HTTP/1.1的代理服务器必须(MUST)确保它向前传递的任何报文确实包括代理服务器可识别的请求服务的适当的Host报头域。所有基于互联网的HTTP/1.1服务器必须(MUST)对任何缺少Host报头域的HTTP/1.1请求报文响应状态代码400(坏的请求)。见5.2和19.6.1.1节和主机关联的其他请求。
14。24 If-Match
If-Match报头域是用一种方法使得它是有条件的。由以前从源获得的一个或更多实体的客户机能够校验那些实体中的一个现在包括在If-Match报头域的一系列联合的实体标签。实体标签在3.11节定义。这种特征的目的是允许用对报头进行最少量处理的方法对高速缓存信息进行有效的修正。它也用来在更新请求时防止源的错误版本无意识的修改。作为一种特殊情况,“*”匹配任何现有源的实体。
If-Match = "If-Match" ":" ( "*" | 1#entity-tag )
如果任何一个实体标签匹配在对类似GET请求的响应中返回的实体的实体标签,或者如果给出“*”以及对那个源任何现存的实体,那么服务器可以(MAY)在执行请求的方法就好像If-Match报头域不存在一样。
服务器必须(MUST)用功能强大的比较函数来比较在If-Match中的实体标签。
如果没有一个实体标签匹配,或者给出了“*”而没有现有的实体,服务器一定不要(MUST NOT)执行请求的方法,并且返回412响应(预处理失败)。当客户机希望防止更新的方法,例如PUT,修改自从客户机上一次找到以后已经改变的源的时候,这种行为是很有用的。
如果请求将会导致除2XX或412以外的任何状态,没有If-Match报头域,那么If-Match报头必须(MUST)被忽略。
"If-Match: *" 的含义是当源服务器(或高速缓存,很可能使用Vary机制,见14.44节)选择的表示法存在时,方法就应该被执行,并且当表示法不存在时,一定不要(MUST NOT)执行。
想要更新源的请求(例如PUT)可以(MAY)包括If-Match报头域来发出信号如果相应于If-Match值的实体(单个实体标签)不再是源的表示法请求方法应订不能(MUST NOT)得到应用。这允许用户表明如果源已经改变而他们不知道的话他们不希望请求成功。
例如:
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请求报头域被用来使得如果请求的变量自从这个域说明的时间以来没有被修改过,实体将不会从服务器返回;相反的,将返回304响应(没有修改的)而没有任何报文实体。
If-Modified-Since = "If-Modified-Since" ":" HTTP-date
这个域的一个例子是:
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
有If-Modified-Since报头没有Range报头的GET方法请求只有如果自从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报头区标明相应实体
标签而流通。此特征的目的是达到最小代价的高效缓存信息刷新。它也可以防止一
些算法无意中修改客户认为不存在而实际存在的资源。
作为特殊情况,特征值“*”匹配资源的任何当前实体。
If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )
如果任何实体标签与将被用来回复GET请求的实体匹配,或给出“*”且针对该资源的实体存在,则服务器不能执行被请求的算法,除非由于资源的修改数据不能匹配If-Modified-Since报头区提供的相应内容而被要求那样做。与之相反,如果请求算法是GET或HEAD,服务器应回复304响应,包含有匹配实体的缓存相关报头区。所有其它算法,服务器必须回复412状态码。
13.3节说明怎样判断两实体标签匹配.弱比较函数只能用于GET或HEAD请求。
如果没有实体标签匹配,则服务器将执行被请求的算法只当If-None-Match报头区不存在,但必须同时也忽略请求中的If-Modified-Since报头区。即,如果没有实体标签匹配则不能回复304响应。
如果没有If-None-Match报头区的请求最终回复非2xx及304响应,则If-None-Match报头一定要被忽略。(见13.3.4)
"If-None-Match: *"的意思是:当源服务器选择的代表(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(If-Unmodified-Since 和If-Match两者兼用或只取其一)中使用范围请求报头域。然而,若由于实体已被修改而导致条件不满足,客户机就需要再次发出获取当前整个实体正文的请求。
If-Range允许客户机“拦截”第二次请求。 简要说来,其含义为“若实体未改变,请发送我缺少的部分给我;否则,发给我整个实体”。
若客户机不具备实体的实体标签,但有上次修改日期,它可以在If-Range报头中使用此日期(服务器通过检查一两个字符即可区分合法HTTP日期与任意形式的实体标签)。If-Range报头应只和范围报头一起使用,且在请求不含范围报头或服务器不支持亚范围操作时必须被忽略。
若If-Range报头中给出的实体标签于实体当前的实体标签相吻合,则服务器应使用206(部分内容)应答来指明实体的亚范围。 若实体标签不相符,服务器应使用200(OK)应答返回整个实体。
14.28 If-Unmodified-Since
If-Unmodified-Since请求报头域用来使某方法变为条件的。若请求的资源在此域中指定的时间之后即未被修改,则服务器应按If-Unmodified-Since报头不存在的方式执行所请求的操作。
若请求的变量在给定时间之后已被修改,则服务器不得执行所请求的操作,且必须返回412(前提条件不满足)应答。
If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-日期
此域的应用实例:
If-Unmodified-Since: 星期六, 1994年10月29日 19:43:31 格林威治时间
如果正常情况下(即没有If-Unmodified-Since报头时),请求会得到除了2xx与412状态的结果,则If-Unmodified-Since报头应被忽略。
若指定的日期无效,本域亦被忽略。
本说明未定义一个既有If-Unmodified-Since报头,又有If-None-Match 或If-Modified-Since报头的请求的结果。
14.29 上次修改
上次修改实体报头域指明原服务器认为的变量上次被修改的日期和时间。
上次修改="上次修改"":"HTTP-日期
应用示例如下:
上次修改: 星期二, 1994年11月15日, 12:45:26 格林威治时间
此报头域的确切含义取决于原服务器的处理和原资源的性质。 对文件而言,它可能仅仅指示文件系统上次修改时间。 对动态包含各个部分的实体而言,它可能指的是其组成部分的上次修改值中最近的一个。 对数据库网关而言,它可能就是记录的上次更新时间戳。 对虚拟对象而言,它可能是上次内部状态改变的时间。
原服务器不得发送迟于服务器生成此报文时间的上次修改日期。 在这种情况下资源的上次修改意味着将来的某一时刻,服务器必须以报文生成日期取代之。
原服务器应尽量在靠近其生成应答日期值的时刻获取上次修改值。 这样接收者可以更准确的估计实体的修改时间,当实体在应答生成时间的前后有所改动时尤为如此。
HTTP/1。1服务器应尽可能发送"上次修改"信息。
14.30 位置(Location)
除了应用于关于请求完成或新资源确认的请求,URI位置响应报头域还用于使收件人重发到某个地址.对201(Created)响应,位置是请求建立的新资源.对3xx响应.Location应当指出服务器的关于资源自动重定向的首选URI.该域的值由单个绝对的URI组成.
Location = "Location" ":" absoluteURI
例如:
Location: http://www.w3.org/pub/WWW/People.html
注: Content-Location报头域(14.14节)不同于Location, Content-Location定义了请求附属实体的源地址.因此响应有可能既有Location报头域,也有Content-Location报头域.看13.10节一些方法的缓存需求.
14.31 最大前向(Max-Forwards)
最大前向请求头域提供一种带有TRACE(9.8节)和OPTION(9.2节)方法的机制以限制那些能够向下一个本地服务器转送请求的代理或网关.当客户尝试跟踪一个似乎失败或在中间链循环的请求链时,这一点十分有用.
Max-Forwards = "Max-Forwards" ":" 1*DIGIT
最大前向值是一个表示剩余的请求转送时间的十进制整数.
每个代理或网关接受包含最大前向头域的TRACE或OPTION请求时必须在转送请求前检查和修正它的值.如果接收到的值是zero(0),接收者一定不能转送这个请求;相反,它必须像最终接收者一样响应.如果接收到的最大前向值大于0,转送的消息必须包含一个经过修正的最大前向域,其域值减一.
对本说明书定义的所有其它方法以及任何没有明确将它归作定义的一部分的扩展方法,最大前向头域可以被忽略.
14.32 实用(Pragma)
实用常规头域被用来包含特殊的执行指令,它可沿请求/接受链应用于任何接收端。从协议的观点所有的实用指示了详细的可选行为;不管怎样,一些系统可以被要求那些行为与指示的相一致。
Pragma ="pargma"":"1#pragma-directive
Pragma-directive ="no-cache"|extension-pragma
Extension-pragma =token["="(token|quoted-dtring)]
当一个非缓存的指示出现在请求的消息中,应用程序必须跟随这个原服务器的请求,甚至这是个正在被请求的缓存的复制。这个实用的指示的语义和非缓存指示(14。9节)一致,他的定义是为了和http/1.0保持一致。当一个非缓存的请求被送到一个不知道是否支持http/1.1的服务器,客户端必须包括两个头域。
使用指示必须被代理和网关应用程序过,不管对于那些应用程序有没有意义。因为这些指令可以被请求/应答链上的所有接受者应用。不可能为一个特殊的接收者定义一个实用,然而,实用指示必须被不相关的接收者忽略。
HTTP/1.1高速缓冲器必须把"Pragma:no_cache"当作客户端发送了"cache_control:no-cache".在http中不会有新的指令定义。
注意:因为Pragma: no-cache的意思并没有作为应答的头域在十几种定义,他不提供可靠的应答中Cache-Control: no-cache的替代。
14.33 代理认证(Proxy-Authenticate)
代理认证的响应头域必须是407响应的一部分.这个域的值由表示认证方案的复杂问题和应用于这个请求URI的代理的参数组成.
Proxy-Authenticate = "Proxy-Authenticate" ":" 1#challenge
HTTP访问认证进程如"HTTP认证:基本和分类访问认证"[43]所描述.与www认证不同,代理认证的头域仅仅应用于当前连接,不应该转到下游客户.但是,中间代理可能需要向下游客户请求获得它自己的证书,有时候看起来这好像代理在转送代理认证头域.
14.34 代理授权
代理授权的请求头域允许客户将它自己(或的使用者)看作和需要认证的代理一样.代理授权的域值由包含用户代理对代理服务器的授权信息和正在被请求的资源界组成. [译者注]realm:数据库中的一种逻辑子域,它包含了有约定的数据的聚集的全部(具体)值.
Proxy-Authorization = "Proxy-Authorization" ":" credentials
HTTP访问认证进程如"HTTP认证:基本和分类访问认证"[43]所描述.与授权不同,代理授权的头域仅仅应用于下一个需要认证的外地代理,用的是代理认证域.当多个代理在链中使用时,代理授权的头域由第一个期待收到证书的外地代理消耗.代理可以从客户请求向下一个代理转发证书,如果那是代理协同认证给定请求的机制.
14.35 范围
14.35.1 字节范围
既然所有的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值给出了这个范围里最后一个字节的偏移量;也就是说,确定的字节位置包含在内.字节偏移量初始值为零.如果存在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.
通过选择last-byte-pos,客户能够限制检索字节的数量而不必知道实体的大小.
suffix-byte-range-spec用来表示实体正文的后缀,其长度由后缀长度值给出.(也就是说,这种形式规定了实体正文的最后N个字节.)如果实体短于确定的后缀长度,则使用整个实体正文.
如果一个句法正确的byte-range-set至少包括一个这样的byte-range-spec:它的first-byte-pos比实体正文的当前长度小,或至少包括一个后缀长度非零的suffix-byte-range-spec,那么byte-range-set是可以满足的.否则是不可满足的.
如果byte-range-set是不可满足的,服务器应该返回一个带有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 范围检索请求
HTTP检索请求使用有条件或无条件GET方法,可以利用范围请求头来请求实体的一个或更多子范围而不是整个实体,范围请求头部应用于作为请求结果返回的实体.
Range = "Range" ":" ranges-specifier
服务器可以忽落范围头.但是,HTTP/1.1源服务器和中间高速缓存应该在可能的时候支持字节范围,既然范围支持部分失败传输的有效恢复,并且支持对大实体的部分检索.
如果服务器支持范围头和确定的范围,或范围对实体是合适的:
-- 如果GET是以别的方式成功的,无条件GET里范围头的存在修改返回的东西.换句话说,响应携带的是状态代码206(部分内容)而不是200(好).
-- 如果GET以别的方式成功且条件为真,有条件GET(一种使用If-Modified-Since和If-None-Match二者之一或全部,或者If-Unmodified-Since和If-Match二者之一或全部的请求)里范围头的存在修改返回的东西.它并不影响返回的304(未修改)响应,如果条件为假.
某些情形下,使用Range header(范围头)辅以If-Range header(假设范围头)可能更合适.
如果支持范围的代理收到范围请求,将请求转发到本地服务器,以及收到回复的整个实体,它应该只把请求的范围返回给客户.它应该将接收到的整个响应存储在高速缓存中,如果这跟它的高速缓存分配方针一致的话.
14.36 参考者(Referer)
参考者(Referer)请求头域允许客户确定获得请求URI的资源地址(URI)-为了服务器的利益.Referer请求头允许服务器生成关于到资源的反向连接(back-link)的列表,为了兴趣,记录,优化的高速缓存等等.它也允许追踪过时的或错误类型的连接(link)以便维护.如果请求URI是从一个没有自己的URI的源获得的,如从使用者键盘的输入,那么一定不要发送Referer域.
Referer = "Referer" ":" ( absoluteURI | relativeURI )
例如:
Referer: http://www.w3.org/hypertext/DataSources/Overview.html
如果域值是相对URI,它应该理解为与请求URI相关.URI一定不能包括片断.安全考虑请参看15.1.3节.
14.37 稍后重试
稍后重试应答报头域可以和503(服务不可达)应答一起使用,以指示服务对于发出请求的客户机而言预计有多久不可达。本域也可与任何3xx(重新定向)应答一起用于指示用户代理在重定向请求前被要求等待的最小时间。本域的值可以是应答时间只有的HTTP-日期或整值的秒数(十进制)。
稍后重试=“稍后重试”“:”(HTTP-日期|delta-秒)
应用的例子有二:
稍后重试:星期五,1999年12月31 23:59:59 格林威治时间
稍后重试:120
在后一例中,延迟时间为2分钟。
14.38 服务器
服务器应答报头域包含了原服务器用于处理请求的软件信息。 此域可包含多个产品标记(3。8节),以及鉴别服务器与其他重要亚产品的注释。产品标记按它们对于鉴别应用程序的重要性的顺序排列。
服务器=“服务器”:“1*(产品|注释)
例:
服务器:CERN/3。0 libwww/2.17
若应答是通过代理服务器转发的,则代理程序不得修改服务器应答报头域。作为替代,它应添入路由(Via)报头(如14。45节定义)。
注:揭示特定的软件版本可能会使服务器易于受到那些针对已知的软件安全漏洞的攻击。 建议服务器实现者将此域作为可设置项。
14.39 TE
TE请求报头域指明了它愿意从应答中接收哪种扩展传输编码以及是否愿接收成块传输-代码中的trailer域。其值可由关键字“trailers”,由逗号隔开的含可选接收参数的扩展传输-代码列表组成。
TE = "TE" ":" #( t-codings )
t-codings = "trailers" | (传输-扩展 [接收-参数 ] )
关键字“trailers”的存在表明客户机愿意接收如3。6。1节中定义的成块传输-代码中的trailer域。 此关键字为传输-代码值而保留,但它本身不代表一种传输-代码。
应用举例:
TE: deflate
TE:
TE: trailers, deflate;q=0.5
TE报头域仅适用于立即连接。所以无论何时HTTP/1。1消息中有TE,连接报头域(参见14。10节)中就必须提供关键字。
服务器利用下述规则,依据TE域来裁定传输-代码是否可被接受:
如果关键字“trailers”在列,则成块传输-代码总被接受。 客户机已代表它自己与下游客户机指出愿接受成块应答中的trailer域。 这意味着,可能的话,客户机正申明要么所有下游客户机都愿接收转发应答中的trailer域,要么它将试图代表下游接收者暂存应答。
注:HTTP/1。1并未定义任何限制块状应答大小,以保证客户机能够暂存整个应答的方法,
若被检验的传输-代码在TE域中有列出,它就可被接受,除非伴有qvalue为0值(如3。9节定义, qvalue 的0值表示“不可接受”)。
若多个传输-代码都是可接受的,则可接受传输-代码中qvalue值最高者优先。 “成块”传输-代码的qvalue值总是1。
若TE报头域为空,或没有TE报头域,则仅有的传输-代码是“成块”。 无传输-代码的报文总是可接受的。
14.40 追踪者(Trailer)
Trailer常规域值指示在trailer消息中有给定的头域设置,此消息用成块传输编码编码的。
Trailer = "Trailer" ":" 1#field-name
一个http/1.1消息使用成块传输编码时要包括一个trailer头域,且其不能为空。这样才能让接收者知道trailer中期望得到哪个头域。
如果没有trailer头域存在,trailer不能包括任何头域。在成块传输编码中用到的trailer域的限制看3。6。1节。
Trailer头域中列出的消息头域必须不能包括下面的头域:
传输编码
内容长度
Trailer
14.41 传输-编码
传输-编码常规头域指出为了在发送者和接收者之间安全的传输而应用了什么样类型的转换。它不同于内容代码,传输代码是消息而不是实体的属性。
Transfer-Encoding = "Transfer-Encoding" ":" 1#transfer-coding
传输代码在3。6节中被定义了。一个例子是:
Transfer-Encoding: chunked
如果一个实体应用了多种编码,传输代码必须顺序列出应用的编码。关于代码参数的额外信息有其他的实体头域指定。许多旧的http/1.0应用程序不懂传输编码头。
14.42 升级(Upgrade)
升级头域允许客户端指定它支持什么样的附加传输协议并想使用如果服务器发现选择这种协议是恰当的话。服务器必须用101(选择协议)升级头域来指示要选择那个协议。
Upgrade = "Upgrade" ":" 1#product
举个例子:
Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
升级头域被用来规定一种简单的机制从http/q.q过渡到其他不同性质的协议。它允许客户发出它期望使用另一个协议,比如说稍后的更高版本的http协议,甚至当前的请求已经使用了http/1.1协议。通过允许客户端发出一个用更普通的协议的请求来指示服务器它想用更好的协议(这儿得更好的由服务器决定,可能是按照方法的自然性或被请求的资源)它减轻了两个不同性质的协议之间传输的困难。
升级头域只被用来从存在的传输层协议之上选择应用层协议。升级不能被用来强迫一个协议的改变;它的接受和使用是由服务器自由决定的。协议变换后应用层的通讯的性能和本性是由新选择的协议决定的,虽然改变协议以后的第一个动作是包含升级头域的原来http请求的应答。
升级头域只应用于直接连接,因此无论升级出现在http/1.1消息的是什么时候,升级的关键字都必须应用于连接的头域中。
升级头域不能被用来指示选择不同连接中的协议。为这个目的,使用301,302,303重定位应答更合适。
这个规范着定义了http协议的名字,它被在3。1节的http版本规则中定义的超文本传输协议家族使用。任何一个记号都可被用来做协议名字,然而,只有当客户端和服务器用同一个协议关联时才有用。
14.43 用户代理
用户代理请求头包括发出请求的用户代理的信息。这是为了统计学的目的,跟踪违反协议,为了因特定用户代理的限制制作对应响应而自动识别用户代理。用户代理必须在请求中包括这个域。这个域包括多个指明代理和构成代理的重要组件的产品标记和元素。按惯例,这些产品标记按指明应用程序的重要性的顺序排列。
User-Agent = "User-Agent" ":" 1*( product | comment )
例子:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
14.44 更正(Vary)
更正头域是在响应开始的时候变更完全接收的请求头域设置,而不管高速缓存是否允许用响应回复后续的请求。对于非高速缓存或者旧的响应,更正头域值建议用户代理用来选择请求的标准。
一个为“*”的更正域意味着高速缓存不能根据后来的请求的请求头判断而不管这个请求是否是恰当请求。高速缓存对更正头域的用法间13。6节。
Vary = "Vary" ":" ( "*" | 1#field-name )
一个HTTP/1.1的服务器的任何能缓存的响应必须包括一个更正头域,这是服务器驱动商议的科目。这样做高速缓存呢能恰当的解释下一个关于那个资源的请求同时通知用户代理需要对那个资源商议。一个服务器可以在非缓存的响应中包括更正头域,这是服务器驱动商议的科目,既然这可以提供用户代理在响应的时候响应的变化的有用信息。
一个更正头域由一张头域的表组成,响应按一个选择的法则从其中选出,这个法则在选择最恰当的响应的时候只考虑列出的请求头域。一个高速缓存会假定下一个请求的选择会和列出的头域的值一样。
此给定头域的名字不受这个说明书定义的标准请求头域的规范所限制。域名是对缓存不敏感的。
一个值为没有定义的“*”表明对请求头没有限制(例如,网络客户端的地址),作为选择响应表述的规则。“*”值一定不能由代理服务器产生;它只可以由源服务器产生。
14.45 路由(Via)
路有常规头域必须被网关和代理服务起来指示中间的协议和关于请求的使用者和服务器之间的接收者及应答的原服务器和客户端的接收者。它类似于RFC 822[9]的接收域,被用来跟踪消息的去向,避免请求循环,及识别沿请求/应答链个发送者协议的性能。
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
接收协议指出沿请求/应答链的每一段后被服务器或客户端接收到的消息的版本。接收协议的版本被加到路由域值中,因此对于所有的接收者来说以前的所有应用程序的协议能力的信息都保留了。
协议的名字是可以选择的,只要也只有它是HTTP。接收到的域一般是通常的主机和接收服务器或客户端的可选择的端口,然而,如果真实的主机考虑信息的敏感性,它可能会用假名代替,如果没有指明端口,它被假设成接收协议的默认端口。
多重路由域值应答传递消息中的每一个代理或网关。每一个接收者必须添加上自己的信息,这样结果依照传递的应用程序的顺序范围。
路由头域可能会使用注释来识别接收的代理或网关的软件,用户代理和服务器头域也是如此。然而,所有的路由头域中的注释是可选的,它可以被任何接收的代理服务器删掉。
举个例子,一个http/1.0的用户代理发送一个叫fred的请求消息给国内的代理,它使用http/1.1来传递请求给在nowhere.com的公共代理,它把这个请求传递给在wwwlics.uci.edu的原服务器。这个请求被www.ics.uci.edu收到的时候应该有以下的路由头域:
Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
代理和网关被作为一个通过防火墙的入口,在默认情况下,它不能传递防火墙内的主机的名字和端口。这个信息只有在明确允许下才能传播。如果不允许的话,任何在防火墙后面的主机将被用假名代替。
对于那些要求很强的隐藏内部结构的需求的机构,一个代理可以把有顺序的路由头域和同样的接收协议值组合在单个的条目中。举个例子:
Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy
可能退化为
Via: 1.0 ricky, 1.1 mertz, 1.0 lucy
应用程序不能把多个实体组合在一起除非他们都在同一个组织的控制之下同时主机已经用假名代替了。应用程序不能把不同接收协议值的实体组合在一起。
14.46 警告(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 <">
警告文本必须使用自然语言,对于接收应答的使用人来说它基本上时可理解的。这个决定可以基于任何可利用的知识,比如说缓存或使用者的位置,请求中的接收语言域,应答中的内容语言域,等等。默认的语言是英语,默认的属性设置是ISO-8859-1。
如果属性设置不是使用ISO-8859-1,它必须按RFC 2047[14]中描述的在警告文本中指明。
警告头一般能被应用于任何的消息,然而一些特殊的警告代码对于高速缓存是特殊的,只能应用于应答消息。新的警告头必须加到任何存在的警告头的后面。一个高速缓存一定不能删掉它接收到的消息的警告头域。然而,如果高速缓存成功的使高速缓存条目有效,它能把符合条目的警告头都删掉除了那些特殊的警告代码。它必须马上把它接收到的警告头域加到确认应答中。用其他华说,警告头实那些能附加于最近大多数应答的应答。
当多个警告头附加于一个应答,用户代理必须按应答中显示的顺序尽可能多的通知使用者。如果不能通知所有警告的拥护,用户代理必须按这些HEURISTICS运作:
-出现在应答中前面的警告从那些出现在后面手中接过优先权
-符合用户首选性质设置的警告从其它使用相同的警告代码和警告代理但在其他性质设置的警告手中接过优先权。
产生多个警告头的系统必须按用户代理的行为排列它们。
对于注意警告的高速缓存的行为的要求在13。1。2节中规定。
这是通常定义的警告代码的列表,每一个有推荐的英语的警告文本和它意思的描述。
110 应答迟缓
当回复应答迟缓的时候应用
111 重新连接失败
当试图重新连接失败高速缓存返回一个迟缓应答,原因是服务器不可达。
112 分离操作
当高速缓存要有意从其它的网络中分离一段时间。
113 探索终止
高速缓存要选择保鲜的。生存期大于24小时,应答年龄大于24小时。
199 混合警告
警告文本可以包括只能给使用人看的信息。一个系统收到这样的警告必须给使用者看而不能自动处理。
214 转变被应用了
如果中间高速缓存或代理的任何应答的内容编码(如在内容编码头中指定的)或媒体类型(如在内容类型头指定的)或实体正文被改变了则这个警告必须被添加上去,除非这个警告代码已经出现在应答中。
299 持久混合警告
警告文本可以包括只能给使用人看的信息。一个系统收到这样的警告一定不能自动处理。
如果一个实现用http/1.0或更低的版本发送了一个又一个或多个警告头的消息,发送者必须包括和应答中匹配的每一个警告值和警告数据。
如果一个实现收到一条报文,在这条报文中警告值包括一个警告数据,这个警告数据和行营中的数据值不同,那么这个警告值必须在储藏,传递或使用以前从这条消息中删掉。这可防止错误储存警告头域)如果因为这个原因所有的警告制度被删掉了,则这个警告头也应该被删掉。
14.47 WWW-认证
401(未授权的)应答报文中必须含有WWW-认证应答报头域。 域值至少包括一个指明了可应用于请求-URI的认证方案与参数的挑战(challenge).
WWW-认证=“WWW-认证”“:”1#挑战
HTTP访问认证过程在“HTTP认证:基本与摘要访问认证”[43]中有所描述。
建议用户代理尤其谨慎地解析WWW-认证域值,因为它可能含多个挑战,或在有多个WWW-认证报头域的情况下挑战内容本身即含有由逗号隔开的认证参数列表。
15.安全考虑
这一部分是用来提醒程序开发人员,信息提供者,和HTTP/1.1中的安全限制的用户这篇文档所叙述的事情。虽然这个讨论为减少安全风险确实提供了一些建议,但是它并不包括所透露问题的最终解决方案。
15.1 个人信息
HTTP的客户机经常对大量的个人信息是敏感的(例如用户的名字,域,邮件地址,口令,密匙等。),并且应当(SHOULD)非常小心地防止这些信息无意识地通过HTTP泄露到其他的主机。我们非常强烈地建议应该提供给用户一个方便的界面来控制这种信息的分发,并且设计者和使用者在这方面应该特别注意。历史告诉我们在这方面的错误经常引起严重的安全和/或者机要问题并导致出现对使用者的公司非常不利的公开的情况。
15.1.1服务器日志信息的滥用
服务器是处在存储个人数据的位置上,这些数据是关于用户的请求的,这些请求可以识别他们的阅读习惯或者感兴趣的主题。自然这种信息明显是机要的并且在某些国家对它的处理是受限制的。使用HTTP协议提供数据的人们有责任确保这样的材料不会在没有得到任何公开结果确认的人允许的情况下被散布出去。
15.1.2敏感信息的传输
就像任何种类的数据传输协议一样,HTTP不能控制被传输数据的内容,也没有任何一种区分的方法来决定在任何给定请求的上下文中某个特别的信息片段的敏感性。因此,应用程序应该(SHOULD)提供给发布信息的人尽可能多的对这个信息的控制能力。四个报头域是值得在这段文字中特别提到的:Server,Via,Referer和From。
暴露服务器详细的软件版本信息可能会导致服务器因为已知有安全漏洞的软件而变得更易受到攻击。开发人员应该(SHOULD)使Server报头域是一个可配置的选项。
作为通过一个网络防火墙的入口的代理服务器应该(SHOULD)对关于确认防火墙后面的主机的报头信息的传输采取特别的防范。特别的,它们应当移走或者用清洁的版本代替,Via域在放火墙后面产生。
Referer报头允许学习的阅读模式并且可以进行反向连接。虽然它非常有用,但是如果用户的资料没有从Referer包括的信息中分离出来的话它的能力就可能会被滥用。甚至当信息已经被移开,Referer报头还是可能指示出一个不适于公开的私人文档的URI。
在From域发送的信息可能和用户的个人利益或者他们站点的安全政策相抵触,因此用户如果不能使之失效,对其授权,和修改域的内容的话,它就不应该(SHOULD NOT)被传输。用户必须(MUST)能够按用户的选择或者应用程序的缺省配置设置这个域的内容。
虽然并不是必须的,我们建议向用户提供一个可以选择允许或者禁止From和Referer信息的发送的方便捆绑界面。
用户代理(14.43节)或者服务器(14.38节)的报头域有时候会被用来判断某个特定的客户机或者服务器有一个可以被利用的特别的安全漏洞。不幸的是同样的信息经常被用作其它有价值的目的因为HTTP现在没有更好的机制。
15.1.3 URI中敏感信息的编码
因为一个连接的源地址可能是机要的信息或者可能会暴露另外一个机要的信息源,所以强烈推荐用户能够选择是否发送Referer域。例如,一个浏览器的用户能够有一个捆绑的选择是公开/匿名浏览,这将会分别允许/禁止Referer和From信息的发送。
如果目标页使用安全的协议传输的话,在一个(不安全)HTTP请求中客户机不应该(SHOULD NOT)包括一个Referer报头域。
使用HTTP协议的服务提供者不应该(SHOULD NOT)使用基于使敏感数据屈服的形式的GET命令,因为这将导致在Request-URI中编码这个数据。许多现有的服务器,代理服务器,和用户代理将把请求URI日志记录在某个第三方可以看见的地方。服务器可以用基于屈服形式的POST代替。
15.1.4连接到Accept报头的机要问题
接受request-header可能暴露关于用户可以进入的所有服务器的信息。特别的Accept-language报头可能暴露用户个人的民族,因为对特殊语言的理解对特殊的同文化的民族的成员经常有很强的相关性。提供在每个请求中配置发送的Accept-language报头的选项的用户代理被坚定的鼓励让配置过程包括让用户明白有关机要泄露的信息。
对于用户代理来说一种限制机要泄露的方法是在缺省的情况下忽略发送Accept-language包头,并且如果通过寻找任何由服务器发出的变化的response-header域,发现这样的发送能够提高服务的质量,就询问用户是否向服务器发送Accept-language报头。
在每个request中发送的为用户精心制作的accept报头域,特别如果这些包括质量价值,能够被服务器用作相关地可信赖的和长久的用户标识符。这样的用户标识符将会允许内容提供者进行单击轨迹跟踪以及允许合作的内容提供者匹配交叉服务器单击轨迹或者形成单个用户的屈从。注意对于许多并不在代理服务器后面的用户,运行用户代理的主机的网络地址也将作为长久用户的标识符。在代理服务器被用作增强保密的环境里,用户代理在提供给终端用户accept报头配置选项上应该是保守的。作为一个保密的极端措施,代理服务器应该在转发请求信息的时候过滤accept报头。提供高度报头配置能力的一般用途的用户代理应该(SHOULD)警告用户可能涉及的机要泄漏。
15.2 基于文件和路径名称的攻击
实现HTTP的原服务器应该(SHOULD)小心地限制由HTTP请求返回的文档仅仅是那些服务器管理员授权设置的。如果HTTP服务器直接把HTTP URIs翻译成文件的系统名称,服务器必须(MUST)特别注意不要提供没有授权发布给HTTP客户的文件。例如UNIX,微软Windows,和其它操作系统使用".."作为指示当前目录的上一层的路径的一部分。在这样一个系统中,如果不允许通过HTTP服务器访问那些除授权允许访问以外的资源的话,HTTP服务器就必须(MUST)禁止在Request-URI中任何这样的结构。同样的,必须(MUST)保护认为仅仅涉及服务器内部的文件(例如访问控制文件,配置文件,和剧本代码)不要被不适当的获取,因为它们可能包含敏感信息。经验表明在HTTP服务器这样的使用中次要的bug已经转变为威胁安全的风险。
15.3 DNS欺骗
客户使用HTTP严重依赖于域名服务,因此一般倾向基于故意不相关的IP地址和DNS名称的安全攻击。客户需要在假定一个IP号/DNS名称关联继续合法时谨慎。
特别的,HTTP客户对于一个IP号/DNS名称关联的确认应该(SHOULD)依靠对它们名字的解析,而不是存在高速缓存中以前主机名解析查找的结果。在适当的时候并且他们应该(SHOULD)被设置成这样做的时候,许多论坛已经能够在本地用高速缓存存储主机名。只有当域名服务器报告的TTL(现在时刻)信息使高速缓存里的信息很可能仍然是有用的时候,对这些高速缓存的查询才是适当的。
如果HTTP客户为了达到提高性能的目的把查询到的主机名结果存在高速缓存中,他们必须(MUST)遵守域名服务器报告的TTL信息。
如果HTTP客户不遵守这个规则,在一个以前访问过的服务器的IP地址改变的时候他们就会被欺骗。在网络重新编号被认为变得日益普遍的时候,这种形式的攻击的可能性将会增大。遵守这个必要条件将会因此减少这种潜在的安全隐患。
这个必要条件也改进了客户机对使用同样域名的镜像服务器的平衡加载行为并且减少了用户访问使用这种策略的站点经历失败的可能性。
15.4 Location(位置)报头和欺骗
如果单个的服务器支持互不信任的多个组织,那么它必须(MUST)检查在自称的某个组织控制下产生的应答信息中Location和Content-Location报头的值以确认他们没有企图使他们没有权限的资源无效。
15.5 内容倾向问题(Content-Disposition Issues)
RFC 1806 [35],在HTTP中经常使用的Content-Disposition(见19.5.1节)报头就源于此,有许多非常认真的安全考虑。Content-Disposition并不是HTTP标准版本中的一部分,但自从它被广泛应用以来,我们正在证明它对使用者的价值和风险。详细资料见RFC 2183 [49](对RFC 1806的升级)。
15.6 鉴定证书和空闲的客户机
现有的HTTP客户机和用户代理有代表性地不确定地保留鉴定信息。HTTP/1.1没有提供一个从服务器到直接的客户机的方法来丢弃这些保存在高速缓存里的证书。这是一个重大的需要对HTTP做进一步扩展的的缺点。在高速缓存里的证书可能干扰应用程序的安全模式的情况包括但不只限于:
--客户机已经空闲了很长时间,然后服务器可能希望引起客户机再一次出示用户的证书。
--应用程序包括了一个进程中断的指令(例如在一页上有"logout"或者"commit"的按钮),在此之后应用程序的服务器方面"知道"客户机没有进一步的理由保留证书。
这是当前分散考虑的情况下。这个问题的各部分有许多的工作区,我们鼓励在屏保程序中使用密码保护,空闲暂停,以及其它在这个问题中减轻固有安全问题的方法。特别的,在高速缓存中保存证书的用户代理被鼓励提供一个在用户控制下丢弃保存在高速缓存中的证书的可以容易访问的机制。
15.7 代理服务器和高速缓存
HTTP代理是中间人,并且扮演一个"中间者"攻击的目标。代理运行系统的妥协可能导致严重的安全和保密问题。代理有权访问与安全相关的信息,关于个人用户和组织的私人信息,属于用户和内容提供者的所有权信息。一个不安全的代理,或者一个使用或配置没有注意安全和保密考虑的代理,可能被用作广泛的潜在攻击的代理。
代理服务器的管理员应当保护代理服务器上运行的系统就像他们保护包括或者传递敏感信息的任何系统一样。特别的,在代理上聚集的日志信息经常包括高度敏感的个人信息,和/或者关于组织的信息。日志信息应该被小心地保护,并且对发展的和接下来的使用持适当的指导方针。(15.1.1节)
高速缓存代理给其它潜在的攻击提供了机会,因为高速缓存的内容对于恶意利用是一个有吸引力的目标。因为当一个HTTP请求完成以后高速缓存的内容仍然存在,对高速缓存的攻击能揭示很早以前用户就认为已经从网络上移走的信息。因此,高速缓存的内容应该当作敏感信息保护。
代理服务器的设计者应当考虑他们的设计和编码的制定,以及他们提供给代理服务器操作人员的配置选项(尤其是缺省配置)所牵涉到的保密和安全问题。
代理服务器的用户必须明白他们并不比管理代理服务器的人更值得信任;HTTP自己不能解决这个问题。
在适当的时候明智的使用密码系统可以提供足够的保护免遭广泛的针对安全和保密的攻击。这种密码系统超出了HTTP/1.1规范的范围。
15.7.1 对代理服务器的拒绝服务攻击
它们是存在的。它们很难防御。研究在继续。当心。
16 感谢(Acknowledgment)
( 略 )
17 参考资料 (Reference)
( 略 )
19 附录
19.1 互联网媒介类型message/http和application/http
这篇文档除了定义HTTP/1.1协议外,还用作互联网媒介类型"message/http"和"application/http"的规范。倘若message/http类型遵守MIME对所有"message"类型关于路径长度和编码的限制,它就可以用来封装单独的HTTP请求和应答信息。application/http类型可以用来封装一个或者更多HTTP请求或应答信息(非混合的)的传输路径。下列是在IANA[17]注册的。
媒介类型名称: message
媒介次类型名称: http
必须参数: 无
可选参数: 版本,信息类型
版本:封装信息的HTTP版本号(例如,"1.1")。如果不存在,版本可以从报文的 第一行确定。
信息类型:信息类型--"request"或者"response"。如果不存在,类型可以从报文的第一行确定。
编码考虑:只有"7bit","8bit",或者"二进制"是允许的。
安全考虑:无
媒介类型名称: application
媒介次类型名称: http
必须参数: 无
可选参数: 版本,信息类型
版本:封装信息的HTTP版本号(例如,"1.1")。如果不存在,版本可以从报文的第一行确定。
信息类型:信息类型--"request"或者"response"。如果不存在,类型可以从报文的第一行确定。
编码考虑:用这种类型封装的HTTP信息是"二进制"的格式;当通过E-mail传递的时候一种合适的内容传输编码是必须的。
安全考虑:无
19.2 互联网媒介类型multipart/byteranges
当一个HTTP206(部分内容)应答信息包括很大范围的内容(对于大范围非重叠的请求的应答),这些是作为一个multipart信息报文传的。这种用途的媒介类型被称作"multipart/byteranges"。
multipart/byteranges媒介类型包括两个或者更多的部分,每一个都有自己内容类型和内容范围的域。必需的分界参数指定了用来分开每个报文部分的分界字符串。
媒介类型名称: multipart
媒介次类型名称: byteranges
必须参数: boundary
可选参数: 无
编码考虑:只有"7bit","8bit",或者"二进制"是允许的。
安全考虑:无
例如:
HTTP/1.1 206部分内容
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--
注解:
1)附加的CRLFs在报文中可以优先于第一个分界字符串。
2)虽然RFC 2046 [40]允许分界字符串被应用,但是一些现有的程序对引用的分界字符串会进行错误的处理。
3)许多浏览器和服务器是按照使用multipart/x-byteranges媒介类型的byteranges规范的早期草案编码的,这个草案总是但不完全和HTTP/1.1中描述的版本兼容。
19.3 宽容的应用程序 (Tolerent Applications)
虽然这篇文档列出了HTTP/1.1这一代消息所必须的元素,但是并不是所有的程序在实现的时候都是正确的。因此我们建议当偏差可以明确解释的时候操作程序对这种偏差应该是宽容的。
客户机在分析状态行的时候应该(SHOULD)是宽容的并且服务器在分析请求行的时候也是(应该)是宽容的。特别的,甚至在域之间只需要一个SP的时候,他们也应该(SHOULD)接收任意数量的SP或者HT字符。
消息报头域的结束行是顺序CRLF。然而我们建议在解析这样的报头的时候,程序应该接受单个的LF作为一行的结束并忽略第一位的CR。
一个实体正文的特征设置应该(SHOULD)分成基本的类并用那个报文中的特征代码来命名,除非无分类实体的优先级比用US-ASCII或ISO-8859-1分类的实体高。见3.7.1和3.4.1。
对关于时间的分析和编码以及时间编码的其它潜在问题的需要的附加规则包括:
--HTTP/1.1客户机和高速缓存应该(SHOULD)假定一个似乎是50多年以后的RFC-850日期实际上是过去的(这有助于解决"2000年"问题)。
一个HTTP/1.1的实现可以(MAY)在内部表现为分析完成时间比正确日期更早,但是一定不要(MUST NOT)在内部表现为分析完成时间比正确日期更晚。
--所有与结束时间有关的计算必须(MUST)用格林尼治时间。本地市区一定不能(MUST NOT)影响年龄或完成时间的计算和比较。
--如果一个HTTP报头不正确的携带了一个格林尼治时间以外其它市区的时间,它必须(MUST)用所有可能中最保守的方法转换成格林尼治时间。
19.4 HTTP实体和RFC 2045实体之间的区别
HTTP/1.1使用了许多为网际邮件(RFC 822 [9])和多用途网际邮件扩充(MIME [7])定义的允许在一个开放的表现多样的环境中用扩展的机制传输实体的结构。不论如何,RFC 2045讨论邮件,HTTP有一些功能部件和RFC 2045中描述的不同。这些不同被小心地挑选出来优化二进制连接的性能,允许使用新媒介类型有更大的灵活性,是时间比较更容易,并且承认一些早期HTTP服务器和客户机的规则。
这个附录描述了HTTP和RFC 2045不同的特殊区域。在严格的MIME环境中的代理服务器和网关应该(SHOULD)意识到这些不同并且在必要的地方提供这种转换。从MIME环境到HTTP的代理服务器和网管也需要意识到这些不同因为一些转换可能是需要的。
19.4.1 MIME版本
HTTP不是一个遵守MIME的协议。然而HTTP/1.1消息可以(MAY)包括单个MIME版本的普通报头域来指出构造这个消息使用的MIME协议的版本。
MIME版本的报头域的使用表明这个消息是完全遵守MIME协议的(RFC 2045[7]定义的)。在输出HTTP消息到严格MIME环境的时候代理服务器/网关有责任确保(在可能的地方)完全匹配。
MIME-Version = "MIME-Version" ":" 1*DIGIT "." 1*DIGIT
在HTTP/1.1用的缺省值是MIME1.0版本。然而,HTTP/1.1消息的分析和语义是由这篇文档而不是MIME规范定义的。
19.4.2 转换到规范形式
RFC 2045 [7]需要网际通信实体在传输以前先转换成规范形式,就像在RFC 2049 [48]第4部分中描述的那样。这篇文档的3.7.1节描述了当用HTTP传输时允许使用的"文本"媒介的次协议的形式。RFC 2046需要关于"文本"类型的内容就像CRLF一样代表行间隔符并禁止在行间隔符序列以外使用CR或者LF。HTTP允许CRLF,单独的CR,和单独的LF来指出在一个消息用HTTP传输的时候文本内容里的行间隔符。
在可能的地方,从HTTP到严格的MIME环境的代理服务器或者网关应该(SHOULD)把本文档3.7.1节描述的文本媒介类型里的所有行间隔符翻译成RFC 2049 CRLF的规范形式。然而注意当出现内容的编码以及HTTP允许使用一些不用八位组的13和10表示CR和LF的特殊设置的实际,就像一些多位组的特殊设置的情况,这可能是复杂的。
使用者应该注意转换将会破坏任何用于原内容的密码校验和,除非原内容已经是规范形式。因此,对任何在HTTP中使用这种校验和的内容建议表示为规范形式。
19.4.3 日期格式的转换
为了简化日期比较的过程HTTP/1.1使用了一种限定的日期格式设置。从其它协议过来的代理服务器河网馆应该(SHOULD)确保消息里现在的任何日期报头域符合一种HTTP/1.1的格式,如果必要的话重写日期。
19.4.4 内容编码的介绍
RFC 2045不包括任何相当于HTTP/1.1的内容编码报头域的概念。既然从HTTP到服从MIME协议的代理和网关作为媒介类型的修正者,它就必须(MUST)改变内容类型报头域的值或者在向前传送消息以前解码实体正文。(一些网际通信内容类型的试验程序已经使用了媒介类型参数";conversions="来实现等效于媒介编码的功能。不管怎样,这个参数不是RFC 2045的一部分。)
19.4.5 无内容传输编码
HTTP不使用RFC 2045的内容传输编码(CTE)。从使用MIME协议到HTTP的代理和网关必须(MUST)在把应答信息传给HTTP客户机之前删除任何非实体CTE("quoted-printable"或"base64")编码。
从HTTP到使用MIME协议的代理和网关有责任确保信息对那个协议来说是用正确的格式和编码在安全的传输,在那"安全传输"的定义是由使用的协议的限制给出的。如果分类将提高用目标协议安全传输的可能,代理或网关就应该(SHOULD)用合适的内容传输编码对数据进行分类。
19.4.6 传输编码的介绍
HTTP/1.1介绍了传输编码报头域(14.41节)。代理/网关必须(MUST)在(经过)使用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规范基础上的地址的实验部署的特征。
许多从SMTP和MIME来的其它的报头,例如内容处理和标题,也经常实现(见RFC 2076 [37])。
19.5.1 内容处理
内容处理应答报头已经被计划为一种如果用户请求把内容存成一个文件原服务器提供一个缺身文件名的方法。这种用法来自RFC 1806 [35]的定义。
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)注意任何在文件名的参数中出现的文件路径信息,这个参数被认为仅仅是一个在这一次申请应用HTTP的参数。文件名应该(SHOULD)只被当作终端的一部分。
如果在应答中用到的报头有程序/八位字节流内容类型,这暗示用户代理不应该现实应答(信息),而直接开始应答...'dialog。
见15.5节内容处理的安全问题。
19.6 和以前版本的兼容
要求和以前的版本的兼容超出了协议规范的范围。然而HTTP/1.1有意设计成很容易支持以前的版本。在写这份规范的时候,值的记录下我们希望商业化的HTTP/1.1服务器是:
--接受HTTP/0.9,1.0和1.1请求的请求行格式;
--懂得HTTP/0.9,1.0或1.1格式中的任何有效请求;
--恰当地用客户机使用的主要版本回复信息。
并且我们希望HTTP/1.1的客户机:
--接受HTTP/1.0和1.1应答的状态行格式;
--懂得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地址的改变
客户机和服务器支持主机请求报头,如果主机的HTTP/1.1请求的请求报头(14.23节)不存在就报告出错,并且接受绝对的URIs(5.1.2节)是本规范定义的最重要的改变。
老的HTTP/1.0客户机假定IP地址和服务器是一对一的关系。没有其它确定的机制区别有意对服务器的请求和直接对IP地址的请求。一旦老的HTTP客户疾步在普遍上文概述的改变将允许互联网支持一个IP地址多重WEB站点,极大简化了对WEB服务器的控制,对一个主机分配多个IP地址已经导致严重的问题。互联网也能从新获得已经分配给用在顶层HTTP URLs只单独为了某个特殊用途的域名的IP地址。给定WEB增加的速度,已经配置的服务器的数量,所有对HTTP的实现(包括对现有HTTP/1.0的程序的升级)正确的实现这些要求是非常重要的:
--客户机和服务器都必须(MUST)支持主机请求报头。
--发送HTTP/1.1请求的客户机必须(MUST)发送主机报头。
--如果HTTP/1.1请求不包括主机请求报头服务器就必须(MUST)报告错误400(Bad Request)。
--服务器必须(MUST)接受完全URIs。
19.6.2 和HTTP/1.0持续连接的兼容
一些客户机和服务器可能希望和一些对以前实现HTTP/1.0持续连接的客户机和服务器兼容。单个持续连接不是缺省的行为的时候,它就被明确的越过。HTTP/1.0持续连接的实验性实现是有缺陷的,在HTTP/1.1中设计新的简单的来纠正这些问题。问题是一些现有的1.0客户机可能发送Keep-Alive给一个不明白这种连接的代理服务器,那么就错误地将它传向下一个接收服务器,它将建立一个Keep-Alive连接并导致一个挂着的HTTP/1.0代理等待关闭的应答。结果是HTTP/1.0客户机必须禁止使用Keep-Alive和代理交谈。
然而,和代理交谈是持续连接最重要的用处,所以禁止很明显是无法接受的。因此,我们需要一些其它的机制来表明渴望持续连接,甚至当和一个忽略Connection的老代理交谈这样使用也是安全的。对HTTP/1. 0消息持续连接是缺省的;我们引入一个新的关键字(Connection: close)来申明非持续。见14.10节。
原始的持续连接HTTP/1.0的形式(the Connection: Keep-Alive and Keep-Alive header)记录在RFC 2068 [33]。
19.6.3 对RFC 2068的改变
这篇规范已经被仔细的审查来纠正关键字的用法和消除它们的歧义;RFC 2068在遵守RFC 2119 [34] 制定的协定方面有很多问题。
澄清哪个错误代码将会使入站服务器失灵(例如DNS失灵)。(10.5.5节)
CREATE有一个特点当一份资料第一次创建的时候他必须发送一个Etag。(10.2.2节)
从规范中删除了内容基:它无法广泛的实现,并且除了精力充沛的扩展机制以外没有简单,安全的方法把它引入。此外它以类似但不一样的方式在MHTML [45] 中使用。
传输译码和消息长度以当使用chunked编码(允许传输自己不划界的编码)需要正确匹配的方式相互影响;正确的弄清如何计算消息长度是重要的。(3.6,4.4,7.2.2,13.5.2,14.13,14.16节)
引入"身份"的内容译码来解决高速缓存中发现的问题。(3.5节)
零值的性质应该表明"我什么都不想要"以允许客户机拒绝请求。(3.9节)
RFC 2145已经澄清了HTTP版本号的使用和解释。需要代理升级他们为了处理在实现HTTP/1.0中发现的问题而要求支持的最高协议版本。(3.1节)
统配符字符设置的引入是为了避免在接受报头的性质设置名称的激增。(14.2节)
HTTP/1.1的高速缓存控制模式中的一种情况被遗漏了;引入s-maxage是为了补充这种情况。(13.4,14.8,14.9,14.9.3节)
高速缓存控制:为了应答而定义的最大生存时间指标是不恰当的。(14.9.3节)
有服务器(尤其是代理)不知道应答的全部长度但仍可以应答比特流请求的情况。我们因此需要一个机制允许内容范围并不指示消息全部长度的比特流。
如果总是回复所有的meta-data范围请求应答将变得非常冗长;通过允许服务器在206应答中只发送必要的报头,这个问题能够避免。(10.2.7,13.5.3,和14.27节)
解决不能满足请求范围的问题;有两种情况:语法问题,以及范围在文档中不存在。需要状态416代码确定这种模糊,它必须指出一个超出文档实际内容的比特请求范围错误。 (10.4.17, 14.16节)
消息传输重写的需要使得明白错误的事先更加困难,因为这里错误的结果对互联网有重大的影响,要应付下列问题:
1.把"HTTP/1.1或以后的版本"变成"HTTP/1.1",这不适当的设置了对未来HTTP/1.x版本实现行为的要求。
2.一般是用户代理而不是客户机应该重发请求这一点要清楚。
3.把对客户机忽略不希望的100(以后)应答,以及对代理转发应答100的要求变为对应答1xx的一般要求。
4.修改一些特殊TCP语言,使得HTTP可以用非TCP传输这一点更清楚。
5.要求原服务器在发送必须的应答100(扩展)之前一定不要(MUST NOT)等待请求主体。
6.如果服务器已经看见一些请求主体,允许,不是必须,它忽略100(扩展)。
7.允许服务器防范拒绝服务攻击和被控制的客户机。
这个变化增加了期待的报头和状态417代码。消息传输要求的修改在8.2,, 10.4.18,8.1.2.2, 13.11, 和14.20节。
代理应该可以在适当的时候增加内容的长度。(13.5.2节)
整理应答403和404之间的混乱。(10.4.4, 10.4.5, 和10.4.11节)
警告可能被错误的隐藏起来,或者没有得到适当的纠正。(13.1.2, 13.2.4, 13.5.2, 13.5.3, 14.9.3, 和14.46节)警告也需要有一个普通的报头,因为PUT或其它命令可能需要它。
传输译码有重要的问题,特别是由于用chunked编码的交互作用。解决的办法是把传输译码变得和内容译码一样快速。这涉及到给传输译码增加一个IANA注册(从内容译码中分离),一个新的报头域(TE)和未来授权跟踪报头。传输编码性能有很主要的好处,所以修改它是值得的。TE也解决其它的,不太明显的,因为跟踪认证,chunked编码和HTTP/1.0客户机之间相互作用而出现的向下兼容的问题。(3.6, 3.6.1, 和14.39节)
补丁,连接,解除连接的方法在这份规范以前的版本中定义过但不能一般的实现。见RFC 2068 [33]。
变化,内容版本,源,连接,URI,公开和内容基报头域在这份规范以前的版本中定义过,但不能一般地实现。见RFC 2068 [33]。