HTTP/1.1协议翻译

1 引言(2005-9-16)
1.1目的
HTTP是一个为分布式的协作的超媒体的信息系统而建立的应用层上的协议。自从1990年就被www采用。第一个版本,HTTP/0。9,是一个简单的跨INTERNET传输原始数据的协议。HTTP/1.0(在RFC1945[6]描述),允许信息以类似MIME形式存在(包含关于传输数据的描述元数据和一些关于REQUEST/RESPONSE语义描述符。但是,HTTP/1。0并没有考虑到多级代理,缓存,持久连接的需要,或着虚拟主机。另外,越来越多的HTTP/1。0的不兼容实现也使得一个新版本的出现变的必要(需要一个统一版本来使协议双方确定彼此实现了哪些功能)。
这份规范定义了HTTP/1。1协议。这份协议比HTTP/1。0包含了更严格的限制,以此来保证实现的可靠性,兼容性。
实际的信息系统要求更多功能而不仅仅是简单的取数据,将包括查询,前台更新,注解。HTTP允许一个开放的方法和头的集合来表示REQUEST的确切要求(对基于URI,URL,URN指定的资源的要求)。而传递的信息则采用类似MIME信息格式。
HTTP也被用来做客户端和处理其他信息系统(SMTP,NNTP,FTP,GOPHTER,WAIS)。的代理/网关的交流。这样,HTTP允许各种各样的应用访问基本的多媒体资源。
1. 2要求
在这个文档里出现的关键词“MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL”按RFC2119[34]描述的那样解释。
如果有1个或多个MUST,REQUIRED水平的要求未满足,那么这个实现就是不兼容的。如果满足所有的MUST,REQUIRED,SHOULD水平的要求,那么这个实现就“unconditionallycompliant”;
满足所有MUST但是不是所有SHOULD是“conditionally compliant”。
1.3术语
这个规范用了许多术语来描述在HTTP交流中的参与者和对象。
Connection
2个要交流的程序间建立的虚拟传输层信路。
Message
基本的HTTP交流单元。由结构化的字节流构成,其结构符合SECTION4的词法定义;通过CONNECTION传递。
Request
一个HTTP request message,SECTION 5 DES。
Response
一个HTTP response message,SECTION 6 DES。
Resource
一个能够被URI标识的网络数据对象或服务,SECTION3。2 DES。资源可以有多种表示,并且可以在其他方面有所变化。
Entity
被一个request或response作为有效负荷传输的信息。由头区的元数据信息和体区的数据区组成,SECTION7 des。
Representation
在一个response里的属于content negotiation的entity,SECTION12 des。在1个response中可以存在多个representation。
Content negotiation
一种机制,用来选择合适的representation来服务一个request,SECTION12 des。
Variant
一个资源可以在任何给定时刻拥有多个representation。每一个被命名为variant。
Client
一个用来建立连接发送request的程序。
User agent
发送一个request的client。最常见的是浏览器
Server
接受连接用来为request服务并且发送回response的应用程序。任何一个程序都可以既做server,又做client,这里的概念指的就是在一次connection中的角色,而不是一般意义下的程序的能力。同样,任何server可以作为一个origin server,proxy,gateway,或者tunnel,基于请求的性质做出不同的行为。
Orgin server
一个指定的资源的所在地或被创建地的server。
Proxy
一个中间程序,既做server又做client(做client是为了其他的的clients)。请求被内部服务或者被传递(有可能做下翻译)到其他server。一个proxy必须实现规范关于client和server的双重要求。一个“transparent proxy“是一个不对request和response做超越代理鉴定要求处理的proxy,相反就是做。除了“transparent proxy”或者“non-transparent proxy”被明确指定的特殊行为外,HTTP proxy 的要求也适用于这两种proxy。
Gateway
一个用来为其他server服务的server。不象一个proxy,一个gateway接受请求就好象他是请求resource的origin server一样;而请求client可能根本就不知道经过了一个gateway。
Tunnel
一个中间程序,在两个conncetion之间做一个透明传递。一旦激活,它将不被认为是HTTP交流的一部分,虽然它可能是被HTTP请求初始化的。当两个connection都关闭后它也消失了。
Cache
程序对reponse message的局部存储,包括控制,查询,删除存储的子系统。一个cache存储cache response用来应对未来的同样的请求,达到降低reponse时间和带宽消耗的目的。任何client和server都可以包括一个cache,但是一个cache不能被一个tunnel使用。
Cacheable
如果一个cache可以存储response message的备份来应对以后的请求,那么这个response就是cacheable。SECTION13 des。即使一个response是Cacheable,也有另外的限制来决定是否一个cache可以用一个cache拷贝来应对请求。
First-hand
一个response是从origin server或经过了几个proxy过来的那么就是first-hand。如果它的有效性被origin server校验过那它也是first-hand。
Explicit expiration time
Origin server确定的关于一个entity不应再由一个cache未经进一步校验就返回的时间。
Herristic expiration time
如果一个Explicit expiration time不可用,那么这个时间被缓存使用
age
一个response的age是自从它被发送或成功地被origin server校验后的时间段
freshness lifetime
一个response自从产生到expiration time之间的时间长度
fresh
一个response是fresh的,如果它的age还没有超过它的freshness lifetime。
Stale
一个response是stale的,如果它的age超过了它的freshness lifetime。
Semantically transparent
一个cache一一种Semantically transparent的方式工作,对于特定的一个response,这时它的使用既没有影响request client也没有影响origin server(和没经过cache一样),但是却提高了性能。
Validator
一个协议元素被用来找出一个cache entity 是不是等同于一个entity。
Upstream/downstream
描述了一个message的流动:所有的message从upstream流向downstream。
Inbound/outbound
是指message的request和response路径。前者只流向origin server,后者指流向user agent。
1.4整体运行框架
HTTP协议是一个request/response协议。一个client发送一个request给一个server,由一个request method,uri,协议版本,紧跟着mime类似的信息(包含request描述符,client的信息,和与一个server传递数据可能的容量)。Server回以一个状态行(包括message的协议版本,一个成功或失败的代码),紧跟一个MIME类似的message(包括server信息,entity的元数据,可能的entity-body容量。HTTP和MIME的关系appendix19.4。
大多数的HTTP连接被一个user agent发起,请求某些origin server上的资源。在简单情况,可以如图所示:
request chain ------------------------>
UA -------------------v------------------- O
<----------------------- response chain
一个更加复杂点的情况:有多个中间体介于request/response chain。有3个普遍的中间体形式:proxy,gateway,tunnel。一个proxy是一个转送站,接受一个request,更改全部或部分message,根据uri重新发request。一个gateway是一个接受站,就象居于其他一些server之上的server一样,如果必要,会把requeset传给它下面的server。一个tunnel是一个接力点,连接2个连接而不改变任何message;可以被用来处理防火墙。
request chain -------------------------------------->
UA -----v----- A -----v----- B -----v----- C -----v----- O
<------------------------------------- response chain
上面的图展示了3个中间体abc在user agent和origin server之间。一个request或response message穿越整个链需要通过4个独立的连接。这个区别是很重要的,因为一些 HTTP通讯选项只能加到最近的,非tunnel邻居,只能到chain的末端或所有连接。虽然图是画地直线,但是每一个参与者可能同时处理多个通讯。比如,B在处理A的request 的同时可能正在接受其他clients发过来的request,而把它们转向非c的server。
任何参与通讯的只要不是tunnel都可以用一个内部cache来处理request。这会缩短通讯链如果有一方有对该request的cached reponse。下面展示了结果链如果B有一个从O的cache copy,而UA,或A没有。
request chain ---------->
UA -----v----- A -----v----- B - - - - - - C - - - - - - O
<--------- response chain
并不是所有的response的缓存都是有用的,一些request可能会包含关于缓存要求的描述符。HTTP对于缓存的方式控制和response,des13。
事实上,缓存和代理的构架现在正在被整个WWW实验和部署。这些系统包括国家级的代理缓存来存储越洋的带宽,系统广播或多点播送cached entries,组织那些零散的缓存到CD-ROM等等。HTTP系统也在公司内网的宽带连接和PDA的低能耗无线断续连接系统中被使用。HTTP1。1的目标是支持在协议诞生期间已经部署的各种配置,使得WEB应用能够达到高可靠性,至少是在失败后有可靠的提示。
HTTP通讯通常是跨TCP/IP连接地发生。默认端口是TCP80[19],但是其他的端口也可以被使用。这就使HTTP可以作为INTERNET上其他协议的上层协议,或其他网络的协议。HTTP只要求一个可靠连接,任何能提供这样的保证的协议都可以被使用;把HTTP/1。1的request和response的结构转化成正在被讨论的协议的数据单位超出了本规范的范围。
HTTP/1。0,大多数实现使用一个新的连接应对request/response交换。在HTTP/1。1中,一个连接可以被多个request/response交流使用,虽然连接可以因为多个原因被关闭。
2.2基本规则
下面这些规则描述了基本的解析符号,贯穿于整篇规范中。US-ASCII字符集在ANSI X3.4-1986[21]中被定义。
OCTET = <any 8-bit sequence of data>
CHAR = <any US-ASCII character (octets 0 - 127)>
UPALPHA = <any US-ASCII uppercase letter "A".."Z">
LOALPHA = <any US-ASCII lowercase letter "a".."z">
ALPHA = UPALPHA | LOALPHA
DIGIT = <any US-ASCII digit "0".."9">
CTL = <any US-ASCII control character
(octets 0 - 31) and DEL (127)>
CR = <US-ASCII CR, carriage return (13)>
LF = <US-ASCII LF, linefeed (10)>
SP = <US-ASCII SP, space (32)>
HT = <US-ASCII HT, horizontal-tab (9)>
<"> = <US-ASCII double-quote mark (34)>
HTTP/1。1 定义了回车换行作为所有协议元素行结束标志,entity-body除外。在entity-body的行结束标志和它相关联的数据类型紧密联系,des3.7。
CRLF = CR LF
HTTP/1。1头区的值可以多行,但需要接续行以一个空格或水平TAB开头。所有的LWS,可以转弯,都和SP有相同的语义。一个*可以在解释域值和转向message downstream时代替任何的LWS用一个单独的SP。
LWS =[CRLF]1*(SP|HT)
TEXT只被用来描述那些不会被message 解析器解析的域内容域值。只要按RFC2047[14]编码时,*TEXT可以包含除ISO-8859-1[22]在外的所有字符。
TEXT = <any OCTET except CTLs,but including LWS>
一个CRLF在TEXT定义中只作为头区的继续的一部分。多行的LWS会在其所在TEXT被解释前被一个单独的SP取代。
十六进制数字字符在几个协议元素中被使用。
HEX = "A" | "B" | "C" | "D" | "E" | "F"
| "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
许多HTTP/1。1头区值由LWS或一些特殊字符分隔的字符组成。而在参数值(des3.6)中这些特殊的字符必须在一对引号中被使用。
token = 1*<any CHAR except CTLs or separators>
separators = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "/" | <">
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
注释可以包含在一些HTTP头区内,但是要在()内。而且只能在注释区内。在其他区,会被认为是区值的一部分。
comment = "(" *( ctext | quoted-pair | comment ) ")"
ctext = <any TEXT excluding "(" and ")">
一个text字符串如果被双引号包着,那会被认为是一个单独的词。
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
qdtext = <any TEXT except <">>
斜划线可以被作为单字符的转换机制,但是必须要在引号内包着,并且是在注释区。
quoted-pair = "/" CHAR
 
3协议参数

3.1HTTP版本

HTTP使用一个“<major>.<minor>”模式来标志协议版本。协议版本就是要允许发送者表达message格式的信息以及它理解更多HTTP协议的能力(不只是说通讯的功能)。加了不影响通讯行为的MESSAGE组件或加了扩展的域值都不必改变版本号。<minor>增大表示协议被改变,一般的MESSAGE解析算法没有变,但是增加了MESSAGE语义也就增加了发送者额外的功能。<major>增大如果MESSAGE的格式改变了。

HTTPmessage的HTTP版本在MESSAGE的头一行的版本域中被表示。

HTTP-Version =”HTTP””/”1*digit”.”1*DIGIT

注意major和minor数每一个都可以独立对待。因此HTTP/2。4比HTTP/2。13低,而HTTP/2。4又比HTTP/12。3低。前面的0必须被接收者忽略而发送者千万不要发。

一个发送包含“HTTP/1。1”版本的request或response信息必须最少与这个规范条件兼容。而一个和这个规范最少条件兼容的应用应该在他们的MESSAGE中标明HTTP/1。1版本,并且对于于HTTP/1。0不兼容的MESSAGE必须标明HTTP/1。1版本。关于什么时候送规范的HTTPV值更多细节看RFC2145[36]。

应用的HTTP版本是应用最少条件兼容的最高HTTP版本。

Proxy和gateway应用需要仔细对待转发不同于自身应用版本的message。因为过来的MESSAGE中的HTTP版本代表了发送者的协议能力,一个PROXY/GATEWAY千万不要发送一个高于该版本的MESSAGE。相反,如果接受了一个更高版本也不要减低或报错或转向TUNNEL行为。

RFC2068[33]发布时发现了与HTTP/1。0proxy交互时出现的问题,缓存proxy必须,gateway可以,tunnel千万不要升级request到他们支持的最高版本。Proxy和gateway的Response必须和那个request保持同一个版本。

注意:在HTTP版本间的转换可能包含头区某域的改变,而这些改变可能被要求或被拒绝。

3.2统一资源定位符

关于URI以前出现的名称有:WWW地址,通用文档标志,通用资源标志,最后,代表URL和URN的组合。只要和HTTP相关,URI就是一个简单的格式化字符串,通过名称,地址或其他特征来标志一个资源。

3.2.1普通语法

在HTTP中URI可以以一个绝对的形式表现或相对于一些知道的基本的URI,这取决于使用的上下文。这两种形式被区分于:绝对的URI总是以一个模式名称跟一个冒号开始。关于URL的词法和语法的绝对定义信息,需要看“Uniform Resource Identifiers (URI): Generic Syntax and Semantics,” RFC 2396 [42](取代了RFCs1738[4]和RFC1808[11]);而其中的部分定义“URI-reference”, “absoluteURI”, “relativeURI”,“port”, “host”,“abs_path”, “rel_path”, 和 “authority”在本规范中也被使用。

HTTP协议并没有对URI的长度有一个预先的限制。服务器必须能够处理任何他们提供资源的响应URI,而且应该能够处理无限长度的URI,如果他们提供基于GET的表达形式。一个服务器应该返回414如果一个URI比服务器能处理的URI还长的话。

注意:服务器应该小心对待长度超过255个字节的URI,因为一些老client和proxy实现可能不支持这些长度。

3.2.2http URL

“http”模式被用来通过HTTP协议定位网络资源。下面为httpURL定义了模式化的词法和语法.

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

如果端口空或为给出,使用80。语法就是,资源所在的server在host的port端口监听tcp连接,而abs_path指定了请求资源的Request-URI。IP地址的使用只要有可能就应该被避免(RFC1900[24])。如果abs_path没有出现在URL中,它必须作为“/”作为Request-URI(SEC5。1。2)。如果一个代理接受到不完全domain名称的主机名称,它可以用它自己的domain名称加进去;如果接受到完整的,则不能改变主机名称。

3.2.3URI比较

当把两个URI比较以决定他们是否匹配,一个client应该采用大小写敏感地字节对应字节地方式比较整个URI,下面除外:

端口默认为80,有没有相同

host名称必须大小写不敏感

模式名称必须大小写不敏感

一个空的abs_path等同于一个“/”的abs_path

不在“reserved” and “unsafe”字符集里的字符等价与“% HEX HEX”编码。例如

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

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

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

等价的。

3.3Data/Time 格式

3.3.1完整日期

HTTP应用历史上允许3中不同的DATE/TIME表示:

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标准并且代表了RFC1123[8](RFC822[9]的更新)的固定长度子集。

第二种被普遍使用,但是基于被废弃的RFC850[12]日期格式并且缺少年度的4位表示。HTTP/1.1clients 和server解析date值就必须接受所有3种格式,虽然必须的是在HTTP头区按RFC1123产生日期值。SEC19.3。

注意:date值的接收程序被鼓励可以接受非HTTP应用发的DATE值,这种情况经常出现在通过SMTP/NNTP的代理或网关接收或发送信息。

3.2.2 delta秒

一些HTTP头区允许一个时间值被一个秒的整数值来表示,十进制,在message被接收到之后。

3.4 字符集

HTTP使用MIME描述的相同定义来定义字符集。

    在这篇文档中,术语字符集指使用一个或多个表把一组字节码转换成一组字符的方法。注意相反方向的无限制的转化不是必需的,并不是所有的字符都在一个给定字符集中,并且一个字符集可以提供多个字节码组合来代表一个指定字符。这个定义用来允许多种字符编码,从简单的单表映射如US-ASCII到复杂表的转化如ISO-2022技术。但是,和MIME字符集名称定义相关的定义必须完整地明确从字节码到字符的映射。具体地说,使用外面的相关信息来确定精确映射是不允许的。

   注意:更常使用字符编码来指字符集。但是因为HTTP和MIME使用相同的登记,所以术语最好统一起来。

HTTP字符集用大小写不敏感的标记来标志。完整的标记组合由IANACharacter Set registry [19]来定义。

   Charset=token

虽然HTTP允许任意的TOKEN,凡是IANA Character Set registry [19]中定义的组合值必须代表其中注册的字符集。应用应该仅使用那些在IANA登记中的字符集。

实现者要意识到IETF[38][41]。

3.4.1没有CHARSET

一些HTTP/1。0软件认为没有CHARSET参数的CONTENT-TYPE头应该“由接收者来猜”。这并不正确。发送者如果要阻止这种行为应该包含一个参数即使字符集是ISO-8859-1而且如果不会迷惑接收者也应该这样做。

不幸的是一些更老的HTTP/1。0CLIENT不能合适地处理CHARSET参数。HTTP/1。1接收者必须采用发送者提供的该参数;而且那些可以猜的用户端初始展示一个文档时也必须使CONTENT-TYPE区里的字符集,而不是自己爱咋咋地。

3.5内容编码

内容编码值来指示一个可以被用到一个ENTITY上的编码转换。内容编码主要被使用来允许一个文档被压缩或不丢失媒体类别信息和其他信息的转化。ENTITY被编码地存储,直接发送,然后只被接收者解码。

content-coding = token

token是大小写不敏感的。HTTP/1。1在Accept-Encoding(section 14.3)和Content-Encoding (section 14.11)使用该值。尽管该值描述了内容编码,更重要的是它指定了什么样的解码是合适的。

IANA登记了内容编码值。起初,登记包含了下面这些标记:

Gzip 一个编码样式,由文件压缩程序GZIP(GNU ZIP)提供,RFC1952[25]描述。这个格式是LZ77和32CRC编码。

Compress

   有UNIX文件压缩程序“compress”来提供。格式是LZW编码。

   使用程序名字来标志编码格式并不理想,也将在未来的编码中被取代。在这里使用是历史的原因,并不是个好设计。为了向前兼容,一个应用应该把“x-zip”和“x-compress“认为和”gzip“”compress”认为是各自相同的。

Deflate

   “zlib“(RFC1950[3]定义)和”deflate“压缩机制(RFC1951[29]定义)的组合。

Identity

    默认的编码;没有转化的转化。只在Accept-Encoding头中使用,不应在Content-Encoding中使用。

新的内容编码值应该被登记;为了允许交互性,对新值的内容编码算法应该是可公共使用并足够用来独立实现,并且要满足内容编码存在的初衷。

3.6传输编码

传输编码被用来指示一个用来保证ENTITY穿越网络安全传输的编码。它是MESSAGE的一个属性并不是原始的ENETITY的。

   transfer-coding = "chunked" | transfer-extension

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

parameter以属性值对的形式存在。

parameter = attribute "=" value

attribute = token

value = token | quoted-string

所有的传输编码值是大小写不敏感的。HTTP/1。1在TE(sec14.39)和Transfer-Encoding(SEC14。41)中使用。

只要一个传输编码被应用在一个MESSAGE-BODY中,该编码集合必须包含“CHUNKED“,除非message因关闭连接而结束。当”chunked“被使用,他必须是对MESSAGE-BODY的最后的编码。绝对不能用两次。靠这个接受者可以决定MESSAGE的传输长度(SEC4。4)。

MEME[7]的Content-Transfer-Encoding值,用来通过7位传输服务来实现2进制数据安全传输。虽然传输编码类似于这种安全传输,但是,安全传输在8位传输协议有一个不同的焦点。在HTTP传输中不安全的问题主要在决定BODY的长度和加密数据。

IANA登记了传输编码值。最初,包含“chunked” (section 3.6.1), “identity” (section 3.6.2), “gzip” (section3.5), “compress” (section 3.5), and “deflate” (section 3.5)。新登记也应该和内容编码一样登记。

一个server,如果接收了无法处理的传输编码,应该返回501,并且关闭连接。一个server绝对不能发给HTTP1。0客户端传输编码。

3.6.1大块的传输编码

修改BODY改成一块一块的序列,每一个带大小指示,带一个可选的尾部,里面有ENTITY-HEADER区。这允许动态地产生的内容也被接收者识别组装好。

Chunked-Body = *chunk

last-chunk

trailer

CRLF

chunk = chunk-size [ chunk-extension ] CRLF

chunk-data CRLF

chunk-size = 1*HEX

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

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

chunk-ext-name = token

chunk-ext-val = token | quoted-string

chunk-data = chunk-size(OCTET)

trailer = *(entity-header CRLF)

chunk-size区是十六进制数字用来表示块的大小。编码以一个大小为0,跟着一个空行结束的尾部的块来作为结束。

尾部允许发送者来在MESSAGE结束出包括额外的HTTP头区。而TRAILER头区可以用来知识哪个头区被包含在了一个尾部(SEC14。40)

一个server如果使用块传输编码,决不能为头区使用尾部,除非下面至少一个是真的。

a)request包含一个TE头区,指示在response的传输编码中尾部是可以接受的。

b)server是response的origin server,尾部整个由可选元数据,而接收者可以不接收这些元数据也能使用MESSAGE。换句话说,ORIGIN SERVER愿意接收在client传递过程中尾部被割掉的信息。

