原创 HTTP报文格式

2012-8-21 13:29 4638 20 21 分类: 通信

 

1.协议简介和应用

1.1协议介绍

HTTP(Hypertext Transfer Protocol, 超文本传输协议)是目前最常用的应用层协议之一,这里只对协议做一个简单的介绍。

HTTP自1990 年以来就被全球信息网采用为基础通讯协议,它是一种应用层的通讯协议,特性是轻便、快速,特别适合如Web 这种分布式、合作式的超媒体信息系统。HTTP 虽早自1990 年起就已被普遍使用,但过去许多年并无统一规范,此项不明确的规范后来通称为HTTP/0.9。直到1996 年6 月一份仅供参考的文件才由Internet Society 的HTTP Working Group 出版,称为HTTP/1.0。

HTTP/1.0 传输格式就像大部分的网络通讯协议,HTTP 使用C/S模式。但是,HTTP/1.0没有充分考虑到分层代理,高速缓存的作用以及对稳定连接和虚拟主机的需求。并且随着不完善的进程应用的激增,HTTP/1.0迫切需要一个新的版本,以便使两个通信应用程序能够确定彼此的真实性能。

这里规定的协议叫做“HTTP/1.1”,这个协议与HTTP/1.0相比,要求更为严格,以确保各项功能得到可靠实现。

1.2协议常见的应用环境

在我们日常生活中最常见的应用环境就是上网浏览网页,很多上班族到办公室的第一件事就是打开电脑,而开机后的第一件事就是打开IE、Firefox、Myie、GreenBrowser、Opera等浏览器时,做的第一件事就是浏览一下例如www.sina.com.cn, www.163.com的新闻,而这种简单的应用操作,完成的交互过程就是一个典型的HTTP协议的应用过程。

1.2.1正常连接的应用环境

基于HTTP协议的客户/服务器模式的信息交换过程,它分四个过程:建立连接、发送请求信息、发送响应信息、关闭连接。如图1

HTTP_图1

显而易见有如下4个交互的过程:

1.2.1.1建立连接  

连接的建立是通过申请套接字(Socket)实现的。客户打开一个套接字并把它约束在一个端口上,如果成功,就相当于建立了一个虚拟文件。以后就可以在该虚拟文件上写数据并通过网络向外传送。通俗地说就是TCP的三次握手。

1.2.1.2发送请求 

首先,这个消息是用普通的ASCII文本书写的。这个消息共有多行(每行以一个回车符和一个换行符结束),最后一行后面还有额外的一个回车符和换行符。当然,一个请求消息也可以仅仅只有一行。请求的报文中包含了各种信息,包括客户端想要访问的URL,HTTP的版本,支持的浏览的字体等内容。详细分析见2.2.1请求报文字段。

1.2.1.3发送响应  

服务器在处理完客户的请求之后,要向客户机发送响应消息。

这个响应消息分为3部分:1个起始的状态行(status line),6个头部行(不固定)、1个包含所请求对象本身的附属体。状态行有3个字段:协议版本字段、状态码字段、原因短语字段。详细分析见2.2.2应答报文字段。

1.2.1.4关闭连接  

客户**务器双方都可以通过关闭套接字来结束TCP/IP对话。通俗地说就是TCP的4次握手断开。常见的应用环境就是这样,实际生活中可能就是多了一个NAT转换,其实过程都是一样的。

1.2.2通过代理上网的应用环境

在很多网络安全产品中,提供了HTTP过滤的功能,要求客户在IE浏览器上做一个【Internet选项】->【连接】->【局域网设置】的更改,配置代理的ip和端口。如下图2:

HTTP_图2

点击【局域网设置】后输入ip和端口,并钩选“为LAN使用代理服务器”如下图3:

HTTP_图3

客户端和代理主机间用交换机相连,下面的拓扑中为了看得更加清晰并没有画出交换机。

下面是一个简单的拓扑图4:

HTTP_图4

详细的交互过程分析参见:3.3

2.协议分析

HTTP报文格式并不复杂,但是各个字段类型数量庞大,这里只对常见的字段进行分析。

对于下面字段说明中出现的一些常见字符作一下说明:

“文字”

文字原文使用引号。除特殊情况,原文对外界不敏感。

规则1 | 规则2

由竖线("|")分开的元素是可选的,例如,"yes | no"表示yes或no都是可接受的。

(规则1 规则2)

