RFC1945 超文本传输协议--HTTP/1.0 之一

组织:中国互动出版网(http://www.china-pub.com/)
RFC文档中文翻译计划(http://www.china-pub.com/compters/emook/aboutemook.htm)
E-mail:ouyang@china-pub.com
译者:黄晓东(黄晓东  xdhuang@eyou.com)
译文发布时间:2001-7-14
版权:本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载,但必须
保留本文档的翻译及版权信息。




Network Working Group                                        T. Berners-Lee
Request for Comments: 1945                                        MIT/LCS
Category: Informational                                            R. Fielding
                                                               UC Irvine
                                                              H. Frystyk
                                                                 MIT/LCS
                                                                May 1996


超文本传输协议 -- HTTP/1.0
(Hyptertext Transfer Protocol – HTTP/1.0)

关于下段备忘(Status of This Memo)
	
本段文字为Internet团体提供信息,并没有以任何方式指定Internet标准。本段文字没
有分发限制。

IESG提示(IESG Note):
	IESG已在关注此协议,并期待该文档能尽快被标准跟踪文档所替代。

摘要(Abstract)
	HTTP(Hypertext Transfer Protocol)是应用级协议,它适应了分布式超媒体协作系统对
灵活性及速度的要求。它是一个一般的、无状态的、基于对象的协议,通过对其请求方法
(request methods)进行扩展,可以被用于多种用途,比如命名服务器(name server)及分
布式对象管理系统。HTTP的一个特性是其数据表现类型允许系统的构建不再依赖于要传输
的数据。
	HTTP自从1990年就在WWW上被广泛使用。该规范反映了“HTTP/1.0”的普通用法。




目录(Table of Contents)
1.  介绍(Introduction)	6
1.1  目的(Purpose)	6
1.2  术语(Terminology)	6
1.3  概述(Overall Operation)	8
1.4  HTTP and MIME	9
2.  标志转换及通用语法(Notational Conventions and Generic Grammar)	9
2.1  补充反馈方式(Augmented BNF)	9
2.2  基本规则(Basic Rules)	10
3.  协议参数(Protocol Parameters)	12
3.1  HTTP版本(HTTP Version)	12
3.2  统一资源标识(Uniform Resource Identifiers)	13
3.2.1 一般语法(General Syntax)	13
3.2.2 http URL	14
3.3  Date/Time 格式(Date/Time Formats)	15
3.4  字符集(Character Sets)	16
3.5  内容译码(Content Codings)	16
3.6  介质类型(Media Types)	17
3.6.1标准及文本缺省(Canonicalization and Text Defaults)	18
3.6.2 多部分类型(Multipart Types)	18
3.7  产品标识(Product Tokens)	19
4.  HTTP 消息(HTTP Message)	19
4.1  消息类型(Message Types)	19
4.2  消息标题(Message Headers)	20
4.3  普通标题域(General Header Fields)	20
5. 请求(Request)	21
5.1  请求队列(Request-Line)	21
5.1.1 方法(Method)	22
5.1.2 请求URI(Request-URI)	22
5.2  请求标题域(Request Header Fields)	23
6.  回应(Response)	23
6.1  状态行(Status-Line)	24
6.1.1 状态代码和原因分析(Status Code and Reason Phrase)	24
6.2  回应标题域(Response Header Fields)	25
7.  实体(Entity)	26
7.1  实体标题域(Entity Header Fields)	26
7.2  实体主体(Entity Body)	26
7.2.1 类型(Type)	27
7.2.2 长度(Length)	27
8.  方法定义(Method Definitions)	27
8.1  GET	28
8.2  HEAD	28
8.3  POST	28
9.  状态代码定义(Status Code Definitions)	29
9.1  消息1xx(Informational 1xx)	29
9.2  成功2xx(Successful 2xx)	29
9.3  重定向(Redirection 3xx)	30
9.4  客户端错误(Client Error )4xx	31
9.5  服务器错误(Server Error )5xx	32
10.  标题域定义(Header Field Definitions)	33
10.1  允许(Allow)	33
10.2  授权(Authorization)	34
10.3  内容编码(Content-Encoding)	34
10.4  内容长度(Content-Length)	34
10.5  内容类型(Content-Type)	35
10.6  日期(Date)	35
10.7  过期(Expires)	36
10.8  来自(From)	37
10.9  从何时更改(If-Modified-Since)	37
10.10  最近更改(Last-Modified)	38
10.11  位置(Location)	38
10.12  注解(Pragma)	39
10.13 提交方(Referer)	39
10.14  服务器(Server)	40
10.15  用户代理(User-Agent)	40
10.16  WWW-授权(WWW-Authenticate)	40
11.  访问鉴别(Access Authentication)	41
11.1  基本授权方案(Basic Authentication Scheme)	42
12.  安全考虑(Security Considerations)	43
12.1  客户授权(Authentication of Clients)	43
12.2  安全方法(Safe Methods)	43
12.3  服务器日志信息的弊端(Abuse of Server Log Information)	43
12.4  敏感信息传输(Transfer of Sensitive Information)	44
12.5  基于文件及路径名的攻击(Attacks Based On File and Path Names)	44
13.  感谢(Acknowledgments)	45
14. 参考书目(References)	45
15.  作者地址(Authors' Addresses)	47
附录(Appendices)	48
A.  Internet介质类型消息/http(Internet Media Type message/http)	48
B.  容错应用(Tolerant Applications)	48
C.  与MIME的关系(Relationship to MIME)	49
C.1  转换为规范形式(Conversion to Canonical Form)	49
C.2  日期格式转换(Conversion of Date Formats)	49
C.3  内容编码介绍(Introduction of Content-Encoding)	50
C.4  无内容传输编码(No Content-Transfer-Encoding)	50
C.5  多个主体的HTTP标题域(HTTP Header Fields in Multipart Body-Parts)
	50
D.  附加特性(Additional Features)	50
D.1  附加请求方法(Additional Request Methods)	51
D.2  附加标题域定义(Additional Header Field Definitions)	51

  
1.  介绍(Introduction)
1.1  目的(Purpose)
	HTTP(Hypertext Transfer Protocol)是应用级协议,它适应了分布式超媒体协作系统对
灵活性及速度的要求。它是一个一般的、无状态的、基于对象的协议,通过对其请求方法
(request methods)进行扩展,可以被用于多种用途,比如命名服务器(name server)及分
布式对象管理系统。HTTP的一个特性是其数据表现类型允许系统的构建不再依赖于要传输
的数据。
	HTTP自从1990年就在WWW上被广泛使用。该规范反映了“HTTP/1.0”的普通用法。
	该规范描述了在大多数HTTP/1.0客户机及服务器上看起来已经实现的特性。规范将被
分成两个部分:HTTP特性的实现是本文档的主要内容,而其它不太通行的实现将被列在附
录D中。
	实用的信息系统需要更多的功能,而不仅仅是数据的获取,包括搜索、前端更新及注解。
HTTP允许使用开放的命令集来表示请求的目的,它使用基于URI[2](Uniform Resource 
Identifier),即统一资源标识的规则来定位(URL[4])或命名(URN[16])方法所用到的资
源。HTTP使用与邮件(Internet Mail [7])和MIME(Multipurpose Internet Mail Extensions [5])
相似的格式来传递消息。
	HTTP也作为用户代理、代理服务器/网关与其它Internet协议进行通讯的一般协议,这
些协议是,SMTP [12], NNTP [11], FTP [14], Gopher [1], and WAIS [8]等。HTTP允许不同的
应用可以进行基本的超媒体资源访问,并简化用户代理的实现。1.2  术语(Terminology)
	本规范用了许多与参与方、对象及HTTP通讯相关的术语,如下:
连接(connection)
	两个应用程序以通讯为目的在传输层建立虚拟电路。
消息(message)
HTTP通讯的基本单元,在连接中传输的结构化的、有顺序的字节(其含义在第四
节中定义)。

请求(request)
		HTTP的请求消息(在第五节定义)
回应(response)
		HTTP的回应消息(在第六节定义)
资源(resource)
		网络上可以用URI来标识的数据对象或服务(见3.2节)
	实体(entity)
可被附在请求或回应消息中的特殊的表示法、数据资源的表示、服务资源的回应等,
由实体标题(entity header)或实体主体(entity body)内容形式存在的元信息组成。
客户端(client)
	指以发出请求为目的而建立连接的应用程序。
用户代理(user agent)
指初始化请求的客户端,如浏览器、编辑器、蜘蛛(web爬行机器人)或其它终端
用户工具。
服务器(server)
		指接受连接,并通过发送回应来响应服务请求的应用程序。
原始服务器(origin server)
		存放资源或产生资源的服务器。
代理(proxy)
同时扮演服务器及客户端角色的中间程序,用来为其它客户产生请求。请求经过变
换,被传递到最终的目的服务器,在代理程序内部,请求或被处理,或被传递。代
理必须在消息转发前对消息进行解释,而且如有必要还得重写消息。代理通常被用
作经过防火墙的客户端出口,用以辅助处理用户代理所没实现的请求。
网关(gateway)
服务器之间的服务器。与代理不同,网关接受请求就好象它就是被请求资源所在的
原始服务器,发出请求的客户端可能并没有意识到它在与网关进行通讯。网关是网
络防火墙服务器端的门户。对非HTTP系统资源进行访问时,网关做为中间的协议
翻译者。
隧道(tunnel)
隧道就好象连接两端看不见的中继器。处于激活状态时,它虽然是由HTTP请求来
初始化的,但它并不参与HTTP通讯。当需要中继连接的两端关闭后,隧道也自然
终止。在入口有需求及中间程序无法或不该解释要中继的通讯时,通常要用到隧道
技术。
缓存(cache)
		指程序本地存储的回应消息和用来控制消息存储、重获、删除的子系统。

缓存回应的目的是为减少请求回应时间,以及未来一段时间对网络带宽的消耗。任
何客户端及服务端都可以包含缓存。服务器在以隧道方式工作时不能使用缓存。
		
任何指定的程序都有能力同时做为客户端和服务器。我们在使用这个概念时,不是看程
序功能上是否能实现客户及服务器,而是看程序在特定连接时段上扮演何种角色(客户或服
务器)。同样,任何服务器可以扮演原始服务器、代理、网关、隧道等角色,行为的切换取
决于每次请求的内容。

1.3  概述(Overall Operation)
	HTTP协议是基于请求/回应机制的。客户端与服务器端建立连接后,以请求方法、URI、
协议版本等方式向服务器端发出请求,该请求可跟随包含请求修饰符、客户信息、及可能的
请求体(body)内容的MIME类型消息。

	服务器端通过状态队列(status line)来回应,内容包括消息的协议版本、成功或错误代
码,也跟随着包含服务器信息、实体元信息及实体内容的MIME类型消息。
	绝大多数HTTP通讯由用户代理进行初始化,并通过它来组装请求以获取存储在一些原
始服务器上的资源。在最简单的情况下,通过用户代理(UA)与原始服务器(O)之间一
个简单的连接(v)就可以完成。

          request chain ------------------------>
       UA -------------------v------------------- O
          <----------------------- response chain

	更复杂的情况是当请求/回应链之间存在一个或更多中间环节。总体看来,有三种中间
环节:代理(proxy)、网关(gateway)、隧道(tunnel)。
代理(proxy)是向前推送的代理人(agent),它以绝对形式接收URI请求,重写全部
或部分消息,并将经过改写的请求继续向URI中指定的服务器处推送。
网关是接收代理,它处于服务器层之上,在必要时候,它用服务器可识别的协议来传递
请求。
隧道不改变消息,它只是连接两端的中继点。在有中间层(如防火墙)或中间层无法解
析消息内容的情况下,需要靠隧道技术来帮助通讯穿越中间层。

           request chain -------------------------------------->
       UA -----v----- A -----v----- B -----v----- C -----v----- O
           <------------------------------------- response chain

	上面的图形表示在用户代理和原始服务器之间有三个中间层(A,B和C)。由图可见,
请求或回应消息在整个信息链上运行需要通过四个单独的连接,它与在此之前介绍的简单情
况是有区别的,而且此区别是十分重要的。因为HTTP通讯选项可以设置成几种情况,如只
与最近的非隧道邻居连接、只与信息链末端连接、或者可与链中全部环节连接等等。虽然上
面的图是线性的,而实际上每个参与环节都在同时与多方进行通讯活动。例如,B在接受除
A之外其它客户端请求的同时,向除C之外的其它服务器推送请求,在这个时刻,它可能
接受到A的请求,并给予处理。
	参与通讯的任何一方如果没有以隧道方式进行工作,必须要借助内部缓存机制来处理请
求,如果链上某个参与方碰巧缓存了某个请求的回应,那就相应于缩短了请求/回应链。下
面的图例演示了当B缓存了从O经由C过来的回应信息,而UA和A没缓存的情况:



          request chain ---------->
       UA -----v----- A -----v----- B - - - - - - C - - - - - - O
          <--------- response chain

	并非所有的回应都可以被缓存,某些请求所包含的修饰符中可能对缓存行为进行了特别
指明。一些基于HTTP/1.0的应用使用了启发式的方法来描述哪些回应可被缓存,而哪些则
不可以,但遗憾的是,这些规则并没有形成标准。
	在Internet上,HTTP通讯往往基于TCP/IP的连接方式。缺省的端口是TCP 80[15]口,
但也可以使用其它端口。并不排除基于Ineternet上的其它协议或网络协议的HTTP实现方
式,HTTP只是假定传输是可靠的,因而任何能提供这种保证的协议都可以被使用。至于
HTTP/1.0请求和回应在数据传输过程中的数据结构问题,不在本文讨论范围之内。
	实验室应用除外,当前的做法是客户端在每次请求之前建立连接,而服务器端在发送回
应后关闭此连接。不管客户端还是服务器端都应注意处理突发的连接中断,因为双方都有可
能因为用户操作、自动超时、程序失败等原因关闭与对方的连接。在这种情况下,不管请求
处于什么样的状态,如单方或双方同时关闭连接,都会导致当前的请求被终止。

1.4  HTTP and MIME
	HTTP/1.0使用了多种结构来定义MIME,详见RFC1521[5]。附录C描述了Internet承
认的Internet介质类型与mail介质类型的不同工作方式,并给出二者区别的基本解释。
	
2.  标志转换及通用语法(Notational Conventions and 
Generic Grammar)
2.1  补充反馈方式(Augmented BNF)
	与RFC822[7]很类似,本文对所有机制的说明都是以散文和补充反馈的方式来描述的。
对于实现者来说,要想理解这些约定,必须对这些符号很熟悉。补充反馈方式(augmented 
BNF)包括下面的结构:

要解释的名词=名词解释(name = definition)
规则的名字(name)就是它本身(不带任何尖括号,“<”,“>”),后面跟个等号=,
然后就是该规则的定义。如果规则需要用多个行来描述,利用空格进行缩进格式排
版。某些基本的规则使用大写,如SP, LWS, HT, CRLF, DIGIT, ALPHA,等等。定义
中还可以使用尖括号来帮助理解规则名的使用。

字面意思("literal")
		文字的字面意思放在引号中间,除非特别指定,该段文字是大小写敏感的。

规则1|规则2(rule1 | rule2)
		“|”表示其分隔的元素是可选的,比如,“是|否”要选择‘是’或‘否’。

(规则1 规则2)((rule1 rule2))
在圆括号中的元素表明必选其一。如(元素1(元素2|元素3)元素4)可表明两
种意思,即“元素1 元素2 元素4”和“元素1 元素3 元素4”

*规则(*rule)
在元素前加星号“*”表示循环,其完整形式是“<n>*<m>元素”,表明元素最少产
生<n>次,最多<m>次。缺省值是0到无限,例如,“1*元素”意思是至少有一个,
而“1*2元素”表明允许有1个或2个。

[规则]([rule])
方括号内是可选元素。如“[元素1 元素2]”与“*1(元素1 元素2)”是一回
事。

N 规则(N rule)
表明循环的次数:“<n>(元素)”就是“<n>*<n>(元素)”,也就是精确指出<n>
取值。因而,2DIGIT 就是2位数字, 3ALPHA 就是由三个字母组成字符串。

#规则(#rule)
“#”与“*”类似,用于定义元素列表。

完整形式是“<n>#<m>元素”表示至少有<n>个至多有<m>个元素,中间用“,”或
任意数量的空格(LWS-linear whitespace)来分隔,这将使列表非常方便,如“(*LWS 
元素 *( *LWS "," *LWS 元素 ))”就等同于“1#元素”。

空元素在结构中可被任意使用,但不参与元素个数的计数。也就是说,“(元素1),,
(元素2)”仅表示2个元素。但在结构中,应至少有一个非空的元素存在。缺省
值是0到无限,即“#(元素)”表示可取任何数值,包括0;而“1#元素”表示至
少有1个;而“1#2元素”表示有1个或2个。 

;注释(; comment)
		分号后面是注释,仅在单行使用。

隐含*LWS(implied *LWS)
本文的语法描述是基于单词的。除非另有指定,线性空格(LWS)可以两个邻近符
号或分隔符(tspecials)之间任意使用,而不会对整句的意思造成影响。在两个符号之
间必须有至少一个分隔符,因为它们也要做为单独的符号来解释。实际上,应用程序在
产生HTTP结构时,应当试图遵照“通常方式”,因为现在的确有些实现方式在通常方
式下无法正常工作。

2.2  基本规则(Basic Rules)
下面的规则将用于本文后面对结构基本解析。
US-ASCII 编码字符集定义[17]。

OCTET			= <8-bit的顺序数据,即bytes>
CHAR			= < US-ASCII字符(取值为0 – 127的OCTET)>
UPALPHA		= < US-ASCII 大写字符"A"到"Z">
LOALPHA		= <US-ASCII 小写字符"a"到"z">

       ALPHA		= UPALPHA | LOALPHA
       DIGIT		= < US-ASCII 数字"0"到"9">
       CTL			= < US-ASCII 控制字符(取值0到31的octet )和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.0规定,除实体主体(Entity-Body,见附录B容错应用)外,所有协议元
素的行结束标志都是CRLF(按字节顺序)。在实体主体内部的行结束标志定义及
其对应的介质类型定义,见3.6节的描述。

CRLF		= CR LF

HTTP/1.0的头可以折成许多行,只要每个后续行以空格或水平制表符开头。所有
的线性空格(LWS),同空格(SP)有相同的语义。

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

实际上,有些应用并没有考虑处理这样多行的头,所以从兼容性上考虑,HTTP/1.0
应用最好不要产生折成多行的头。

TEXT规则只是用于描述消息解释器不关心的域的内容及其取值。文本内容可包含
不同于US-ASCII的字符。

TEXT		= <除了控制字符(CTLs)之外的任何OCTET,包括LWS >
		
在标题域中的收件人域如包含US-ASCII字符集以外的字符,这些字符将按照
ISO-8859-1标准来解释。

十六进制数字型字符在几个协议元素中到。

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

许多HTTP/1.0头域的内容由被LWS分隔的单词或特殊字符组成,这些特殊字符
必须置于引号中间的字符串内,作为参数值使用。

Word		= 符号(token)| 被引号引起来的字符串

token		= 1*<除控制字符(CTLs)或tspecials之外的任意字符>

tspecials	    = "(" | ")" | "<" | ">" | "@"
                      | "," | ";" | ":" | "\" | <">
                      | "/" | "[" | "]" | "?" | "="
                      | "{" | "}" | SP | HT
		
在HTTP头域中可用括号表示注释文字。注释只允许写在包含注释的域,做为域值
定义的一部分。在除此之外其它域中,括号将被视为域值。

comment		= "(" *( ctext | comment ) ")"
ctext			= <除圆括号外的任何TEXT>

被双引号圈中的文本字符串将被视为一个单词。

quoted-string	= ( <"> *(qdtext) <"> )
qdtext		= <除了双引号及控制字符之外的任何字符,包括LWS >

		在HTTP/1.0中不允许使用后斜线“\”来引用单字符。

3.  协议参数(Protocol Parameters)
3.1  HTTP版本(HTTP Version)
	
	HTTP采用主从(<major>.<minor>)数字形式来表示版本。协议的版本政策倾向于让发
送方表明其消息的格式及功能,而不仅仅为了获得通讯的特性,这样做的目的是为了与更高
版本的HTTP实现通讯。只增加扩展域的值或增加了不影响通讯行为的消息组件都不会导致
版本数据的变化。当协议消息的主要解析算法没变,而消息语法及发送方的隐含功能增加了,
将会导致从版本号(<minor>)增加;当协议中消息的格式变化了,主版本号(<major>)也
将发生改变。
	HTTP消息的版本由消息第一行中的HTTP版本域来表示。如果消息中的协议版本没有
指定,接收方必须假定它是符合HTTP/0.9的简单标准。

HTTP-Version		= "HTTP" "/" 1*DIGIT "." 1*DIGIT
		
注意,主从版本应当被看作单独的整数,因为它们都有可能增加,从而超过一位整
数。因而,HTTP/2.4比HTTP/2.13版本低,而HTTP/2.13又比HTTP/12.3版本低。
版本号前面的0将被接收方忽略,而在发送方处也不应产生。
		
本文档定义了HTTP协议的0.9及1.0版本。发送完整请求(Full-Request)及完整
回应(Full-Response)消息的应用必须指明HTTP的版本为“HTTP/1.0”。

HTTP/1.0服务器必须:

o识别HTTP/0.9及HTTP/1.0请求命令中的请求队列(Request-Line)的格式。
o理解任何HTTP/0.9及HTTP/1.0中的合法请求格式。
o 使用与客户端相同版本的协议进行消息回应。

HTTP/1.0 客户端必须:

      o 识别HTTP/1.0回应中状态队列(Status-Line)的格式。
o 理解HTTP/0.9及HTTP/1.0中合法回应的格式。

	当代理及网关收到与其自身版本不同的HTTP请求时,必须小心处理请求的推送,因为
协议版本表明发送方的能力,代理或网关不应发出高于自身版本的消息。如果收到高版本的
请求,代理或网关必须降低该请求的版本,并回应一个错误。而低版本的请求也应在被推送
前升级。
代理或网关回应请求时必须遵照前面列出的规定。

3.2  统一资源标识(Uniform Resource Identifiers)

	URI有许多名字,如WWW地址、通用文件标识(Universal Document Identifiers)、通
用资源标识(Universal Resource Identifiers [2]),以及最终的统一资源定位符(Uniform 
Resource Locators (URL) [4])和统一资源名(URN)。在涉及HTTP以前,URI用简单格式
的字符串描述-名字、位置、或其它特性,如网络资源。

3.2.1 一般语法(General Syntax)
	在HTTP中URI可以用绝对形式表示,也可用相对于某一基本URI[9]的形式表示,具
体取决于它们的使用方式。这两种形式的不同在于绝对URI总是以方法名称后跟“:”开头。

       URI			= ( absoluteURI | relativeURI ) [ "#" fragment ]

       absoluteURI	= scheme ":" *( uchar | reserved )

       relativeURI	= net_path | abs_path | rel_path

       net_path       = "//" net_loc [ abs_path ]
       abs_path       = "/" rel_path
       rel_path       = [ path ] [ ";" params ] [ "?" query ]

       path           = fsegment *( "/" segment )
       fsegment       = 1*pchar
       segment        = *pchar

       params         = param *( ";" param )
       param          = *( pchar | "/" )

       scheme         = 1*( ALPHA | DIGIT | "+" | "-" | "." )
       net_loc        = *( pchar | ";" | "?" )
       query          = *( uchar | reserved )
       fragment       = *( uchar | reserved )

       pchar          = uchar | ":" | "@" | "&" | "=" | "+"
       uchar          = unreserved | escape
       unreserved     = ALPHA | DIGIT | safe | extra | national

       escape         = "%" HEX HEX
       reserved       = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
       extra          = "!" | "*" | "'" | "(" | ")" | ","
       safe           = "$" | "-" | "_" | "."
       unsafe         = CTL | SP | <"> | "#" | "%" | "<" | ">"
       national       = <any OCTET excluding ALPHA, DIGIT,


                        reserved, extra, safe, and unsafe>
	权威的URL语法及语义信息请参见RFC1738[4]和RFC1808[9]。上面所提到的BNF中
包括了合法URL中不允许出现的符号(RFC1738),因为HTTP服务器并没有限制为只能用
非保留字符集中的字符来表示地址路径,而且HTTP代理也可能接收到RFC1738没有定义
的URI请求。

3.2.2 http URL

“http”表示要通过HTTP协议来定位网络资源。本节定义了HTTP URL的语法和语义。

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

host           = <合法的Internet主机域名或IP地址(用十进制数及点组成)
,见RFC1123,2.1节定义>

       port           = *DIGIT

	如是端口为空或没指定,则缺省为80端口。对于绝对路径的URI来说,拥有被请求的
资源的服务器主机通过侦听该端口的TCP连接来接收该URI请求。如果URL中没有给出
绝对路径,要作为请求URI(参见5.1.2节)使用,必须以“/”形式给出。

	注意:虽然HTTP协议独立于传输层协议,http URL只是标识资源的TCP位置,而对
于非TCP资源来说,必须用其它的URI形式来标识。
	
	规范的HTTP URL形式可通过将主机中的大写字符转换成小写(主机名是大小写敏感
的)来获得。如果端口是80,去掉冒号及端口号,并将空路径替换成“/”。

3.3  Date/Time 格式(Date/Time Formats)

	出于历史原因,HTTP/1.0应用允许三种格式来表示时间戳:

       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[6])。第二种格
式在普通情况下使用,但是它是基于已经废弃的RFC850[10]中的日期格式,而且年不是用
四位数字表示的。HTTP/1.0 客户端及服务器端在解析日期时可识别全部三种格式,但是它
们不可以产生第三种时间格式(asctime) 。
	注意:对于接收到由非HTTP应用产生的日期数据时,提倡对接收到的日期值进行填充。
这样做是因为,在某些时候,代理或网关可能通过SMTP或NNTP来获取或发送消息。
	所有的HTTP/1.0 date/timp时间戳必须用世界时间(Universal Time,UT),即格林威治
时间来表示(Greenwich Mean Time,GMT),没有任何修改的余地。前面的两种格式用了
“GMT”表示时区,在读ASC表示的时间时,也应假定是这个时区。

HTTP-date	= rfc1123-date | rfc850-date | asctime-date

rfc1123-date	= wkday "," SP date1 SP time SP "GMT"
rfc850-date	= weekday "," SP date2 SP time SP "GMT"
asctime-date	= wkday SP date3 SP time SP 4DIGIT
date1		= 2DIGIT SP month SP 4DIGIT
                     ; day month year (e.g., 02 Jun 1982)
date2		= 2DIGIT "-" month "-" 2DIGIT
                      ; day-month-year (e.g., 02-Jun-82)
date3		= month SP ( 2DIGIT | ( SP 1DIGIT ))
                      ; month day (e.g., Jun  2)
time			= 2DIGIT ":" 2DIGIT ":" 2DIGIT
                      ; 00:00:00 - 23:59:59
wkday		= "Mon" | "Tue" | "Wed"
                      | "Thu" | "Fri" | "Sat" | "Sun"
weekday		= "Monday" | "Tuesday" | "Wednesday"
                      | "Thursday" | "Friday" | "Saturday" | "Sunday"
month		= "Jan" | "Feb" | "Mar" | "Apr"
                      | "May" | "Jun" | "Jul" | "Aug"
                      | "Sep" | "Oct" | "Nov" | "Dec"
注意:HTTP要求只能在协议流中使用data/time时间戳格式,不要求客户端及服务
器端在用户描述、请求登录等情况下使用这类格式。
3.4  字符集(Character Sets)

	HTTP所使用的字符集定义和描述MIME时用的相同:
本文档用字符集(character set)来指明利用一个或多个表将顺序字节转换成顺序字
符的方法。注意,不需要其它方向的无条件转换,因为不是所有的字符都可以用给
定字符集来表示,同时,一个字符集也可能提供一种以上的字节顺序来表示一种特
殊的字符。这种定义倾向于允许不同类型的字符编码通过简单的单表映射来实现,
如,从表US-ASCII切换到复杂表如ISO2202。实际上,与MIME字符集名相关的
定义必须完整指定从字节到字符的映射,特别是不允许通过利用外部配置信息来确
定精确的映射。

注意:术语字符集(character set)归于字符编码(character encoding)。事实上,
由于HTTP与MIME共同使用同样的注册,所以其术语也应一致。
		
HTTP字符集由大小写敏感的符号组成。全部的符号定义参见IANA字符集注册
[15]。因为注册处不会为每个字符集单独定义一套符号,所以我们在这看到的字符
集名大多是与HTTP实体使用相关的。这些在RFC 1521 [5] 中注册的字符集,即
US-ASCII [17] 及ISO-8859 [18]字符集,还有一些其它字符集被强烈建议在MIME
字符集参数内部使用。

charset = "US-ASCII"
             | "ISO-8859-1" | "ISO-8859-2" | "ISO-8859-3"
             | "ISO-8859-4" | "ISO-8859-5" | "ISO-8859-6"
             | "ISO-8859-7" | "ISO-8859-8" | "ISO-8859-9"
             | "ISO-2022-JP" | "ISO-2022-JP-2" | "ISO-2022-KR"
             | "UNICODE-1-1" | "UNICODE-1-1-UTF-7" | "UNICODE-1-1-UTF-8"
             | token
		
虽然HTTP允许使用专用符号做为字符集值,但是任何在IANA字符集注册表[15]
中有预定义值的符号都必须表明其所属的字符集。应用应当将其对字符集的使用限
制在IANA注册表规定的范围之内。

实体主体的字符集如果属于US-ASCII 或ISO-8859-1字符集,则勿需标记,否则,
应当用主体字符编码方式中的最基本命名来标记。

3.5  内容译码(Content Codings)
	内容译码值用于指示对资源进行的编码转换。内容译码主要用于将经过压缩、加密等操
作的文件进行还原,使其保持其原来的介质类型。典型情况下,经过编码保存的资源只能经
过解码或类似的操作才能还原。
content-coding = "x-gzip" | "x-compress" | token
	注意:出于对未来兼容性的考虑,HTTP/1.0应用应将"gzip" 和"compress" 分别与 
"x-gzip"和"x-compress"对应起来。
	所有的内容译码值都是大小写敏感的。HTTP/1.0在内容编码(10.3节)头域中使用内
容译码值。虽然该值描述的是内容译码,但更为重要的是,它指明了应当用什么机制来进行
解码。注意,单独的程序可能有能力实现对多种格式编码的解码。
	在这段文字中,提到了两个值:
x-gzip
文件压缩程序"gzip" (GNU zip,由Jean-loup Gailly开发)的编码格式。该格式属于
典型的带有32位CRC 校验的Lempel-Ziv译码 (LZ77)。
x-compress
文件压缩程序"compress"的编码格式,该格式适用于LZW(Lempel-Ziv-Welch)译
码。
注意:用程序名来标识编码格式的做法不是很理想,在将来可能不会继续这样做。现在
之所以这样做是出于历史的原因,并非良好的设计。

3.6  介质类型(Media Types)

	HTTP在Content-Type header域(10.5节)中使用Internet介质类型[13],用以提供开放
的可扩展的数据类型。
media-type		= type "/" subtype *( ";" parameter )
type				= token
subtype			= token

	参数可参照属性/值对的方式,用类型/子类型的格式来写。

Parameter		= attribute "=" value
Attribute			= token
Value			= token | quoted-string

	其中,类型、子类型、参数属性名是大小写敏感的。而参数值不一定是大小写敏感的,
这得看参数名的语法而定。在类型和子类型、属性名和属性值之间不能有LWS(空格)。当
接收到不能识别的介质类型的参数时,用户代理应当忽略它们。
	一些老的HTTP应用不能识别介质类型参数,所以HTTP/1.0的应用程序只能在定义消
息内容时使用介质参数。
	介质参数(Media-type)值用Internet授权分配数字(Internet Assigned Number   
Authority ,IANA [15])注册。介质类型注册过程请参见RFC1590[13]。不鼓励使用未注册
的介质类型。

3.6.1标准及文本缺省(Canonicalization and Text Defaults)
	Internet介质类型是用规范形式注册的。一般来说,在通过HTTP协议传输实体主体
(Entity-Body)之前,必须先将其表示成适当的规范格式。如果主体用使用了一种
Content-Encoding进行编码,下面的数据在编码前必须转换成规范形式:
	"text"类型的介质子类型在规范形式中使用CRLF做为文本行中断。实际上,为和实体
主体(Entity body)内的使用方式保持一致,HTTP允许传输纯以CR或LF单独表示行中断
的文本介质。HTTP应用程序必须将其通过HTTP方式接收到的文本介质中的CRLF、CR、
LF看做是行中断符。

	另外,如果文本介质的字符集没有使用字节13和10做为CR和LF,象一些多字节字
符集,HTTP允许使用该字符集指定的任何顺序的字节替代CR和LF做为行中断,这种行
中断的灵活运用方式仅可于实体主体(Entity-Body)中。一个纯CR或LF不应在任何HTTP
控制结构(如标题域-header field和多块分界线-multipart boundaries)中替代CRLF。
	参数"charset"在定义数据的字符集(3.4节)时,与一些介质类型一起使用。当发送方
没有显式给出字符参数时,HTTP在接收时将"text"的介质子类型定义为缺省
值"ISO-8859-1"。"ISO-8859-1"字符集或其子集以外的数据必须要标记其相应的字符集值,
这样可以保证接收方能正确地对其进行解析。
	注意:许多当前HTTP服务器提供的数据使用"ISO-8859-1"以外的其它字符集,而且也
没有正确的进行标记,这种工作方式限制了互操作性,建议不要采用。做为一种补救方法,
一些HTTP用户代理提供了配置选项,使用户可以在字符集参数没指定的情况下,自行更改
缺省的介质类型解释方式。

3.6.2 多部分类型(Multipart Types)


	MIME提供了多部分("multipart")类型的数字――在一个单独的消息实体主体
(Entity-Body)内可以封装几个实体(entities)。虽然用户代理可能需要了解每种类型,从
而可以正确解释每部分主体的意图,但是在IANA[15]的多部分类型(multipart types)注册
中却找不到专为HTTP/1.0所指定的内容。HTTP用户代理只得自己来做接收多部分类型的
工作,其过程和行为与MIME用户代理是相同或相似的。HTTP服务器不应假定HTTP客户
端都有能力处理多部分类型。
	
	所有的多部分类型都使用通用的语法,而且必须在介质类型值部分包括边界参数
(boundary parameter)。消息的主体是其自身,做为协议元素,它必须只使用CRLF做为段
间(body-parts)的行中断符。多段主体(Multipart body-parts)中可能包括对各段有重要意
义的HTTP标题域。

3.7  产品标识(Product Tokens)
	是通讯应用程序用来标识其自身的一个简单符号,常和任意字母及版本描述一起使用。
大多数产品标识也将其产品的重要组成部分的版本号一起列出,中间用空格分隔。

	按惯例,在标识应用程序时,组件以其重要性顺序排列。
Product			= token ["/" product-version]
product-version 	= token
例如:
       User-Agent: CERN-LineMode/2.15 libwww/2.17b3
       Server: Apache/0.8.4
	产品标识应当短小,因而禁止利用该域填写广告或其它无关信息。虽然任何符号字符都
可能出现在产品版本中,该符号应当只用于做版本定义,也就是说,同一个产品的连续版本
之间只能通过产品版本值进行区分。

4.  HTTP 消息(HTTP Message)

4.1  消息类型(Message Types)
	
	HTTP消息由客户端到服务器的请求和由服务器到客户端的回应组成。

HTTP-message   = Simple-Request			; HTTP/0.9 messages
                      | Simple-Response
                      | Full-Request				; HTTP/1.0 messages
                      | Full-Response

	完整的请求(Full-Request)和完整的回应(Full-Response)都使用RFC822[7]中实体传
输部分规定的消息格式。两者的消息都可能包括标题域(headers,可选)、实体主体(entity 
body)。实体主体与标题间通过空行来分隔(即CRLF前没有内容的行)。

Full-Request		= Request-Line			; Section 5.1
                        *( General-Header		; Section 4.3
                         | Request-Header		; Section 5.2
                         | Entity-Header )		; Section 7.1
                        CRLF
                        [ Entity-Body ]			; Section 7.2

Full-Response  	= Status-Line				; Section 6.1
                        *( General-Header			; Section 4.3
                         | Response-Header		; Section 6.2

| Entity-Header )			; Section 7.1
                        CRLF
                        [ Entity-Body ]			; Section 7.2
	
	简单请求(Simple_Request)与简单回应(Simple-Response)不允许使用任何标题信息,
并限制只能使用唯一的请求方法(GET)

       Simple-Request  = "GET" SP Request-URI CRLF

       Simple-Response = [ Entity-Body ]
	不提倡使用简单方式请求格式,因为它防止了服务器在接到简单请求时对返回实体的介
质类型进行验证。


4.2  消息标题(Message Headers)
	HTTP标题域,包括主标题(General-Header,4.3节)、请求标题(Request-Header ,5.2节)、
回应标题(Response-Header ,6.2节)及实体标题(Entity-Header,7.1节),都遵照RFC822-3.1
节[7]给出的通用格式定义。每个标题域由后紧跟冒号的名字,单空格(SP),字符及域值组
成。域名是大小写敏感的。虽然不提倡,标题域还是可以扩展成多行使用,只要这些行以一
个以上的SP或HT开头就行。

HTTP-header		= field-name ":" [ field-value ] CRLF

field-name		= token
field-value		= *( field-content | LWS )

field-content		= <the OCTETs making up the field-value
                        and consisting of either *TEXT or combinations
                        of token, tspecials, and quoted-string>
标题域接收的顺序并不重要,但良好的习惯是,先发送主标题,然后是请求标题或回应
标题,最后是实体标题。
	当且仅当标题域的全部域值都用逗号分隔的列表示时(即,#(值)),多个有相同域名
的HTTP标题域才可以表示在一个消息里。而且必须能在不改变消息语法的前提下,将并发
的域值加到第一个值后面,之间用逗号分隔,最终能将多个标题域结合成“域名:域值”对。

4.3  普通标题域(General Header Fields)
	
	有几种标题域是请求与回应都要使用的,但并不用于被传输的实体。这些标题只用于被
传输的消息。

General-Header = Date			; Section 10.6
                      | Pragma		; Section 10.12
	普通标题域名称只有在与协议版本的变化结合起来后,才能进行可靠的扩展。实际上,
新的或实验中的标题域只要能被通讯各方识别,其语法就可使用,而无法识别的标题域都将
被视为实体域。

原文发布于微信公众号 - 开源优测(DeepTest)

原文发表时间:2018-05-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python攻城狮

十一假期即将结束 不如复习下Python基础

博客地址:https://ask.hellobi.com/blog/zhiji 欢迎大家来交流学习。

8410
来自专栏美团技术团队

不可不说的Java“锁”事

Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8)、使用场景进行举例,为...

15320
来自专栏Golang语言社区

Go语言并发与并行学习笔记

Go语言的并发和并行 不知道你有没有注意到一个现象,还是这段代码,如果我跑在两个goroutines里面的话: var quit chan int = make...

32560
来自专栏Golang语言社区

Go语言·我的性能我做主

对于一些服务来说,性能是极其重要的一环,事关系统的吞吐、访问的延迟,进而影响用户的体验。 写性能测试在Go语言中是很便捷的,go自带的标准工具链就有完善的支持,...

375100
来自专栏SDNLAB

OpenDaylight与Mininet应用实战之流表操作三

本文简要介绍在虚拟机环境下,主要目的是对Open vSwitch下发的流表操作,通过OpenDaylight与Mininet熟悉添加、删除流表的命令及设备通信的...

49560
来自专栏orientlu

FreeRTOS 任务调度 任务切换

前面文章 < FreeRTOS 任务调度 任务创建 > 介绍了 FreeRTOS 中如何创建任务以及其具体实现。 一般来说, 我们会在程序开始先创建若干个任务...

1.1K20
来自专栏阮一峰的网络日志

MIME笔记

MIME的全称是"Multipurpose Internet Mail Extensions",中译为"多用途互联网邮件扩展",指的是一系列的电子邮件技术规范,...

15040
来自专栏编程思想之路

WiFiAp探究实录--功能实现与源码分析

Android虐我千百遍,我待Android如初恋。 ——————编辑于2017-08-02——————— wifi热点说的是wifiAp相...

1.7K90
来自专栏Adamshuang 技术文章

Guava Cache -- Java 应用缓存神器

Guava 作为Google开源Java 库中的精品成员,在性能、功能上都十分出色,本文将从实际使用的角度,来对Guava进行讲解。

3.5K70
来自专栏Golang语言社区

Go语言·我的性能我做主

写性能测试在Go语言中是很便捷的,go自带的标准工具链就有完善的支持,下面我们来从Go的内部和系统调用方面来详细剖析一下Benchmark这块儿。

50180

扫码关注云+社区

领取腾讯云代金券