这个要求阻止了一些通过了HTTP/1。1(或更高版本)而被HTTP/1。0接收时出现的交互错误。这样就不会强于要求代理实现一个无限大小的缓存。

App19.4.6展示了一个解码Chunked-Body的例程。

所有的HTTP/1。1应用必须能够接收并解码CHUNKED传输编码,并且必须忽略他们不理解的chunk-extension扩展。

3.7媒体类型

HTTP使用IMT[17]在Content-Type (section 14.17) and Accept (section 14.1) 头区中提供开放和灵活扩展的数据类型和类型交互。

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

type = token

subtype = token

参数可以以attribute/value的形式来跟随type/subtype

ype, subtype, 和 parameter属性名称都是大小写不敏感的。参数值可以是或不是到小写敏感,这取决于参数名称对应的语法。LWS决不能在type和subtype之间被使用,也不能在attribute和它的value之间使用。参数的存在与否可能会对media-type的处理有很重要的意义,这取决于其在登记中的定义。

注意一些老的HTTP应用不会认出该媒体类型参数。当发送数据给这些应用时,实现应该只使用那些被定义要求使用的TYPE/SUBTYPE。

MEDIA-TYPE在(IANA [19])中定义。登记过程在RFC1590[17]中被概括。使用非登记的media tyoe是不提倡的。

