超文本传输协议-HTTP/1.1(修订版) ---译者:孙超进 ---email:[email protected] 说明 本文档规定了互联网社区的标准组协议,并需要讨论和建议以便更加完善。请参考 “互联网官方协议标准”(STD 1)来了解本协议的标准化状态。本协议不限流传发布。 版权声明 Copyright (C) The Internet Society (1999). All Rights Reserved. 摘要 超文本传输协议(HTTP)是一种为分布式,协作式的,超媒体信息系统。它是一种通用的,无 状态(stateless)的协议,除了应用于超文本传输外,它也可以应用于诸如名称服务器和分布 对象管理系统之类的系统,这可以通过扩展它的请求方法,错误代码和消息头[47]来实现 。 HTTP的一个特性就是是数据表现形式是可以定义的和可协商性的,这就允许系统能独立于于 数据传输被构建。 HTTP 在 1990 年 WWW 全球信息刚刚起步的时候就得到了应用。本说明书详细阐述了 HTTP/1.1 协议,是RFC 2068的修订版[33]。 目录(略) 1 引论 1.1 目的 超文本传输协议(HTTP)是一种为分布式的,协作的,超媒体信息系统,它是面向应用层的 协议。在1990年WWW全球信息刚刚起步的时候HTTP就得到了应用。HTTP的第一个版本叫做 HTTP/0.9,是一种为互联网原始数据传输服务的简单协议。由RFC 1945[6]定义的HTTP/1.0进一 步完善了这个协议。它允许消息以类MIME消息的格式传送,它包括传输数据的元信息和对请 求/响应语义的修饰。但是,HTTP/1.0没有充分考虑到分层代理,缓存的,以及持久连接和虚拟 主机的需求的影响。并且随着不完善的HTTP/1.0应用程序的激增,这就迫切需要一个新的版本, 以便能使两个通信程序能够确定彼此的真实能力。 此规范定义的协议叫做“HTTP/1.1”,.这个协议与HTTP/1.0相比,此规范更为严格,以确保 各个协议的特征得到可靠实现。 实际的信息系统除了简单的获取信息之外,还要求更多的功能,包括查找(search),终端更 新(front-end update)和注解(annotation)。HTTP为请求提供可扩充方法集和消息头集 [47]。HTTP是建立在统一资源标识符(URI)[3]的约束上的,作为一个地址(URL)[4]或名称 (URN)[20],以指定被一个方法使用的资源。消息以一种类似于互联网邮件[9]消息格式来传 输的,互联网消息格式定义于多目的互联网邮件扩展(MIME)[7]里。 HTTP也是用于用户代理(user agents)和其它互联网系统的代理/网关之间通信的通信协议, 这些互联网系统可能由SMTP[16],NNTP[13],FTP[18],Gopher[2]和WAIS[10]协议支持。通过 这种方式,HTTP允许不同的应用程序对资源进行基本的超媒体访问。 1.2 要求 本文的关键词“必须”("MUST"),,“不能”("MUST NOT"),“需要”( "REQUIRED"), “应该”("SHALL"),“不应该”("SHALL NOT"),“应该” ( "SHOULD" ) , “ 不 应 该 ” ( "SHOULD NOT" ) , “ 建 议 的 ” ( "RECOMMENDED"),“可能”("MAY"), 和“可选的”( "OPTIONAL")将由RFC 2119[34]解释。 一个应用程序如果不能满足协议提供的一个或多个MUST或REQUIRED等级的要求,是不符 合要求的。一个应用程序如果满足所有必须(MUST)或需要的(REQUIRED)等级以及所有 应该(SHOULD)等级的要求,则被称为非条件遵循(unconditionally compliant)的;若满 足所有必须(MUST)等级的要求但不能满足所有应该(SHOULD)等级的要求则被称为条件 遵循的(conditionally compliant)。 1.3 术语 本说明用到了若干术语,以表示HTTP通信中各参与者和对象扮演的不同角色。 连接(connection) 为通信而在两个程序间建立的传输层虚拟电路。 消息(message) HTTP通信中的基本单元。它由一个结构化的八比特字节序列组成,与第 4章定义的句法相匹 配,并通过连接得到传送。 请求(request) 一种HTTP请求消息,参看第5章的定义。 响应(response) 一种HTTP响应消息,参看第6章的定义。 资源(resource) 一种网络数据对象或服务,可以用第3.2节定义的URI指定。资源可以以多种表现方式(例如 多种语言,数据格式,大小和分辨率)或者根据其它方面而而不同的表现形式。 实体(entity) 实体是请求或响应的有效承载信息。一个实体包含元信息和内容,元信息以实体头域(entity- header field)形式表示,内容以消息主体(entity-body)形式表示。在第7章详述。 表现形式 (representation) 一个响应包含的实体是由内容协商(content negotiation)决定的。如第12章所述。有可能存在 一个特定的响应状态码对应多个表现形式。 内容协商(content negotiation) 当服务一个请求时选择资源的一种适当的表示形式的机制(mechanism),如第12节所述。任 何响应里实体的表现形式都是可协商的(包括错误响应)。 变量(variant) 在某个时刻,一个资源对应的表现形式(representation)可以有一个或多个(译注:一个 URI请求一个资源,但返回的是此资源对应的表现形式,这根据内容协商决定)。每个表现形 式(representation)被称作一个变量。 ‘变量’这个术语的使用并不意味着资源 (resource)是由内容协商决定的.。 客户端(client) 为发送请求建立连接的程序.。 用户代理(user agent) 初始化请求的客户端程序。常见的如浏览器,编辑器,蜘蛛(可网络穿越的机器人),或其他 的终端用户工具. 服务器(Server) 服务器是这样一个应用程序,它同意请求端的连接,并发送响应(response)。任何给定的程 序都有可能既做客户端又做服务器;我们使用这些术语是为了说明特定连接中应用程序所担当 的角色,而不是指通常意义上应用程序的能力。同样,任何服务器都可以基于每个请求的性质 扮演源服务器,代理,网关,或者隧道等角色之一。 源服务器(Origin server) 存在资源或者资源在其上被创建的服务器(server)被成为源服务器(origin server)。 代理( Proxy) 代理是一个中间程序,它既可以担当客户端的角色也可以担当服务器的角色。代理代表客户端 向服务器发送请求。客户端的请求经过代理,会在代理内部得到服务或者经过一定的转换转至 其他服务器。一个代理必须能同时实现本规范中对客户端和服务器所作的要求。透明代理 (transparent proxy)需要代理认证和代理识别,而不修改请求或响应。非透明代理(non- transparent proxy)需修改请求或响应,以便为用户代理(user agent)提供附加服务,附加 服务包括组注释服务,媒体类型转换,协议简化,或者匿名过滤等。除非透明行为或非透明行 为经被显式地声明,否则,HTTP代理既是透明代理也是非透明代理。 网关(gateway) 网关其实是一个服务器,扮演着代表其它服务器为客户端提供服务的中间者。与代理(proxy) 不同,网关接收请求,仿佛它就是请求资源的源服务器。请求的客户端可能觉察不到它正在同 网关通信。 隧道(tunnel) 隧道也是一个中间程序,它一个在两个连接之间充当盲目中继(blind relay)的中间程序。一旦 隧道处于活动状态,它不能被认为是这次HTTP通信的参与者,虽然HTTP请求可能已经把它 初始化了。当两端的中继连接都关闭的时候,隧道不再存在。 缓存(cache) 缓存是程序响应消息的本地存储。缓存是一个子系统,控制消息的存储、获取和删除。缓存里存 放可缓存的响应(cacheable response)为的是减少对将来同样请求的响应时间和网络带宽消 耗。任一客户端或服务器都可能含有缓存,但缓存不能存在于一个充当隧道(tunnel)的服务器 里。 可缓存的(cacheable) 我们说响应(response)是可缓存的,如果这个响应可以被缓存(cache)保存其副本,为的 是能响应后续请求。确定HTTP响应的缓存能力(cacheability)在13节中有介绍。即使一个资 源(resourse)是可缓存的,也可能存在缓存是否能利用此缓存副本为某个特定请求的约束。 第一手的(first-hand) 如果一个响应直接从源服务器或经过若干代理(proxy),并且没有不必要的延时,最后到达 客户端,那么这个响应就是第一手的(first-hand)。 如果响应通过源服务器(origin server)验证是有效性(validity)的,那么这个响应也同样是 第一手的。 显式过期时间(explicit expiration time) 是源服务器认为实体(entity)在没有被进一步验证(validation)的情况下,缓存(cache) 不应该利用其去响应后续请求的时间(译注:也就是说,当响应的显式过期时间达到后,缓存 必须要对其缓存的副本进行重验证,否则就不能去利用此副本去响应后续请求)。 启发式过期时间(heuristic expiration time) 当没有显式过期时间(explicit expiration time)可利用时,由缓存指定过期时间. 年龄(age) 一个响应的年龄是从被源服务器发送或被源服务器成功验证到现在的时间。 保鲜寿命(freshness lifetime) 一个响应产生到过期之间的时间。 保鲜(Fresh) 如果一个响应的年龄还没有超过保鲜寿命(freshness lifetime),那么它就是保鲜的.。 陈旧(Stale) 一个响应的年龄已经超过了它的保鲜寿命(freshness lifetime),那么就是陈旧的. 语义透明(semantically transparent) 缓存(cache)可能会以一种语意透明(semantically transparent)的方式工作。这时,对于 一个特定的响应,使用缓存既不会对请求客户端产生影响也不会对源服务器产生影响,缓存的 使用只是为了提高性能。当缓存(cache)具有语意透明时,客户端从缓存接收的响应跟直接从 源服务器接收的响应完全一致(除了使用hop-by-hop头域)。 验证器(Validator) 验证器其实是协议元素(例如:实体标签(entity tag)或最后修改时间(last-modified time) 等),这些协议元素被用于识别缓存里保存的副本(即缓存项)是否等价于源服务器的实体的 副本。 上游/下游(upstream/downstream) 上游和下游描述了消息的流动:所有消息都是从上游流到下游。 内向/外向(inbound/outbound) 内向和外向指的是消息的请求和响应路径:“内向”即“移向源服务器”,“外向”即“移向 用户代理(user agent)”。 1.4 总体操作 HTTP协议是一种请求/响应型的协议。 客户端给服务器发送请求的格式是一个请求方法 (request method),URI,协议版本号,然后紧接着一个包含请求修饰符(modifiers),客 户端信息,和可能的消息主体的类MIME(MIME-like)消息。服务器对请求端发送响应的格式 是以一个状态行(status line),其后跟随一个包含服务器信息、实体元信息和可能的实体主体 内容的类MIME(MIME-like)的消息。其中状态行(status line)包含消息的协议版本号和一 个成功或错误码。HTTP和MIME之间的关系如附录19.4节所阐述。 大部分的HTTP通信是由用户代理(user agent)发起的,由应用于一个源服务器资源的请求 构成。最简单的情形,这可以通过用户代理(UA)和源服务器(O)之间的单一连接(v)来实 现。 请求链(Request chain)-------------------------------------- ---------- 用户代理(UA)----------------单一连接(v)--------------源服务器(O) <----------------------------------------------------------响应链(response chain) 有可能在请求/响应链中出现一个或多个中间者(intermediares),这是比较复杂的情形。常见 的中间者(intermediares)有三种:代理(proxy),网关(gateway)和隧道(tunnel)。代 理(proxy)是一种转发代理(a forwarding agent),它接收绝对URI(absoulute url,相对 于相对url)请求,重写全部或部分消息,然后把格式化后的请求发送到URI指定的服务器上。 网关是一种接收代理(receiving agent),它充当一个在服务器之上的层(layer),必要时它 会把请求翻译成为下层服务器的协议。隧道不改变消息而充当两个连接之间的中继点;它用于 通信需要穿过中间者(如防火墙)甚至当中间者不能理解消息内容的时候。 请求链(request chain)---------------------------------------- UA-----v-----A-----v-----B-----v-----C------------v-----------------O <----------------------------------------响应链(response chain) 上图显示了用户代理(user agent)和源服务器之间的三个中间者(A,B和C)。整条链的请 求或响应将会通过四个被隔离开的连接。这个不同点很重要,因为某些HTTP通信选项有可能 只能采用最近的非隧道邻接点的连接,有可能只采用链的端点(end-point),或者也有可能只 采用于链上所有连接。图表尽管是线性的,每个参与者可能忙于多个并发的通信。例如,B可以 接收来自不是A的许多客户端的请求,并且/或者可以把请求转发到不是C的服务器,与此同 时C正在处理A的请求。 通信中任何非隧道成员都可能会采用一个内部缓存(internal cache)来处理请求。如果沿着链 的成员有请求已缓存的响应,请求/响应链就会大大缩短。下图阐明了一个最终请求响应链,假 定B拥有一个来自于O(通过C)的以前请求响应的缓存副本,并且此请求的响应并未被 UA 或A缓存。 请求链(request chain)----------> UA-----v----------A-----v-----B-----C----O <---------响应链 (response chain) 并不是所有的响应都能有效地缓存,一些请求可能含有修饰符(modifiers),这些修饰符对缓 存动作有特殊的要求。HTTP对缓存行为(behavior)和可缓存响应(cacheable responses) 的定义在第13章定义。 实际上,目前万维网上有多种被实践和部署的缓存和代理的体系结构和配置。这些系统包括节 省带宽的缓存代理(proxy cache)层次(hierarchies)系统,可以广播(broadcast)或多播 (multicast)缓存数据的系统,通过CD-ROM发布缓存数据子集的机构,等等。HTTP系统 (http system)会被应用于宽带连接的企业局域网中的协作,并且可以被用于PDAs进行低耗 无线断续连接访问。HTTP1.1的宗旨是为了支持各种各样的已经部署的配置,同时引进一种协 议结构,让它满足可以建立高可靠性的web应用程序,即使不能达到这种要求,也至少可以可 靠的定位故障。 HTTP通信通常发生在TCP/IP连接上。默认端口是TCP 80,不过其它端口也可以使用。但并不 排除HTTP协议会在其它协议之上被实现。HTTP仅仅期望的是一个可靠的传输(译注:HTTP 一般建立在传输层协议之上);所以任何提供这种保证的协议都可以被使用;协议传输数据单 元(transport data unit)与HTTP/1.1请求和响应的消息结构之间的映象已经超出了本规范的 范围。 大部分 HTTP/1.0 的实现都是对每个请求/响应交换(exchange)产生一个新的连接。而 HTTP/1.1中,一个连接可以用于一个或更多请求/响应交换,虽然连接可能会因为各种原因中 断(见第8.1节)。 2 符号习惯和一般语法 2.1 扩充的BNF(扩充的 巴科斯-诺尔范式) 本文档规定的所有机制都用两种方法描述:散文体(prose)和类似于 RFC 822 的扩充 Backus-Naur Form(BNF)。要理解本规范,使用者需熟悉符号表示法。扩充BNF结构如下: 名字(name)=定义(definition) 名字(name)就是代表规则的名字,规则名里不能包含“<”和“>”,通过等号把规则名和规 则定义(definiation)分离开。空格只有在采用延续行缩进来指定跨度多于一行的规则定义的时 候才有意义。某些基本规则(basic rules)使用大写字母包含在规则定义里, 如 SP,LWS,HT,CRLF,DIGIT,ALPHA,等等。尖括号可以包含在规则定义里,只要它们的 存在有利于区分规则名的使用。 “字面文本”(“literal”) 字面文本(literal text)两边用引号。除非声明,字面文本大小写不敏感(译注:如,HEX = "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT 里的A,B,C,D等等都是字 面文本(literal text))。 规则1 | 规则2 由竖线(“|”)分开的元素是可选的,例如,“yes | no”表示yes或no都是可接受的。 (规则1 规则2) 围在括号里的多个元素视作一个元素。所以,“(elem (foo | bar) elem)”符合的字符串是“elem foo elem”和“elem bar elem”。 *规则 前面的字符“*”表示重复。完整的形式是“<n>*<m>元素”,表示元素至少出现<n>次,至多出 现<m>次。默认值是0和无穷大,所以"*(元素)"允许任何数值,包括零;"1*元素"至少出现一 次;"1*2element"允许出现一次或两次。 [规则] 方括号里是任选元素;“[foo bar]”相当于“*1(foo bar)”。 N 规则 特殊的重复:“<n>(元素)”与“<n>*<n>(元素)”等价;就是说,(元素)正好出现 <n>次。这样2DIGIT是一个两位数字,3ALPHA是一个由三个字符组成的字符串。 #规则 类似于“*”,结构“#”是用来定义一系列元素的。完整的形式是<n>#<m>元素,表示至少<n>个 元素,至多<m>个元素,元素之间被一个或多个逗号(“,”)以及可选的线性空白(LWS)隔 开了。这就使得表示列表这样的形式变得非常容易;像 (*LWS element *(*LWS ","*LWS element)) 就可以表示为 1#element 无论在哪里使用这个结构,空元素都是允许的,但是不计入元素出现的次数。换句话说 , “(element ), , (element) ”是允许的,但是仅仅视为两个元素。因此,在至少需要一个 元素的地方,必须存在至少一个非空元素。默认值是0和无穷大,这样,“#element”允许任意 零个或多个元素;“1# element”需要至少一个;“1#2element”允许一个或两个元素。 注释(comment) 用分号引导注释。 隐含的*LWS 本规范所描述的语法是基于字(word-based)的。除非特别注明,线性空白(LWS)可以出现 在任何两个相邻字之间(标记(token)或引用字符串(quoted-string)),以及相邻字和间 隔符之间,但是这并没有改变对一个域的解释。任何两个标记(token)之间必须有至少一个分 割符,否则将会被理解为只是一个标记。 2.2 基本规则 (basic rule) 下面的规则贯穿于本规范的全文,此规则描述了基本的解析结构。US-ASCII(美国信息交换标 准码)编码字符集是由ANSI X3.4-1986[21]定义的。 OCTET(字节) = <任意八比特的数据序列> CHAR = <任意ASCII字符(ascii码值从 0到127的字节)> UPALPHA = <任意大写字母"A"..."Z"> LOALPHA = <任意小写字母"a"..."z"> ALPHA = UPALPHA | LOALPHA DIGIT = <任意数字0,1,...9> CTL = <任意控制字符(ascii码值从0 到 31的字节)及删除键DEL(127> CR = <US-ASCII CR, 回车(13)> LF = <US-ASCII LF, 换行符(10)> SP = <US-ASCII SP, 空格(32)> HT = <US-ASCII HT, 水平制表 (9)> <"> = <US-ASCII双引号(34)> HTTP/1.1 将 CR LF 的序列定义为任何协议元素的行尾标志,但这个规定对实体主体 (endtity-body)除外(要求比较松的应用见附录19.3)。实体主体(entity-body)的行尾标志 是由其相应的媒体类型定义的,如3.7节所述。 CRLF = CR LF HTTP/1.1 的消息头域值可以折叠成多行,但紧接着的被折叠行由空格(SP)或水平制表 (HT)折叠标记开始。所有的线性空白(LWS)包括被折叠行的折叠标记(空格SP或水平制 表键HT),具有同SP一样的语义。接收者在解析域值并且将消息转送到下游(downstream) 之前可能会将任何线性空白(LWS)替换成单个SP(空格)。 LWS = [CRLF] 1*(SP | HT) 下面的TEXT规则仅仅适用于头域内容和值的描述,不会被消息解释器解析。TEXT里的字可以 包含不仅仅是ISO-8859-1[22]里的字符集,也可以包含RFC 2047里规定的字符集。 TEXT = <除CTLs以外的任意OCTET,但包括LWS> 一个CRLF只有作为HTTP消息头域延续的一部分时才在TEXT定义里使用。 十六进制数字字符用在多个协议元素(protocol element)里。 HEX = "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT 许多HTTP/1.1的消息头域值是由LWS或特殊字符分隔的字构成的。这些特殊字符必须先被包 含在引用字符串(quoted string)里之后才能用于参数值(如3.6节定义)里。 token (标记) = 1*<除CTLs与分割符以外的任意CHAR > separators(分割符) = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT 通过用圆括号括起来,注释(comment)可以包含在一些HTTP头域里。注释只能被包含在域 值定义里有“comment”的域里。在其他域里,圆括号被视作域值的一部分。 comment (注释)= "(" *(ctext | quoted-pair | comment )” )" ctext = <除"(" 和 ")"以外的任意TEXT > 如果一个TEXT若被包含在双引号里,则当作一个字。 quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) qdtext = <any TEXT except <">> 斜划线("\")可以被作为单字符的引用机制,但是必须要在quoted-string和comment构造之 内。 quoted-pair = "\" CHAR 3 协议参数 3.1 HTTP 版本 HTTP使用一个“<major>.<minor>”数字模式来指明协议的版本号。为了进一步的理解 HTTP 通信,协议的版本号指示了发送端指明消息的格式和能力,而不仅仅是通过双方通信而获得的 通信特性。当消息元素的增加不会影响通信行为或扩展了域值时,协议版本是不需要修改的。当 协议会因为添加一些特征而做了修改时,<minor>数字就会递增。这些修改不会影响通常的消息 解析算法,但它会给消息添加额外的语意(semantic)并且会暗示发送者具有额外的能力。协 议的消息格式发生变化时,<major>数字就会增加。 HTTP消息的版本在HTTP-Version域被指明,HTTP-Version域在消息的第一行中。 HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT 注意major和minor数字必须被看成两个独立整数,每个整数都可以递增,并且可以增大到大 于一位数的整数,如HTTP/2.4比HTTP/2.13低,而HTTP/2.4又比HTTP/12.3低。前导0必 须被接收者忽略并且不能被发送者发送。 一个应用程序如果发送或响应消息里的包含HTTP-Version为“HTTP/1.1”的消息,那么此应 用程序必须至少条件遵循此协议规范。最少条件遵循此规范的应用程序应该把“HTTP/1.1”包含 在他们的消息的HTTP-Version里,并且对任何不兼容HTTP/1.0的消息也必须这么做。关于何 时发送特定的HTTP-Version值的细节,参见RFC2145[36]。 应用程序的HTTP版本是应用程序最少条件遵循的最高HTTP版本。 当代理或网关应用程序转发(forwarding)消息的协议版本不同于代理或网关应用程序本身协 议版本的时候,代理(proxy)和网关(gateway)应用程序就要小心。因为消息里协议版本说 明了发送者处理协议的能力,所以一个代理/网关千万不要发送一个高于该代理/网关应用程序 协议版本的消息。如果代理或网关接收了一个更高版本的消息,它必须要么使协议的版本降低, 要么以一个错误响应,或者要么切换到隧道行为(tunnel behavior)。 自从RFC 2068[33]发布后,由于存在与HTTP/1.0代理(proxy)的互操作问题,所以缓存代 理(caching proxies)必须能提升请求的版本到他们能支持的程度,但网关(gateway)可以 这么做也可以不这么做,而隧道(tunnels)却不能这么做。代理(Proxy)/网关(gateway) 的响应(Response)必须和请求(request)的主版本(major version)号保持一致。 注意:HTTP版本间的转换可能会对消息头域(header fields)在版本里有或没有而进行改变。 3.2 通用资源标识符(URI) URIs有许多名字已为人所知:WWW地址,通用文档标识符,通用资源标识符[3],以及后来 的统一资源定位器(URL)[4]和统一资源名称(URN)[20]。就HTTP而言,通用资源标识符 (URI)只是简单的格式化字符串---通过名称,位置,或其它特征---识别一个资源。 3.2.1 一般语法 根据使用的背景,HTTP里的URIs可以表示成绝对(absoulute)形式或相对形式(相对URI 基于根URI[11])。两种形式的区别是根据这样的事实:绝对URI总是以一个模式(scheme) 名作为开头,其后是一个冒号。关于 URL更详尽的语法和含义请参看“统一资源标识符 (URI):一般语法和语义”,RFC 2396 [42](代替了RFCs 1738 [4]和RFC 1808 [11])。本 规 范 采 用 了 RFC 2396 里 的 ” URI- reference” , "absoluteURI" , "relativeURI" , "port" , "host" , "abs_path" , "rel_path", 和"authority"的定义格式。 HTTP协议不对URI的长度作事先的限制,服务器必须能够处理任何他们提供资源的URI,并 且应该能够处理无限长度的URIs,这种无效长度的URL可能会在客户端以基于GET方式的 请求时产生。如果服务器不能处理太长的URI的时候,服务器应该返回414状态码(此状态码 代表Request-URI太长)。 注:服务器在依赖大于255字节的URI时应谨慎,因为一些旧的客户或代理实现可能不支持这 些长度。 3.2.2 HTTP URL 在HTTP协议里,http模式(http scheme)被用于定位网络资源(resourse)的位置。本节定 义了http URLs这种特定模式(scheme)的语法和语义。 http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]] 如果端口为空或未给出,就假定为80。它的语义即:已识别的资源存放于正在监听tcp连接的 那个端口的服务器上,并且请求资源的的Request-UR为绝对路径(5.1.2节)。无论什么可能 的时候,URL 里使用 IP 地址都是应该避免的(参看 RFC 1900 [24])。如果绝对地址 (abs_path)没有出现在 URL 里,那么应该给出"/"。如果代理(proxy)收到一个主机 (host)名,但是这个主机名不是全称域名(fully quanlified domain name),则代理应该把 它的域名加到主机名上。如果代理(proxy)接收了一个全称域名,代理不能改变主机(host) 名称。 3.2.3 URI 比较 当比较两个URI是否匹配时,客户应该对整个URI比较时应该区分大小写,并且一个字节一 个字节的比较。 但下面有些特殊情况: - 一个为空或未给定的端口等同于URI-refernece(见RFC 2396)里的默认端口; - 主机(host)名的比较必须不区分大小写; - 模式(scheme)名的比较必须是不区分大小写的; - 一个空绝对路径(abs_path)等同于"/"。 除了“保留(reserved)”和“不安全(unsafe)”字符集里的字符(参见 RFC 2396 [42]) ,其它字符和它们的"%HEXHEX"编码的效果一样。 例如,以下三个URI是等同的: http://abc.com:80/~smith/home.html http://ABC.com/%7Esmith/home.html http://ABC.com:/%7esmith/home.html 3.3 日期/时间格式(Date/Time Formats) 3.3.1 完整日期 (Full Date) HTTP应用曾经一直允许三种不同日期/时间格式: Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format 第一种格式是作为 Internet标准提出来的,它是一个国定长度的,由 RFC 1123 [8](RFC 822[9]的升级版本)定义的一个子集。第二种格式使用比较普遍,但是基于废弃的 RFC 850 [12]协议,并且没有年份。如果HTTP/1.1客户端和服务器要解析日期,他们必须能接收所有三