围在括号里的多个元素视作一个元素。这样“(elem (foo | bar) elem)”允许标记序列“elem foo elem”和elem bar elem”。

*规则

前面的字符"*"表示重复。完整的形式是"*元素",表示元素至少出现次,至多出现次。默认值是0和无穷大,所以"*(元素)"允许任何数值,包括零;"1*元素"至少需要一次;"1*2element"允许一次或两次。

[规则]

方括号里是任选元素;"[foo bar]"相当于"*1(foo bar)"。

2.1报文格式

对于HTTP的报文格式分析,就是两种格式,因为基于C/S的访问应答模式,所以一个是请求的报文格式,而另一个是应答的报文格式。

2.1.1请求报文格式

先看一下请求报文格式的作图,如图5:

HTTP_图5

文本分析一下请求报文的内容:

请求 =请求行 Request Line

*((常规报头 General Header

|请求报头 Request Header

|实体报头)CRLF) Entity Header

CRLF

[消息正文] Message Body

说明:

HTTP/1.1将CR LF的顺序定义为任何协议元素的行尾标志,CR= LF= 。

2.1.2应答报文格式

先看一下应答报文格式的作图,如图6:

HTTP_图6

文本分析一下应答报文的内容:

应答   =状态行  Status Line

       *((常规报头(general-header) General Header

|应答报头(response-header) Response Header

|实体报头(entity-header)CRLF) Entity Header

CRLF

[应答正文] Message Body

2.2字段描述

根据上面提到的请求报文和应答报文的格式,对每个字段进行描述。

2.2.1请求报文字段

如图7:

HTTP_图7

2.2.1.1请求行

请求消息的第一行称为请求行(request line),请求行有3个字段:

方法字段(Request Method)图7中为:GET;

URL字段(Request URL)图7中为:/forumdisplay.php?fid=6,这个字段可以是一个“/;

HTTP协议不对URL的长度作事先的限制.服务器必须能够处理它们服务的任何资源的URL,并且应该能够处理无限长度的URL,如果它们提供可以产生这种URL的基于GET的形式。

HTTP版本字段(Request Version)。图7中为:HTTP/1.1。

看一下RFC2616中的截图8:

HTTP_图8

常见的方法字段说明:

GET: 请求指定的页面信息,并返回实体主体。

HEAD: 只请求页面的首部。

POST:请求服务器接受所指定的文档作为对所标识的URL的新的从属实体。

PUT: 从客户端向服务器传送的数据取代指定的文档的内容。

DELETE: 请求服务器删除指定的页面。

OPTIONS: 允许客户端查看服务器的性能。

需要特别说明的是方法字段有若干个值可供选择,最常见的包括GET、POST和HEAD。

而且HEAD字段并不好抓包显示,但是这个字段的作用却需要注意,HTML中的head标记是网页标记中一个非常重要的符号,head标记中包含的内容基本上描述了所属页面的基本属性,包括标题、字符集、站点信息、网站作者信息、站点描述、站点关键词、搜索引擎蜘蛛引导、刷新及跳转、样式表链入以及其它一些有用的附加功能。例如:

简体中文:“ ”

繁体中文:“ ”

英 语:“”

禁止浏览器从本地机的缓存中调阅页面内容。

例子:“ ”

?/P>

2.2.1.2请求头部行

后续各行都称为请求头部行(header),即请求报头。其中RFC2616中定义常见的有:

HTTP_图9

常见的头部说明:

Accept:可以接受的媒体;

Accept-Charset:可以接受的字符集;

Accept-Encoding:可以接受的编码方案;

Accept-Language:能够接受的语言;

Host:主机和端口号;

Referer:指明被连接的目标URL。

同时RFC2616注明可以根据需要扩展自定义的头部行:

原文:Request-header field names can be extended reliably only in combination with a change in the protocol version. However, new or experimental header fields MAY be given the semantics of request-header fields if all parties in the communication recognize them to be request-header fields. Unrecognized header fields are treated as entity-header fields.

翻译:随着协议版本的变化,请求报头域的名字可以可靠的扩展。然而新的或扩展的报头域可以给出请求报头域的语法,其前提是通信中所有部分承认它们是请求报头域。不被承认的报头域被当作实体报头域。

2.2.2应答报文字段

如图10:

HTTP_图10

2.2.2.1状态行

应答信息的第一行是状态行,由协议版本以及数字状态码和相关的文本说明组成,各部分间用空格符隔开,除了最后的回车或换行外,中间不允许有回车换行,注意HTTP/1.1后面没有\r\n。

状态行中的状态码是试图理解和满足请求的三位数字的整数码,状态码用于自动控制而注解短语是面向用户的,客户机不需要检查和显示注解短语。

图10中返回的协议版本为HTTP/1.1,注意,请求的HTTP版本可以和返回的HTTP不一致。返回的状态码为200 OK。

状态码的第一位数字定义应答类型,后两位数字没有任何类型任务,第一位数字有五种值:

-1xx: 报告的 - 接收到请求,继续进程.

-2xx 成功 - 操作成功的收到.

-3xx 重发 - 为了完成请求,必须采取进一步措施.

-4xx 客户端出错 - 请求包括错的顺序或不能完成.

-5xx 服务器出错 - 服务器无法完成显然有效的请求.

HTTP协议状态码的具体含义 :

"100" : Continue 继续;

"101" : witching Protocols 转换协议;

"200" : OK 成功;

"201" : Created 创建;

"202" : Accepted 接受;

"203" : Non-Authoritative Information 非权威信息;

"204" : No Content 无内容;

"205" : Reset Content 重置内容;

"206" : Partial Content 局部内容;

"300" : Multiple Choices 多样选择;

"301" : Moved Permanently 永久移动;

"302" : Found 创立;

"303" : See Other 观察别的部分;

"304" : Not Modified 只读;

"305" : Use Proxy 用户代理;

"307" : Temporary Redirect 临时重发;

"400" : Bad Request 坏请求;

"401" : Unauthorized 未授权的;

"402" : Payment Required 必要的支付;

"403" : Forbidden 禁用;

"404" : Not Found 没找到;

"405" : Method Not Allowed 不允许的方式;

"406" : Not Acceptable 不接受;

"407" : Proxy Authentication Required 需要代理验证;

"408" : Request Time-out 请求超时;

"409" : Conflict 冲突;

"410" : Gone 以往的;

"411" : Length Required 需要的长度;

"412" : Precondition Failed 预处理失败;

"413" : Request Entity Too Large 请求实体太大;

"414" : Request-URL Too Large 请求URL太大;

"415" : Unsupported Media Type 不支持的媒体类型;

"416" : Requested range not satisfiable 请求的范围不足;

"417" : Expectation Failed 期望失败;

"500" : Internal Server Error 服务器内部出错;

"501" : Not Implemented 不能实现;

"502" : Bad Gateway 坏网关;

"503" : Service Unavailable 服务器不能实现;

"504" : Gateway Time-out 网关超时;

"505" : HTTP Version not supported HTTP版本不支持。

2.2.2.2应答头部行

应答头允许服务器传送应答的附加信息,这些信息不能放在状态行里.这些报头域给出有关服务器的信息以及请求URL指定的资源的下一步的通路。

RFC2616中定义的应答头部行,图11:

HTTP_图11

常见的应答头部说明:

Accept-Ranges:给出客户请求的范围;

Age:给出文档的使用期限;

Location:重新定向后的位置;

Server:给出服务器和版本号。

随着协议版本的变化,应答报头可以可靠的扩展。而且,如果通信的所有组成部分都把它当作应答报头域,新的或试验性的应答报头域可以被给定应答报头域的含义,未被承认的报头域被当作实体报头域。

2.2.3实体字段

这个字段可能经常被误以为是头部字段中的内容,在未经特别规定的情况下,请求与应答的报文也可以传送实体。实体包括实体报头与实体正文,而有些应答只包括实体报头。

2.2.3.1实体报文域

实体报文域定义了关于实体正文的维护信息(参数),或在无正文情况下定义了请求的资源。其中一些参数是可选的,一些则是由技术指标规定必须的。

参见RFC2612的图12:

HTTP_图12

可以从中看出实体字段主要规定的是内容编码(Content-Encoding)、内容类型(Content-Type)、内容语言(Content-Language)、内容长度(Content-Length)、上次修改(Last-Modified)等信息。

2.2.3.2实体正文

经由HTTP请求或应答发送的实体正文部分(如果存在的话)的格式与编码方式应由实体报文域决定。

实体正文= *八位字节

实体正文只有当报文正文存在时才存在。实体正文是通过对报文正文按某种保证安全性且便于传输的传输编码进行解码得到的。对于报文中的实体正文而言,其数据类型由报头中的"内容类型"与"内容编码"域决定。也即定义了一个双层有序的编码模型:

实体正文=内容编码(内容类型(数据))

"内容类型"规定了基本数据的媒体类型。

"内容编码"则可用来指明对数据施加的任何附加的,通常以数据压缩为目的的编码方式,并将其作为所请求资源的一项属性。没有缺省的编码方式。

任一包含了实体正文的HTTP/1.1报文都应包括"内容类型"(Content-Type)报头域,以定义正文的媒体类型。当且仅当"内容类型"域未给出媒体类型时,接收者才可以通过查看资源的内容,扩展名或URL来猜测其媒体类型。若媒体类型仍然未知,接收者应将其作为"应用/八位字节流"来处理。

2.2.3.3实体长度

报文的实体长度指的是在对报文进行传输编码前报文正文的长度。图10中标记的内容长度。

2.2.4连接

在持续连接之前,为获取每一URL都建立了独立的TCP 连接,这就加重了HTTP服务器的负担,易引起INTERNET阻塞。嵌入式图片与其它相关数据通常使用户在短时间内对同一服务器提交多个请求。HTTP/1.1 与HTTP/1.0 版本的一个显著区别在于持续连接是任何HTTP连接的缺省方式。也就是说,除非另有指定,客户机总应当假定服务器会保持持续连接,即便在接到服务器的出错应答时也应如此。

注意:在测试验证过程中出现过一种特殊情况,在IE上设置代理上网,在代理服务器上(如图4)抓到的报文却是HTTP/1.0的请求。改用Firefox浏览器设置代理上网却不会出现这个情况。后来发现是IE自身设置的问题,在【internet选项】->【高级】->HTTP1.1设置中有一个【通过代理连接使用HTTP1.1】的钩选项。

2.2.4.1持续连接

持续HTTP 连接有着诸多的优点:

--- 通过建立与关闭较少的连接,不仅节省了路由器与主机(客户机,服务器,代理服务器,网关,隧道或高速缓冲存储机)的CPU时间,还节省了主机用于TCP协议控制块的内存。

--- HTTP请求与应答可以进入连接流水线。流水线方式使得客户无须挨个等待应答即发起多个请求,从而更充分的利用了单个的TCP连接,减少了崩溃时间。

--- 在减少TCP连接中数据包个数的同时,使TCP有了充裕的时间来确定网络的拥塞状况,缓解了网络拥塞。

--- 因为无须在创建TCP连接握手上耗费时间,而使连续请求造成的延迟现象得到改善。

--- 由于出错不会导致TCP连接的关闭,HTTP可以更好的实现自我完善。使用较新版HTTP的用户会乐于尝试一些新功能,与旧版服务器通信时,则会在接到出错报告后用旧模式重试。

文章评论1条评论)