3.7.1标准化和默认文本

国际媒体类型用一个标准形式登记。一个entity-body在通过HTTPmessage传递前必须作为相应的标准形式存在。 “text”类型例外,我们将在下一段说明。

在标准形式下,“text”的子类使用CRLF作为文本行的连接。HTTP放松了这个要求,允许在一个完整的entity-body中始终用“CR”或“LF”单独代表行连接。HTTP应用对于通过HTTP接收到的文本必须能够使用CRLF,CR,LF作为行连接的代表。另外,如果文本使用的字符集并不使用13,10代表CR,LF,就象在一些多字节字符集那样,那么,HTTP允许使用其对应的字节码代表该字符。这种灵活性

3.7.2多部分类型

MIME提供了许多“multipart”类型—用一个message封装一个或多个entity。所有的multipart共享一个公共的语法(sec5.1.1-RFC2046[40]),并且必须包含一个分界参数作为media类型值的一部分。Message本身是一个协议元素因此必须进使用CRLF去作为跨BODY-PART的行继续标志。不同于在RFC2046,任何多部分类型的MESSAGE的尾部必须是空的;HTTP应用绝对不能传递尾部。(即使原先的多部分包含一个尾部)。这个限制的存在是为了保持多部分消息体的自分界性质,就是信息体的结束使用多部分的结束作为结束。

一般情况下,HTTP对于一个多部分消息体是和其他的一样严格作为有效负荷处理的。有个例外是“multipart/byteranges”(appendix19.2)当它出现在206response中时,会被一些HTTP缓存机制象在sec13.5.4和14.16中描述地那样处理。在其他情况下,一个HTTPuser agent 应该类似于一个MIME用户接收一个多类型那样处理。除了那些在MIME语义中定义的那些,在每个多部分消息体中的MIME头区对于HTTP没有任何意义。

一般情况下,一个HTTPuser agent应该象MIME一样处理多部分类型。如果一个应用接受到一个不认识的multipart subtype,它必须把它等同与“multipart/mixed”处理。

注意:“multipart/form-data”已经被明确定义用来通过POST方法传递表单数据,RFC1867[15]。

3.8产品标记

产品标记被用来允许通讯应用来通过软件名称和版本来标志他们自己。大多数使用产品标记的区也使用子产品来形成被列出的应用的重要组成部分,它们以空格分开。按照其重要程度来有序列出。

product = token ["/" product-version]

product-version = token

例如:

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

Server: Apache/0.8.4

产品标记应该言短意赅。它们绝对不能被用来做广告或其他不重要的信息。虽然任何的标记字符可以出现在一个product-version里,这些个字符应该只用来标记版本。(例如,接续的版本好应该只在产品版本部分不同)。

3.9属性值

HTTP content negotiation(SEC12)使用短浮点数来标记各种negotiable参数的重要性(权重)。一个权重回被标准化成一个>0并且<1的数。如果一个参数是0的质量值,那这个参数的内容是不被客户端所接受的。HTTP/1。1应用绝对不能产生多于小数点后3位的数。用户对他们的值的配置也应该限于此

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

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

其实这个名字本身容易引起误解,因为其值仅仅代表要求质量的相对级别。

3.10语言标记

一个语言标记被用来标志人们说的语言。当然计算机语言肯定不被包含在内。HTTP在Accept-Language 和 Content-Language区使用语言标记。

HTTP语言标记的语法和登记和RFC1766[1]定义的类似。总之,一个语言标记是由1或多个部分组成:一个主语言标记和一个可能的空子标记序列:

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

primary-tag = 1*8ALPHA

subtag = 1*8ALPHA

空格在标记中不被允许并且所有的标记都是大小写不敏感的。语言标记命名空间在IANA中管理。例如:

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

任何2字母的主标记是一个ISO-639语言缩写,而任何2字母的初始子标记是一个ISO-3166国家码。(后3个没有登记,最后一个不会被允许)。

3.11实体标记

实体标记用来比较来自相同的去请求资源的两个或多个实体。HTTP/1。1在ETag (section 14.19), If-Match (section 14.24), If-None-Match (section 14.26), 和If-Range

使用实体标记。

如何定义以及怎么作为缓存校验来比较在sec13.3.3中描述。

entity-tag = [ weak ] opaque-tag

weak = "W/"

opaque-tag = quoted-string

如果同一资源的两个ENTITY具有相同的位集可以共享“strong entity tag”。

而由一个"W/" 前缀表示的“weak entity tag”标记的tag,如果是相等的并可以在语义上无修改地互相取代,那么可以共享一个标记。只能用来弱比较。

在一个给定resource中的对应实体必须保持实体标记具有唯一性。但是如果是不同URI得到的实体可以有相同标记值,但不表示这些实体是等价的。

3.12范围单位

HTTP/1。1允许一个client只是response实体的部分被包含在response中。HTTP/1。1在Range (section 14.35) 和Content-Range (section 14.16)中使用范围单位。一个实体能够根据各种结构单位分成多个范围

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

bytes-unit = "bytes"

other-range-unit = token

在HTTP/1。1定义的唯一的范围单位是”byte”。HTTP/1。1的实现可以忽略其他范围定义。HTTP/1。1被设计成允许那些不必知道范围单位的应用的存在。

5 请求

一个从client到server的request,在第一行,包含应用于资源的方法,资源标志,和使用的协议版本。

Request = Request-Line ; Section 5.1

*(( general-header ; Section 4.5

| request-header ; Section 5.3

| entity-header ) CRLF) ; Section 7.1

CRLF

[ message-body ] ; Section 4.3

5.1请求行

以一个方法标记开始,跟着URI,和版本协议,以CRLF结束。SP分隔。除了在最后的CRLF不能有CR,LF。

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

5.1.1方法

方法标记表示将会用在请求资源上的方法,是大小写敏感的。

Method = "OPTIONS" ; Section 9.2

| "GET" ; Section 9.3

| "HEAD" ; Section 9.4

| "POST" ; Section 9.5

| "PUT" ; Section 9.6

| "DELETE" ; Section 9.7

| "TRACE" ; Section 9.8

| "CONNECT" ; Section 9.9

| extension-method

extension-method = token

一个资源可以允许的方法列表可以在ALLOW头区给出。Response的返回代码总是告诉client一个方法可否应用到一个资源,因为总是在变。一个server应该返回405如果方法可以识别但不能用于请求资源,返回501如果方法不可识别或没有被origin server实现。方法get和head必须被所有的通用目的的server实现。所有其他方法是可选的;但是,如果上面的方法被实现,他们必须具备sec9定义的语义。

5.1.2URI

是一个统一资源标记(3。2)标记了request请求的资源。

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

4个选项取决于request的性质。星号意思是request并不指定某一特定资源,而是server本身,只在方法并不一定针对资源时。一个例子:

OPTIONS * HTTP/1.1

如果请求是发给一个代理,absoluteURI形式是必须的。代理被请求来传递request或从一个有效缓存中服务,返回response。注意代理可以传递这个request给另外一个代理或直接给被absoluteURI指定的server。为了避免request循环,一个代理必须能够识别所有它的server名,包括别名,局部变量,和IP地址。里:

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

为了允许传递所有的未来的HTTP版本中的request,所有的HTTP/1。1server必须接收request的absoluteURI,即使HTTP/1。1client只产生他们用来代理。

Authority形式只被CONNECT方法使用。(sec9.9)

最通用的URI形式是用来标记在一个origin server或gateway上的资源。在这种情况下,URI的绝对路径(abs_path)必须作为URI被传递,而且URI的网络路径(authority)也必须被作为一个Host头区被传递。例如,一个希望直接从origin server得到上面指定资源的request会创建一个到“www.w3.org”80端口的TCP连接并且发送这一行:

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

Host: www.w3.org

跟着的是request的其他剩余部分。注意绝对路径不能是空的;如果确实没有,必须作为“/”给出。

URI以SEC3。2。1给出的格式传送。如果URI使用”%HEX HEX”编码[42]的形式编码,origin server必须解码URI一合适的解释request。Server应该对无效的URI给出合适的状态码返回。

一个transparent proxy当把request传递给内部server时绝对不能重写接收到的URI的“abs_path”部分,除非把null abs_path用“/”替换。

注意:“no rewrite”阻止了proxy改变request的原本意义,当origin server使用非保留URI字符对应保留目的时。实现者应该意识到一些HTTP/1。1前proxy可能重写uri。

5.2 Request标记的资源

被一个request请求的资源由uri和host头区精确确定。

当决定一个HTTP/1/1request请求的资源时,一个origin server如果不允许使用host来区别资源,那么可以忽略host头区。(sec19.6.1)

而一个确实使用host(又叫虚拟主机)区分资源的origin server使用下面原则处理HTTP/1。1request请求的资源:

 

  1.如果URI是absoluteURI,那么主机名是其中一部分,任何其他主机名头区被忽略。

  2.如果URI不是,并且包含HOST头区,那么host被头区决定。

  3.400反馈1,2无效的。