登录后参与讨论

用户377235 2012-10-23 23:08

转的?

相关推荐阅读
用户1591794 2015-01-27 12:49
GPRS流量计算方法(TCP/IP)
 流量统计方法: 一、登陆网络,建立TCP链路 PPP握手阶段大约要来回12~16个PPP握手包,每个包为30字节。30*16=480字节。 TCP连接阶段:40×3=120字节 注册:...
用户1591794 2014-07-18 09:27
Warning[Pa082]:undefined behavior:
IAR编译的时候,出现警告如下: Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in...
用户1591794 2014-03-21 10:28
Eclipse AVR Windows8.1 Error
...
用户1591794 2013-08-08 09:13
STM32如何进入sleep模式
  STM32如何进入sleep模式 网上说STM32 STOP模式和Standby模式的不少,却很少有人说怎么操作Sleep模式,东西不多,加一个函数而已,废话不多,下面就给出添加的函数...
用户1591794 2013-08-07 06:50
STM32 BOOT0连接不当造成死机
  STM32的三种启动方式依靠BOOT0和BOOT1两个引脚的电平来决定,ST官方推荐的是串联10k电阻然后在接高电平或接地。 理论上这两个引脚只是在启动的时候用来选择启动方式,启动结束...
用户1591794 2013-04-20 21:52
STM32L BOR 应用
BOR功能 是STM32L系列特有的复位和启动电压调整功能。 BOR 关闭时STM32L的供电范围是1.65 V to 3.6 V, BOR 关闭时STM32L的供电范围是1.8 V to...
我要评论
1
20
关闭 站长推荐上一条 /2 下一条