HTTP/1。0是没有HOST头区的,可以使用直观推测方法来决定请求的精确资源。

5.3请求头区

头区允许client传递额外的关于request和client的自身信息给server。这些区就算request的描述符,就象程序语言的参数一样。

request-header = Accept ; Section 14.1

| Accept-Charset ; Section 14.2

| Accept-Encoding ; Section 14.3

| Accept-Language ; Section 14.4

| Authorization ; Section 14.8

| Expect ; Section 14.20

| From ; Section 14.22

| Host ; Section 14.23

| If-Match ; Section 14.24

| If-Modified-Since ; Section 14.25

| If-None-Match ; Section 14.26

| If-Range ; Section 14.27

| If-Unmodified-Since ; Section 14.28

| Max-Forwards ; Section 14.31

| Proxy-Authorization ; Section 14.34

| Range ; Section 14.35

| Referer ; Section 14.36

| TE ; Section 14.39

| User-Agent ; Section 14.43

s头区的名字可以跟随一个改变的版本号而被扩展。但是,新的或实验的头区可以被给通用头区的语义如果通讯双方都认同。认不出的头区被认为是实体头区。

6 Response

当接收和解析一个request message后,一个server用一个HTTPresponse messge返回。

Response = Status-Line ; Section 6.1

*(( general-header ; Section 4.5

| response-header ; Section 6.2

| entity-header ) CRLF) ; Section 7.1

CRLF

[ message-body ] ; Section 7.2

6.1状态行

一个response message的第一行是状态行,由协议版本,跟状态码,跟对应文本段,每一个用SP分隔。没有CR或LF被允许除了最后的CRLF。

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

6.1.1状态码和原因段

状态码是一个3数字位结果编码,去理解和满足请求。Sec10完全定义。原因段是给一个简短的文本描述给status-code。状态码是自动使用而原因段是人工使用。Client并不需要去检查和表示原因段。

第一位定义了response的分类。后2位没有分类的意思。第一位有5个值。

· 1xx: request收到,继续处理

· 2xx: action被成功接收,理解,接受

· 3xx:还有其他action要做

· 4xx: request有问题

· 5xx: server有问题不能解决有效request的请求。

下面是定义的值和推荐原因段,当然可以自己定义。

Status-Code =

"100" ; Section 10.1.1: Continue

| "101" ; Section 10.1.2: Switching Protocols

| "200" ; Section 10.2.1: OK

| "201" ; Section 10.2.2: Created

| "202" ; Section 10.2.3: Accepted

| "203" ; Section 10.2.4: Non-Authoritative Information

| "204" ; Section 10.2.5: No Content

| "205" ; Section 10.2.6: Reset Content

| "206" ; Section 10.2.7: Partial Content

| "300" ; Section 10.3.1: Multiple Choices

| "301" ; Section 10.3.2: Moved Permanently

| "302" ; Section 10.3.3: Found

| "303" ; Section 10.3.4: See Other

| "304" ; Section 10.3.5: Not Modified

| "305" ; Section 10.3.6: Use Proxy

| "307" ; Section 10.3.8: Temporary Redirect

| "400" ; Section 10.4.1: Bad Request

| "401" ; Section 10.4.2: Unauthorized

| "402" ; Section 10.4.3: Payment Required

| "403" ; Section 10.4.4: Forbidden

| "404" ; Section 10.4.5: Not Found

| "405" ; Section 10.4.6: Method Not Allowed

| "406" ; Section 10.4.7: Not Acceptable

| "407" ; Section 10.4.8: Proxy Authentication Required

| "408" ; Section 10.4.9: Request Time-out

| "409" ; Section 10.4.10: Conflict

| "410" ; Section 10.4.11: Gone

| "411" ; Section 10.4.12: Length Required

| "412" ; Section 10.4.13: Precondition Failed

| "413" ; Section 10.4.14: Request Entity Too Large

| "414" ; Section 10.4.15: Request-URI Too Large

| "415" ; Section 10.4.16: Unsupported Media Type

| "416" ; Section 10.4.17: Requested range not satisfiable

| "417" ; Section 10.4.18: Expectation Failed

| "500" ; Section 10.5.1: Internal Server Error

| "501" ; Section 10.5.2: Not Implemented

| "502" ; Section 10.5.3: Bad Gateway

| "503" ; Section 10.5.4: Service Unavailable

| "504" ; Section 10.5.5: Gateway Time-out

| "505" ; Section 10.5.6: HTTP Version not supported

| extension-code

extension-code = 3DIGIT

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

HTTP状态码是可扩展的。HTTP应用并没有被要求去理解他们但很明显是需要的。但是,应用必须理解代码的分类,也就是第一位,并且对任何不认识的response等同于对应类别的x00,但是不缓存它。例如,如果一个431被client接收到但不识别,它可以认为它的request本身并没有错,并且把response作为400处理。在这种情况下,user agent应该给user展现response返回的整个entity,因为entity可能包含人可以识别的信息来解释不寻常的状态。

6.2 Response 头区

用来让server放在status-line中不能放的关于response的额外信息。这些头区给出了server的信息和更深入的关于REQUEST-URI指定的资源进入。

response-header = Accept-Ranges ; Section 14.5

| Age ; Section 14.6

| ETag ; Section 14.19

| Location ; Section 14.30

| Proxy-Authenticate ; Section 14.33

| Retry-After ; Section 14.37

| Server ; Section 14.38

| Vary ; Section 14.44

| WWW-Authenticate ; Section 14.47

s头区的名字可以跟随一个改变的版本号而被扩展。但是,新的或实验的头区可以被给通用头区的语义如果通讯双方都认同。认不出的头区被认为是实体头区。

7  Entity

request和response可以传递一个实体如果request方法和response状态码未加限制的话。一个entity由头区和体组成,虽然一些response只包含头区。

在这个段中,发送者和接收者可以是client或server,看谁发送和接收实体。

7.1实体头区

定义了实体的描述数据,如果没有实体,那就是request指定资源的描述数据。一些是可选的,一些是必须的。

entity-header = Allow ; Section 14.7

| Content-Encoding ; Section 14.11

| Content-Language ; Section 14.12

| Content-Length ; Section 14.13

| Content-Location ; Section 14.14

| Content-MD5 ; Section 14.15

| Content-Range ; Section 14.16

| Content-Type ; Section 14.17

| Expires ; Section 14.21

| Last-Modified ; Section 14.29

| extension-header

extension-header = message-header

扩展头区机制允许额外的头区定义而不用改变协议,但是这些区并不能假定会被接收者识别出。没有识别的要被接收者忽略而且必须被透明proxy传递。

7.2 Entity Body

它是以实体头区定义的形式和编码形成的伴随request和response发送的。

entity-body = *OCTET

一个Entity Body只存在于一个存在消息体的消息中,(sec4.3)。通过解码传输编码从message-body中得到entity-body。

7.2.1类别

当一个entity-body被一个消息包含时,通过头区Content-Type和Content-Encoding决定类型。这些定义了一个两层的 有序的编码模型。

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

Content-Type声明了数据的类型。Content-Encoding用来给出额外的内容编码,通常是用来数据压缩的,是被request资源的属性。没有默认的编码。

任何包含一个实体的HTTP/1。1消息应该包含一个Content-Type头区来定义那个体的media type。如果media type没有在一个content-type区被给出,接收着可以通过内容或uri的名字扩展来猜。如果还是未知,那就应该作为“application/octetstream”。

7.2.2 实体长度

即使消息体被任何传输编码应用前的长度。Sec4.4定义了怎么确定一个消息体的传输长度。

8 连接

8.1持久连接

8.1.1目的

持久连接之前,一个单独的TCP连接需要每次取得URL来建立,增大了HTTP server的负载并且引起internet的拥挤。使用联机图片和其他相关数据资源通常要求一个client在极短时间向相同的server发送多个request。关于这些性能问题的分析和对一个实验性实现的结果是可用的[26][30]。实现经验和实际的HTTP/1。1(RFC2068)的测量显示了很好的结果。也产生了可选的代替,例如,T/TCP[27]。

持久的HTTP连接有很多优点:

l         打开和关闭更少的TCP连接,节省了通讯链路上路由器和主机(clients,servers,proxies,gateways,tunnels,或caches)上的CPU消耗,也节省了主机上对TCP控制块的内存消耗

l         HTTP连接和请求可以在一次连接上pipeline。这允许一个client发送多个request而不用等response,允许单个TCP连接被更有效地使用而节省了大量时间。

l         网络拥塞被降低了,因为减少了TCP打开的PACKETS,和允许TCP有更多的时间决定网络拥挤状态

l         等待下一个request时间被降低了,应为可以花费更少的时间在TCP握手上

l         HTTP可以更好地发展,因为错误在不关闭TCP连接的情况下被报告。HTTP的未来版本的client可以乐观地使用一个新特征,但是要和一个旧server通讯就要在错误被报告时尝试旧语义。

HTTP应用应该实现持久连接。

8.1.2整体流程

HTTP/1。1和其他早期HTTP的重要区别就是持久化连接是所有HTTP连接的默认连接。也就是,除非有另外指明,client应该假定server保持一个持久连接,即使server发送一个error。

持久化连接提供了一个机制,通过它一个client和一个server能够表示tcp连接的关闭,就是使用connection 头区。一旦一个close被标记,client不能在connection上发送任何request。

8.1.2.1 Negotiation

一个HTTP/1。1server可以假定一个HTTP/1。1client想要保持一个持久化连接直到一个connection区被指定为“close”,并且被以request发送。如果server想在response之后关闭连接,它应该这样指明。

一个HTTP/1。1client可以期待连接保持,但是通过response的connection头区来决定是否保持;而如果不想连接保持,就应该发一个close的connection头区。

如果client和server有一个发了,那么request是连接的最后一个。

Client和server不应该假定低于HTTP1。1的版本会维持一个持久化连接。Sec19.6.2提供更多兼容信息。

为了保持持久,所有在连接中的消息必须有一个自定义的消息长度,sec4.4。

8.1.2.2流水线

一个支持持久化连接的client可以流水它的request(也就是说,发送多个request而不必等待response)。一个server必须发送它的response给那些request按request应该接收到的顺序。

Client在连接建立后马上假定持久化连接和流水线存在的如果第一次流水线试图失败要准备重新建立连接。如果一个client做这样的重试,它在知道连接是持久化之前绝对不能pipeline。如果server在发送所有对应response之前关闭连接,client也必须要准备重发所有的请求。

Client不应该发送非等幂(或序列)方法的request。否则一个运输连接的过早终结可能会导致结果的不确定。一个希望发送一个非等幂request的client应该等到前一个request对应的response到了后再发。

8.1.3代理服务器

proxy正确实现connection头区(sec14.10)的属性是非常重要的。

Proxy必须分别给它的client和origin server(或其他proxy server)标记持久化连接。每一个持久化连接对应一个链。

一个proxy绝对不能建立HTTP/1。1持久连接和一个HTTP/1。0client(RFC2068)。

8.1.4实践考虑

server通常有一些超时值,超过了这些值就不会维持一个活动连接。Proxy可以设得更高因为可能一个client可能会和它r做更多的连接。这个值本身的大小没有限制。

当一个client或server想要超时,它应该给那个连接发一个优美的中断。Client和server都应该经常地观察传输的另一端,合适地给以处理。如果相反的话会导致网络资源耗尽。

一个client,server或proxy可以在任何时候关闭传输连接。例如,一个client会开始发送一个新的request同时一个server决定关闭这个看似空闲的连接。从server的角度看,连接就要被关闭,从client的角度看,一个request正在被发送。

这意味着client ,server,proxy必须能够从异步关闭事件中恢复。Client软件应该从新打开连接从新发送失败的request,只要request序列是等幂的(sec9.1.2)就不需要用户交互。不等幂的方法或序列绝对不能被自动重发,虽然user agent可以提供一个手工操作来选择重新发送。User-agent软件的确认回代替用户的确认。如果第2次请求序列失败自动重发不应该继续。

Server应该总是对一个连接至少发一个response,如果可能的话。Server不应该在发送一个response的过程中关闭一个连接,除非预测到一个网络连接或client失败。

使用持久连接的client应该限制他们维持到同一个server的并行连接数。一个单个的user client不应该对任何server或proxy保持对于2个连接。一个proxy应该使用最多2*N个连接到另一个server或proxy,N是同时活跃的users个数。这些原则被用来提高http response时间并且避免拥塞。

8.2消息传送要求

8.2.1持久连接和流控制

HTTP/1.1的server应该保持持久连接并且使用TCP的流控制机制来解决临时过载的问题,而不是知道client会retry还终止连接。后者会加重网络租塞。

8.2.2 监视连接中的错误状态信息

一个HTTP/1。1(或之后的)正在发送消息体的 client当它正在传递request时应该监视网络连接的错误状态。如果client看到一个错误状态,它应该迅速终止消息体的发送。如果正在用“chunked”(sec3.6)编码发送,一个0长度的chunk和空尾部可以被使用用来标志消息的结束。如果消息体先于一个Content-Length头部,client必须关闭连接。

8.2.3使用100status

100状态的存在是为了允许一个正在发送带body的request message的client来决定是否一个origin server想要接收request(基于request header),这发生在实际发送request body之前。在某些情况下,发送一个不被server看就拒绝的消息体是不合适和浪费效率的。

对HTTP/1。1client的要求:

。如果一个client愿意在发送一个request body前等待100response,它必须发送一个期待100的头区。

。一个client决不能发送一个期待100的头区如果它不想发request body。

由于更老板本的存在,协议允许一个client发了期待100头区后没有受到417,100。因此,一个client发了期待100头区后就不应该无限等待request。

对HTTP/1。1server的要求:

l         当接收到一个包含expect “100-continue”头区的request时,origin server必须要么一100(Continue)状态返回并且继续从输入流中读,要么返回一个终止状态编码。Origin server 绝对不能在发送100response之前等待request body。如果它返回一个终止状态,它可以关闭连接或可以继续读但放弃request的剩余部分。它决不能执行request的方法如果它返回一个终止符。

l         一个origin server不应该发送一个100(continue)response,如果request 消息没有包含expect “100-continue”头区,并且也绝对不能发送这样的response如果request是来自一个HTTP/1。0(或更早版本的)client。有一个意外:为了和RFC2068兼容,一个server可以发送一个100状态在response中给一个HTTP/1。1put或post request,尽管没有包含expect “100-continue”头区。这个异常,只适用于HTTP/1。1request,并不适用于其他HTTP版本,目的就是减少client的等待时间。

l         一个origin server可以可以忽略100如果它已经接收到一些或全部的request body.

l         一个发送了一个100的origin server必须在收完body并且处理后发送一个final status code,除非它过早地终止连接。

l         如果一个origin server接收到一个未包含Expect 100头区的request,而又包含一个body,server在从连接读整个body前回以一个final status,那么server不应该关闭连接直到它读了整个request或直到client关闭了连接。否则,client不能可靠地接收response。然而,这个要求并不是说保护server免受服务拒绝攻击或错误的client实现。

对HTTP/1。1proxy的要求:

。如果一个代理接收到一个包含100期待的头区的request,代理要么知道要么不知道下一个server对HTTP1。1的兼容,它必须转发request,包括expect头区。

。如果proxy知道下一个server 支持http/1.0或更低,它决不能转发,而必须发挥417。

。Proxy应该维护一个关于最近接收的下一个server的HTTP版本号的缓存。

。一个proxy决不能返回100response给一个HTTP/1。0的client(不包含100-continue期待)。这个请求覆盖了转发1xx response的规则。

8.2.4 client在server过早关闭连接后的行为

如果一个HTTP/1。1client发送一个包含body的request,但是没有包含100头区期待,而且并不是直接连HTTP/1。1origin server,而且看到了从server过来的连接关闭,应该重试request。如果重试,它可以采用下面的2等幂算法来确保得到可靠连接:

1.  初始化一个到server的新连接

2.  发送request-headers

3.  初始化一个R,来存放到server 的来回是,如果不可得就设置成5s。

4.  计算T=R*(2**N),N是之前尝试重发的次数。

5.  等一个错误response或Ts

6.  如果没有接收到error response,Ts后发送request的body。

7.  Client看到连接被过早关闭,重复1步直到request被接收,或收到一个错误response,或client不耐烦关闭了尝试进程。

在任何错误状态被接收的点,client

l         不应该继续

l         应该关闭连接如果还没有完成发送request message

HTTP<6>
Posted on 2005-09-27 22:24 英雄 阅读(46) 评论(0)  编辑 收藏 收藏至365Key 所属分类: HTTP1.1协议中文翻译 
9 方法定义

HTTP/1.1通用方法的定义如下。虽然这个集合可以被扩展,但是并不能保证client和server拥有对扩展的相同定义。

HOST request-header头区必须存在于所有的HTTP/1。1request。

9.1 安全和等幂方法

9.1.1 安全方法

实现者要意识到软件代表了用户在Internet上的操作,应该认真地让用户知道他们可以采取的action会给他们自己和其他带来的影响。

特殊地,按约定GET,HEAD方法除获取资源外不应该有任何其他影响。这些方法应该被认为是安全的。这样处理就允许user agent去表现其他方法如POST,PUT,和DELETE,这样用户就可以意识到一个可能不安全的方法并request。

自然的,不可能保证server对GET方法不产生旁效应;事实上,一些动态资源把它作为一种特性。重要的区别是user并不要求旁效应,所以不必要为他们负责。

9.1.2 等幂方法

方法也可以具有等幂特性,这样的N>0个request的旁效应是一致的。方法GET,HEAD,PUT,DELETE都有这个特性。同样OPTIONS,TRACE SHOULD NOT也有旁效应,也天生等幂。

但是,游客能一个request序列是不等幂的,即使所有的方法单独是等幂的。(一个序列是等幂的当且整个序列的执行的结果和再次执行全部,部分是一样的。)例如,一个序列是不等幂的,如果它的结果依赖一个值,而这个值在这个序列中会被修改的。

一个没有旁效应的序列是等幂的,根据定义。(前提是没有并发的操作会在同一个资源集上被执行)。

9.2 options

用来代表一个request来请求关于request-uri标记的request/response链所对应的可用的通讯选项。这个方法允许client去确定和一个资源或一个server相关的选项或要求,而不用去应用一个资源action或初始化一个资源获取。

对于这个方法的response是不能缓存的。

如果options request 包含一个entity-body,那么media type必须由Content-Type区来指示。虽然这个规范并没有为这样一个body定义任何用处,HTTP的未来扩展可以使用它来向server做更细节的查询。一个并不支持这样一个扩展的server可以丢弃这个request body。

如果Request-URI是一个*,OPTIONS request是用来应用给server而不是给一个特定资源。因为一个server的通讯选项一般依靠于资源,* request和“ping”或“no-op”方法的作用类似;除了测试server的接受力外并不做任何其他事情。例如,这个可以用来测试一个代理对HTTP/1。1的兼容性。

如果Request-URI不是一个*,OPITONS request只是指那些能和那个资源交流的选项上。

一个200 response应该包含任何头区来指示server和那个资源可用的特征,也可能包含没有在这个规范中定义的扩展。Response body也应该包含交流选项的信息。这样一个body的格式并没有在这篇规范里被定义,但是可以在HTTP的未来扩展中被定义。Content negotiation

可以被用来选择合适的response 格式。如果没有response body被包含,response必须包含一个Content-Length=0。

Max-Forwards请求头区可以被用在一个request chain上的一个特殊代理。当一个代理在一个absoluteURI接收到一个request forwarding被允许的OPTONS request,proxy必须检查Max-Forwards值。如果Max-Forwards

值是0,proxy绝不能传递message,应该response自己的通讯选项。如果Max-Forwards是一个大于0的值,proxy必须在它传递request的时候降低该值。如果在request 中没有出现Max-Forwards,那么被传递的request决不能包含一个Max-Forwards区。

9.3 GET

GET方法意思是得到URI标记的信息。如果URI只一个数据处理进程,那么处理后的数据是应该在response的entity中被返回的而不是源文件,除非结果正好是那个处理进程的源文件。

如果包含If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range那么GET方法的寓意就变成了“conditional GET”。一个conditional GET方法请求entity只在描述的条件下才被传输。条件GET方法通过避免传递被client held的数据来允许刷新缓存entity以降低网络的使用。

GET 方法的语义在Range头区被包含在request之后改为“partial GET”。它只要求entity的一部分被传递。它也是通过完成entity而部分传递(例如为了避免传递client已经存在的数据)来降低网络负荷。

GET request的response是可以缓存的当且仅当它满足HTTP缓存的要求(sec13)。

看section 15.1.3当使用表单时考虑安全因素。

9.4 HEAD

HEAD方法等同于GET除了server决不能在一个response中返回一个message-body。而在header包含的元数据信息应该和对GET的相同。这个方法可以被用来得到关于entity的元信息而不用得到entity。这个方法通常被用来测试超链接的有效性,可进入性,和最近的修改。

对一个HEAD request的response可以是可缓存的,这样在response的信息可以被用来更新关于那个资源的先前的缓存entity。如果新的区指示缓存entity和当前的不同那么缓存必须认为这个entity是过时的。

9.5 POST

用来请求origin server来接受在request中包裹的entity作为URI标记资源的下属资源。POST被设计成包含下面的功能:

l         存在资源的直接

l         发布一个消息给一个公告牌,新闻组,邮件列表,或类似的文章组

l         提供一个数据块,想提交一个表单的结果,给一个数据处理进程

l         扩展一个数据库通过一个附加的操作

POST方法实际执行的功能取决于server并且通常依赖于URI。post的entity从属于URI,这就象一个文件从属于一个包含它的目录,一个新闻文章从属于一个被post的新闻组,或一条记录从属于一个数据库。

由post方法得到的结果可能不会得到一个结果。在这种情况下,或者200(OK)或者204(没有内容)作为response的status,这依靠于是否response包含一个描述结果的实体。

如果一个资源已经被origin server创建,response应该是201(Created)并且包含一个entity来描述request的status,并指向新资源和一个Location header(sec14.30)。

对这个方法的Response是不缓存的,除非它包含合适的Cache-Control或Expires。但是,303response可以被使用来引导user agent去得到一个缓存的资源。

Post request必须遵守消息传递要求(sec8.2)。

看sec15.1.3来获得安全考虑。

9.6 PUT

Put方法要求包含的entity在URI之下被存储。如果URI指向一个已经存在的资源,entity应该被认为是一个对已经存在的资源的修改版本。如果URI并没有指向一个已经存在的资源,并且那个URI能够被user agent定义为一个新资源,origin server能够创建那个URI对应的资源。如果一个新资源被创建,origin server必须通知user agent通过201(Created)。如果一个存在资源被修改了,或者200或者204应该被发送来指示request的成功完成。如果resource不能被创建或修改,那么一个合适的错误response应该给出来以反映问题。一个entity的接收者决不能忽略任何它不理解或实现的Content-* (e.g. Content-Range)头区,必须返回一个501response。

如果request通过一个cache,并且URI标记一个或更多个缓存entity,那些entity应该被认为是过时的。Response不缓存。

在POST和PUT请求之间的重要区别是URI的不同含义。在POST request的标记资源将会处理entity。这个资源可能是一个数据接受进程,一个去一些其他协议的网关,或一个接收注解的单独的entity。相比之下,在put request的URI标记entity本身。User agent知道哪个URI适合,而且server决不能试图去应用这个request给一些其他资源。如果server想要request去指一个不同的URI,它必须发送一个301response;user agent可以关于是否重定向request做它自己的决定。

一个单个的资源可以不同的URI标记。例如,一个文件可以有一个URI来标记当前版本,这是从URIFor example, an article might have a URI for identifying “the current version” which is separate from the URI identifying each particular version. In this case, a PUT request on a general URI might result in several other URIs being defined by the origin server.

HTTP/1。1没有定义一个PUT方法如何影响一个orgin server的状态。

PUT request必须遵守SEC8。2描述的消息传输要求。

除非对一个特定entity-header做特殊标记,在PUT request的entity-header应该被应用到被PUT创建或修改的资源。

9.7 DELETE

DELETE方法请求origin server删除被URI标记的资源。这个方法可以被在origin server上的手工操作冲突。即使返回的状态码标记action被成功完成,client不能保证action被成功完成。但是,server不应该指示成功,除非在response被给出的时候,它试图删除资源或把它移动到一个不可进入的地方。

一个成功的response应该是200,如果response包含一个描述状态的试题,202如果action还没有被actted,或204如果已经act但还没有包含entity。

如果request 经过一个cache并且URI标记1个或多个缓存体,那些entries应该被认为是过时的。 Response不能缓存。

9.8 Trace

Trace方法被用来唤醒一个远端的应用层的request message的转回来。最后一个request的接收者要把request作为200response的entity返回给client。最后的接收者可能是一个server,1st proxy,gateway接收到了Max-Forwards=0的request。一个Trace request 绝对不能包含一个entity。

Trace允许client去看到在request chain的另一端什么被接受并使用那些数据来做测试或诊断。Via的使用很有意思,因为它作为chain的trace。使用Max-Forwards可以限制chain长度,这对测试在一个无限循环的proxy chain很有用。

如果一个request是有效的,response应该包含整个的request message在body,Content-Type=“message/http”.不能缓存。

9.9 CONNECT

这个规范保留了CONNECT方法,它原用来让一个proxy动态成为一个tunnel(SSL tunneling [44]).

10 Status Code Definitions

每一个status-Code被在下面描述,包括一个描述关于什么方法可以被反馈,和任何关于response的元数据信息。

10.1 Informational 1xx

这一类状态编码代表一个临时的response,由status-line和一个可选的头部组成,由一个空行结束。对这一类状态代码没有必需的头部。因为HTTP/1。0没有定义任何1xx状态码,server决不能发送一个1xx  response给一个HTTP/1。0client除非在实验条件下。

一个client必须准备好在一个常规response前接受1个或多个1xx状态的response,即使client不期待一个100(Continue)状态的message。未被期待的1xx状态的response会被一个user agent忽略。

代理必须传递一个1xx response,除非在proxy和client之间的连接被关闭了,或者除非proxy本身要求产声一个1xxresponse。

10.2 Successful 2xx

这一类状态编码意思是client的request被成功接收,理解,接受。

10.3 Redirection 3xx

这一类状态编码意思是更多的action需要被user agent执行来满足request。可以由user agent在没有用户的操作下进行,前提是在第2个request中的方法是GET或HEAD.一个client应该侦测无限的redirection循环,因为这样的循环对每一个redirection产生网络负载。

注意:先前版本的规范推荐最大5个redirection。内容开发者应该意识到可能有用户实现这样一个固定限制。

10.4 Client Error 4xx

4xx的状态码是被用在client看起来出错的情况下。除了对head request,server应该包含一个entity来包含错误情况,和是否这是一个临时或持久的条件。这些状态码对任何request method都可用。User agents应该对user展现所有包含的entity。

如果client正在发送data,一个使用TCP的server的实现应该仔细保证client认识到包含response的package的接收到在server关闭输入连接前。如果client在close后持续发送数据给server,server的TCP栈会发送一个reset packet给client,这将擦去client发过来的没有接收到的输入缓存在他们被HTTP应用读和解释之前。

10.5 Server Error 5xx

表示server本身意识到它有错或不能执行request。除了对HEAD request,server应该包含一个entity来包含对错误情况的解释,和这是否一个临时或持久的情况。User agent应该表现任何包含的entity给用户。这些response code对任何request 方法都是可用的。

11 Access Authentication

HTTP提供了几个可选的challenge-response认证机制,用来供一个server来要求一个client的request,client来提供认证信息。“HTTP Authentication:Basic and Digest Access Authentication” [43]定义了通用的进入认证框架和基本的以及摘要的认证。这个规范吸收了“challenge” 和“credentials”的概念。

http(大纲)<7>
Posted on 2005-10-07 17:49 英雄 阅读(41) 评论(1)  编辑 收藏 收藏至365Key 所属分类: HTTP1.1协议中文翻译 
13 Caching in HTTP

HTTP多应用于分布式信息系统,通过使用response缓存来提高性能。HTTP/1.1包括许多元素来使缓存发挥作用成为可能。

Cache的目的和机制概述。

关于降低语义透明度。

13.1.1 Cache Correctness

返回最新response:满足的条件

    如果无法做到,那么应该返回error,warning

    对stale的response的处理

13.1.2 Warnings

产生时机,目的

    2类warning

13.1.3 Cache-control Mechanisms

可以在request和response提供显示控制字段

13.1.4 Explicit User Agent Warnings

对于用户指定的cache机制user agent应该加以warning

13.1.5 Exceptions to the Rules and Warnings

   有些时候允许cache发回statle response;同时也允许user agent来通过1步1步地得到first-hand或者fresh的response。

13.1.6 Client-controlled Behavior

   可以指定可以接受的response的expiration information。

13.2 Expiration Model

13.2.1 Server-Specified Expiration

  HTTPserver如何让缓存工作得很好,expiration time。

13.2.2 Heuristic Expiration

  启发式的时间标记

13.2.3 Age Calculations

13.2.4 Expiration Calculations

13.2.5 Disambiguating Expiration Values

出现了多个cache为同一个资源包含多个fresh values。

13.2.6 Disambiguating Multiple Responses

如果client从多个cache收到了多个response

13.3 Validation Model

校验一个stale response是否可用,通过cache validators.

13.3.1 Last-Modified Dates

用来作为cache validators

13.3.2 Entity Tag Cache Validators

用来提供非last-modified date的校验素

13.3.3 Weak and Strong Validators

语义上重大改变才改变的是weak Validators

13.3.4 Rules for When to Use Entity Tags and Last-Modified Dates

13.3.5 Non-validating Conditionals

为什么采用那种ET,而不用其他header

13.4 Response Cacheability

在什么情况下缓存response。

13.5 Constructing Responses From Caches

13.5.1 End-to-end and Hop-by-hop Headers

分成2类,一类是必须在client和server之间传递,一类是在一次连接2端传递

13.5.2 Non-modifiable Headers

不可修改的头

13.5.3 Combining Headers

合并起来作为response的一部分

13.5.4 Combining Byte Ranges

Cache组合得到的range。

13.6 Caching Negotiated Responses

关于Negotiated Responses如何缓存

13.7 Shared and Non-Shared Caches

针对某一个user的cache是shared caches

13.8 Errors or Incomplete Response Cache Behavior

如何面对部分的response和server的5xx

13.9 Side Effects of GET and HEAD

对于get,head方法,旁效应和是否缓存的关系

13.10 Invalidation After Updates or Deletions

如果origin server变了,如何及时通知cache

13.11 Write-Through Mandatory

除了get 和head方法都必须要wirte through

13.12 Cache Replacement

插入新缓存替代旧缓存

13.13 History Lists

历史并不试图保证最新的请求资源

15 Security Considerations

关于HTTP1.1的安全考虑

15.1 Personal Information

关于客户端隐私信息分发的问题

15.1.1 Abuse of Server Log Information

在server上存储的客户信息

15.1.2 Transfer of Sensitive Information

敏感信息的传递应该给user足够的控制

15.1.3 Encoding Sensitive Information in URI’s

必须要考虑post和get方法在安全上的区别。Get方法是会编码到URI中的

15.1.4 Privacy Issues Connected to Accept Headers

在Accept Headers一些隐私

15.2 Attacks Based On File and Path Names

不返回不想给的文件

15.3 DNS Spoofing

Client如果缓存dns,应该观察ttl。

15.4 Location Headers and Spoofing

如果server是多organization,注意Location和Content-Location头区。

15.5 Content-Disposition Issues

虽然不是http内容,但被广泛实现,有很多安全考虑

15.6 Authentication Credentials and Idle Clients

关于认证缓存后可否再次更新

15.7 Proxies and Caching

受攻击的对象;同时注意LOG系统;cache proxy更加容易受到攻击;可以使用密码术来增强安全性,但是这不属于HTTP协议的内容。

15.7.1 Denial of Service Attacks on Proxies

还在研究



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

 
展开阅读全文

没有更多推荐了,返回首页