首页 > 代码库 > http协议分析

http协议分析

博主QQ819594300

博客地址:http://zpf666.blog.51cto.com/

有什么疑问的朋友可以联系博主,博主会帮你们解答,谢谢支持!

http协议介绍

http:HyperText Transfer Protocol 超文本传输协议,是互联网应用最为广泛的一种网络协议,主要用于Web服务。通过计算机处理文本信息,格式为HTML(Hyper Text Mark Language)超文本标记语言来实现。

http协议的版本

http 0.9仅于用户传输html文档

http 1.0

  • 引入了MIME(MultipurposeInternet Mail Extesions)机制:多用途互联网邮件扩展,引入这个技术之后,http可以发送多媒体(比如视频、音频等)信息。此机制让http不在单单只支持html格式,还可以支持其他格式来进行发送了。

  • 引入了keep-alive机制,支持持久连接的功能(但这个keep-alive原理是在首部添加了某个字段而形成的,并非原生就支持此功能)

解释:什么叫keep-alive

答:就是保持长连接。当客户端与web服务端建立连接后,客户端可以利用已建立的连接,可以发送多个http请求,不用每次请求都需要先新建依次连接。这就相当于A和B双方打电话,A给B打电话,拨通一次B的电话号码,就可以和B说很多的话,而不是说一句话就挂断一次,然后A再一次拨通B的号码再和B说一句话,再挂断,再拨通,再说一句话,这样反反复复的拨通挂断,这样的通话效率很低,又浪费电话费。Keep-alive就相当于当客户端和服务端连接一次就可以保持长时间的请求和回应。

  • 引入支持缓存功能

http 1.1

  • 支持更多的请求方法(比如:get、post等请求方式,本博文后面会详细说明请求方法);

  • 更加精细的缓存控制,原生直接支持持久连接功能(presistent)(http1.0该功能是非原生)。

http 2.0

提供了HTTP语义优化的传输,spdy: google引入了的一个技术,能够加速http数据交互,尤其是使用ssl 加速机制,但是spdy现在用的还不多。

目前常用的版本就是http 1.1版本,其次是http1.0版本,还需要说明的是,下一个版本会包含上一个版本的全部功能。

html文本架构

技术分享

html文档的生成方式

静态

就是用html事先就编辑并定义完成的

动态

通过编译语言编写的程序和代码,然后客户端发送动态网页请求,则服务端就会执行编写的代码和程序,把执行后的结果以html格式输出到客户端的屏幕。

动态语言有:php,jsp,asp,.net

备注:这些脚本都必须有相应的解释器,比如说 php需要有php解释器等等

静态和动态的方式

静态

技术分享

过程如下

1、Web服务器向内核注册socket

解释:什么是socker

     答:是进程套接字。当http服务启动后,http服务会自动向内核注册socket套接字进程,用于监听来访问的客户端的IP地址和http服务端的80端口(默认),当有客户端发来访问请求时,socket会重新封装客户端的请求给http服务。

2、客户端通过浏览器,向Web服务器发起request请求

3、Web服务器收到客户端的request信息

4、如果用户请求的资源在服务器本地的话,http服务会向系统内核申请调用

5、内核调用本地磁盘里的数据,并将数据发给http服务

6、http将用户请求的资源通过response报文,最终响应给客户端

动态

技术分享

过程如下:

与静态不同的是,如果用户请求的是动态内容,那么此时http服务会调用后端的解析器,由动态语言去处理用户的请求,如果需要请求数据的时候,会向内核申请调用,从而向磁盘中获取用户指定的数据,通过解释器运行,运行的结果通常会生成html格式的文件。然后构建成响应报文,最终发回给客户端。

http协议的报文

说明:HTTP报文中存在着很多行的内容,一般是由ASCII码串组成,各字段长度是不确定的。

HTTP的报文可分为两种:请求报文与响应报文

1.request Message(请求报文)

客户端  →  服务器端

由客户端向服务器端发出请求,不同的网站用于请求不同的资源(html文档)

2.response Message(响应报文)

服务器端 → 客户端

是服务器予以响应客户端的请求

请求报文格式介绍

格式:请求行 + 请求首部 + 空白行 + 请求实体

技术分享

技术分享

下面分别来介绍请求行、请求首部、空白行、请求实体

1.请求行

说明:由请求方法字段<method>+请求URL字段<request-URL>+HTTP协议版本<version>组成。

用来标识客户端请求的资源时使用的请求方法,请求的资源,请求的协议版本是什么,它们直接使用“空格”进行分隔!

eg:  GET   /    HTTP1.1 \r\n

(“/“就是请求的是http服务端的首页)

技术分享

技术分享

说明:上图是用wireshark工具抓取http请求报文的显示结果。在首部后的“\r\n”表示一个回车和换行,以此将该首部与下一个首部隔开。

或者用curl命令获取http请求报文。

技术分享

2.请求首部

关键字+关键字的值组成,之间使用“:”进行分隔,

格式Name:Value,请求首部的作用是通过客户端将请求的相关内容告知服务器端,首部可以不止一个。

技术分享

技术分享

Host:后面跟的是客户端请求的服务端的域名

Connection:后面跟的是keep-alive,意思是客户端请求和服务端建立长连接。长连接建立成功与否,取决于两个方面,第一个是服务端的http服务是否开启了长连接功能,第二个是http版本是否支持。

Uggrade-Insecure-Requests:1表示客户端告诉服务器,浏览器可以处理https协议,即发送非安全请求(http请求是非安全请求,https请求是安全请求)

User-Agent:是客户端的浏览器的信息(就是浏览器是哪种浏览器和版本号等信息)

Accept:是客户端请求的资源的类型

Accept-Encoding:表示客户端支持服务端对客户端进行压缩传以及类型

Accept-Language:表示客户端支持的HTML语言

3.空白行

请求首部之后会有一个空白行,通过发送回车字符和换行符。

用于通知服务器端以下的内容将不会再出现请求首部的信息

4.请求实体

你需要请求的内容到底是什么

技术分享

技术分享

响应报文格式介绍

格式:起始行 + 响应首部 + 空白行 +  响应实体

技术分享

技术分享

下面分别介绍起始行、响应首部、空白行、响应实体

1.起始行

说明:也称之为状态行,用于服务器端响应客户端请求的状态信息,由版本号<version> + 状态码<status> + 原因短语<reason-phrase>组成,例如“ HTTP/1.1 200 OK”,另外还有404表示请求的网页不存在。

技术分享

技术分享

2.响应首部

技术分享

说明:类似请求报文,起始行后面一般有若干个头部字段。每个头部字段都包含一个名字和一个值,两者之间用冒号分割。格式Name:Value。

例如:

Content-Type: test/html; charset=utf-8

Content-Length: 78

技术分享

Date:是服务端响应客户端的时间(年月日时分秒)

Content-Type:是响应内容的类型(比如是图片、音频等)

Content-Length:是响应内容的长度(以字节为单位)

Connection:后面跟keep-alive,表示服务端回应客户端,它支持长连接。(看见了这个,说明客户端和服务端的长连接建立成功)

Set-Cookie:是客户端第一次发送请求给服务端后,服务端在把客户端的请求数据回应给客户端的同时也回应给客户端一个Set-cookie码。

(cookie用于统计访客数,Set-cookie用于唯一标识同一客户端。当客户端第二次再次请求服务端,则要携带cookie:xxx码,作为请求的守护字段,和请求融合在一起,这样当服务端接收到请求后,可以判断该客户端是新用户还是老用户)

P3P:P3P 是 The Platform for Privacy Preferences 的简称。后面跟的CP,CP 是 CompactPolicy 的简写

Location:后面跟的是服务端响应给客户端访问网页资源在服务端的位置

Server:后面的BWS/1.1是百度的http服务端为了保护服务器不被黑客知道了服务器的类型(是Apache还是nginx)以及http版本号攻击百度的http服务器。后面的服务器类型以及http版本给隐藏了。

X-UA-Compatible:后面跟的是客户端的浏览器的信息,是什么软件类型的浏览器。

3.空白行

最后一个响应首部信息之后就是一个空行,通过发送回车符和换行符,作用是通知客户端空行下无首部信息。

4.响应实体

响应实体中装载了要返回给客户端的数据。这些数据可以是文本,也可以是二进制(例如图片,视频)

技术分享

技术分享

HTTP请求方法

在HTTP通信过程中,每个HTTP请求报文中都会包含一个HTTP请求方法,用于告知客户端向服务器端请求执行某些具体的操作。

下面列举几项常用的HTTP请求方法

技术分享

技术分享

说明:后3种请求方法用的最少。

上面有几个请求方法的描述有点太官方,这里我通俗的解释一下

Head:就是客户端想服务端发送请求,只需要服务端回应该资源是有还是没有,不是要服务端回应资源实体。

Post:比如登录一个网站,要注册会员用户,这里的账户和密码就以post方式发送请求。

Delete:是客户端请求服务端删除自己上传的URL指定资源,别人的上传的资源,你不能用delete请求方法删除。

Trace:跟踪一次请求,请求在传递的过程中,所经历的的代理服务器、防火墙或网关等情况。

HTTP的状态码

技术分享

说明一下5xx,就5xx举个例子,当web服务器和php是分离部署的,当有客户端发送动态请求给web服务器,而web服务器需要把这个动态请求转发给(这里的web服务器就相当于是一个代理服务器)php,让php来处理动态请求,当web去找php,找不到(也可以说web连接不上php),则这时候web服务器会给客户端回一个502的状态码。

常用状态码说明

技术分享

技术分享

这里侧重记住几个状态码:

301:永久重定向。告诉客户端你请求的地址永久挪到了那个新地址。

302:临时重定向。告诉客户端你请求的资源临时存放在某个地方。

304:表示告诉客户端,你再次访问的该资源没有被修改(即该资源在web服务端上没有修改,客户端可以直接从自己的本地缓存中读取该数据。)

HTTP首部介绍

  • 通用首部

  • 请求首部

  • 响应首部

  • 实体首部:专门用来表示实体中资源内部的类型、长度、编码格式等

  • 扩展首部:非标准首部,可有程序员自行创建

通用首部

   Connection:定义C/S之间关于请求、响应的有关选项

在http1.0 的时候,如果他想使用持久连接,那么他所设置的选项即为

Connection:keep-alive

   Cache-Control:缓存控制,实现更精细的缓存控制方式。在http 1.1上比较常见

请求首部

   Client-IP :客户端 IP地址

   Host :请求的主机,这在实现基于主机名的虚拟主机时很有用

   Referer :指明了请求当前资源原始资源的URL,使用referer是可以防盗链

   User-Agent:用户代理,一般而言是浏览器

   Accept首部:指客户端可以接受哪些编码的类型

   Accept:服务端能够发送的媒体的类型

   Accetp-Charset:接收的字符集

   Accept-Encoding:编码格式

   Accept-Lanage:所能接受的语言编码格式

   条件式请求首部:(在http1.1中才会用到)

当发送请求时,先问问对方是否满足条件,如果满足条件就请求,不满足就不请求

   跟安全相关的请求:

   Authorization

   Cookie

响应首部

   Age:资源响应给你之后可以使用的时长

   Server:向客户端说明自己用到的程序名称和版本

   协商类的首部:

   Vary:首部列表,服务器会根据此列表挑选最适合的版本发给客户端

   跟安全相关:

   WWW-Authentication

   Set-Cookie

实体首部

   Location:指明资源的新位置,实现302响应码时通常会用到

   Allow:允许对此资源使用的请求方法

   内容相关的首部

   Content-Encoding

   Content-Language

   Content-Length

   Content-Location:内容所在的位置

   Content-Type

   缓存相关:

   ETag:扩展标签/标记

   Expires:过期时间

   Last-Modified:最后修改时间

ETag解释:

在网络上,有一些缓存服务器,另外,浏览器自身也有缓存功能

基于一个前提:图片不会经常改动,服务器在返回状态码200的同时,还会返回该图片的签名Etag,(可以理解为图片的指纹),当浏览器再次访问该图片时,就会去服务器校验指纹信息,如果图片没有变化,直接使用缓存里的图片,这样减轻了服务器的负担,一看到304,浏览器就知道了,要从本地缓存里面取图片,节省了图片在网络上传输的时间

附:

HTTP最常见的请求头如下:

Accept:浏览器可接受的MIME类型;

Accept-Charset:浏览器可接受的字符集;

Accept-Encoding:浏览器能够进行解码的数据编码方式,比如gzip。

Accept-Language:浏览器所希望的语言种类

Authorization:授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中;

Connection:表示 是否需要持久连接。值为“Keep-Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。

Content-Length:表示请求消息正文的长度;

Cookie:这是最重要的请求头信息之一;

Cookie相关的HTTP扩展头

1)Cookie:客户端将服务器设置的Cookie返回到服务器;

2)Set-Cookie:服务器向客户端设置Cookie;

3)Cookie2(RFC2965)):客户端指示服务器支持Cookie的版本;

4)Set-Cookie2(RFC2965):服务器向客户端设置Cookie。

Cookie的流程

服务器在响应消息中用Set-Cookie头将Cookie的内容回送给客户端,客户端在新的请求中将相同的内容携带在Cookie头中发送给服务器。从而实现会话的保持。

流程如下图所示:

技术分享

Host:初始URL中的主机和端口;

If-Modified-Since:只有当所请求的内容在指定的日期之后又经过修改才返回它,否则返回304“Not Modified”应答;

Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。

User-Agent:浏览器类型

HTTP最常见的响应头

HTTP最常见的响应头如下所示:

Allow:服务器支持哪些请求方法(如GET、POST等);

Content-Encoding:文档的编码(Encode)方法。

Content-Length:表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。

Content-Type:表 示后面的文档属于什么MIME类型。

Accept-Ranges: bytes  该响应头表明服务器支持Range请求,以及服务器所支持的单位是字节(这也是唯一可用的单位).我们还能知道:服务器支持断点续传,以及支持同时下载文件的多个部分,也就是说下载工具可以利用范围请求加速下载该文件.Accept-Ranges: none 响应头表示服务器不支持范围请求.

Date:当前的GMT时间。

Expires:指明应该在什么时候认为文档已经过期,从而不再缓存它。

Last-Modified:文档的最后改动时间。

Location:表示客户应当到哪里去提取文档。

 Refresh:表示浏览器应该在多少时间之后刷新文档,以秒计。

HTTP最常见的实体头

实体头用作实体内容的元信息,描述了实体内容的属性,包括实体信息类型,长度,压缩方法,最后一次修改时间,数据有效性等。

Allow:GET,POST

Content-Encoding:文档的编码(Encode)方法,例如:gzip,

Content-Language:内容的语言类型,例如:zh-cn;

Content-Length:表示内容长度,eg:80,可参考“2.5响应头”;

Content-Location:表示客户应当到哪里去提取文档,例如:http://www.dfdf.org/dfdf.html,

Content-MD5:MD5 实体的一种MD5摘要,用作校验和。发送方和接受方都计算MD5摘要,接受方将其计算的值与此头标中传递的值进行比较。

Content-Type:标明发送或者接收的实体的MIME类型。Eg:text/html;charset=GB2312       主类型/子类型;

HTTP的事务

包含了一个HTTP请求,和对应请求的响应就叫做一个http事务,也可以理解http事务就是一个完整的HTTP请求和HTTP响应的过程

http协议默认情况下每个事务都会打开和关闭一个新的连接,所以会相当耗费时间和带宽,由于TCP慢启动特性,所以每条新的连接的性能本身就会有所降低,所以可打开的并行连接的数量上限是有限的。所以使用持久连接这种模式比默认情况下不使用持久连接的方式会好一点,他的好处表现在其请求和tcp断开的过程所消耗的时间会被减少。

HTTP资源

资源就是通过HTTP协议可以让用户通过浏览器或用户代理能够通过基于http协议向服务器端请求并获取的内容,像html文档,一张图片等等。

资源类型:是通过MIME进行标记

格式:major/minor 主标记和次标记

常用的MIME类型:

技术分享

URI和URL的区别

   URI(Uniform Resource Identifier) 同一资源标示符

用于标识某一互联网资源名称的字符串,通过这种标识来允许你用户对资源可通过特定的协议进行交互操作。在Web上可用的每种资源,包括HTML文档、图像、视频片段、程序等, 由一个通用资源标识符进行定位。所以我们可以使用URI来标识每个资源的名称

通俗的说URI就是服务端上每个资源的名称

   URL(Uniform Resource Locator)(统一资源定位符)

用于描述一个特定服务器上某资源的特定位置。

例如:http://www.baidu.com:80/download/bash-4.3.1-1.rpm

URL的格式分为三个部分

i.   scheme(方案)(也叫协议):http://

ii.  Internet地址:一般这个地址指的是服务器:www.baidu.com:8080

iii. 特定服务器上的资源:download/bash-4.3.1-1.rpm

通俗的说URL就是服务端上每个资源的位置

CGI

是Common Gateway Interface的缩写,意思是通用网关接口

技术分享

说明:web服务器发现需要执行脚本了,就通过CGI协议跟后端的应用程序打交道,把用户的请求动态交给服务器,这个服务器的结果通过CGI协议返回给http服务器。

其他需要了解的知识

一次Web资源请求的具体过程:

1.  客户端在Web浏览器输入需要访问的地址

2.  Web浏览器会请求DNS服务器,查询解析到指定域名和Web服务器的地址

3.  客户端与请求的Web服务器端建立连接(TCP三次握手)

4.  TCP建立成功之后,发起HTTP请求

5.  服务器端收到客户端HTTP请求之后,会处理该请求

6.  处理客户端指定请求的资源

7.  服务器构建响应报文,响应给客户端

8.  服务器端将此信息记录到日志中

http如何并发的接收多个用户请求:

因为http默认是工作在阻塞模型下的,默认一次只接收一个请求,处理完请求后再去接收下一个请求,所以只能一个一个来。

所以我们希望并发响应用户请求,需要多进程模型。web服务器自己会生成多个子进程响应用户请求,也就是说,当一个用户请求发到Web服务器,Web主进程不会直接响应用户请求,而是生成一个子进程响应这个用户请求,这样当子进程和此用户建立连接之后。Web的主进程就会再等待另一个用户的请求,当第二个用户请求过来之后,再生成一个子进程响应第二个用户请求。以此类推。所以每一个用户请求都由一个子进程来处理。

说明一下:这里说的http采用的阻塞模型,是对于apache来说的,而nginx采用的是非阻塞模型,nginx的主进程可以一次性接受多个请求。

扩展知识点1:利用wireshark分析HTTP协议

实验步骤

①清空缓存

在进行跟踪之前,我们首先清空Web 浏览器的高速缓存来确保Web网页是从网络中获取的,而不是从高速缓冲中取得的。之后,还要在客户端清空DNS高速缓存,来确保Web服务器域名到IP地址的映射是从网络中请求。

清除浏览器缓存:

在浏览器→设置,里面手动清除

清除DNS 缓存:

ipconfig /flushdns

②启动wireshare

技术分享

③在客户端浏览器地址栏中输入www.benet.com,并过滤(点击右上角那个漏斗标志,选择只要http,然后点击apply)

得到如下截图:

技术分享

④分析数据

在协议框中选择“GET/ test.html HTTP/1.1”所在的分组会看到这个基本请求行后跟随着一系列额外的请求首部。在首部后的“\r\n”表示一个回车和换行,以此将该首部与下一个首部隔开。

“Host”首部在HTTP1.1版本中是必须的,它描述了URL中机器的域名,本测试中是www.benet.com。这就允许了一个Web服务器在同一时间支持许多不同的域名。有了这个首部,Web服务器就可以区别客户试图连接哪一个Web服务器,并对每个客户响应不同的内容。

User-Agent首部描述了提出请求的Web浏览器及客户机器。

接下来是一系列的Accpet首部,包括Accept(接受)、Accept-Language(接受语言)、Accept-Encoding(接受编码)、Accept-Charset(接受字符集)。它们告诉Web服务器客户Web浏览器准备处理的数据类型。Web服务器可以将数据转变为不同的语言和格式。这些首部表明了客户的能力和偏好。

Keep-Alive及Connection首部描述了有关TCP连接的信息,通过此连接发送HTTP请求和响应。它表明在发送请求之后连接是否保持活动状态及保持多久。大多数HTTP1.1连接是持久的(persistent),意思是在每次请求后不关闭TCP连接,而是保持该连接以接受从同一台服务器发来的多个请求。

技术分享

我们已经察看了由Web浏览器发送的请求,现在我们来观察Web服务器的应答。响应首先发送“HTTP/1.1 200 ok”,指明它开始使用HTTP1.1版本来发送网页。同样,在响应分组中,它后面也跟随着一些首部。最后,被请求的实际数据被发送。第一个Cache-control首部,用于描述是否将数据的副本存储或高速缓存起来,以便将来引用。一般个人的Web浏览器会高速缓存一些本机最近访问过的网页,随后对同一页面再次进行访问时,如果该网页仍存储于高速缓存中,则不再向服务器请求数据。在HTTP请求中,Web服务器列出内容类型及可接受的内容编码。此例中Web服务器选择发送内容的类型是test/html

技术分享

扩展知识点2:curl查看HTTP 响应头信息

先看看客户端(浏览器)从服务器请求数据经历如下基本步骤:

1.用户发起一个http请求,缓存获取到URL,根据URL查找是否有匹配的副本,这个副本可能在内存中,也可能在本地磁盘。 

 2、如果请求命中本地缓存则从本地缓存中获取一个对应资源的"copy";

 3、检查这个"copy"是否过期,否则直接返回,是则继续向服务器转发请求。 HTTP中,通过Cache-Control首部和Expires首部为文档指定了过期时间,通过对过期时间的判断,缓存就可以知道文档是不是在保质期内。Expires首部和Cache-Control:max-age首部都是来告诉缓存文档有没有过期,为什么需要两个响应首部来做这件简单的事情了?其实这一切都是历史原因,Expires首部是HTTP 1.0中提出来的,因为他使用的是绝对日期,如果服务端和客户端时钟不同步的话(实际上这种情况非常常见),缓存可能就会认为文档已经过了保质期。

 4、服务器接收到请求,然后判断资源是否变更,是则返回新内容,否则返回304,未变更,更新过期时间。

技术分享

技术分享

HTTP 响应头的信息

(1). HTTP 返回码:

1xx:client的请求server已经接收,正在处理

2xx:成功  表示 client请求,server端已经接收、理解并处理

3xx:client请求被重定向其他的server【其他的URL】

4xx:表示client请求不正确,server不能识别

5xx:server端服务不正常

Cache-Control(缓存控制):

web 站点对缓存的设置: Cache-Control指定请求和响应遵循的缓存机制

缓存分类

1)私有缓存:常见就是我们的浏览器里内置的缓存。

2)公有缓存:常见的就是代理缓存

先看Cache-Control可选的参数:private、public 、no-cache、max-age、must-revalidate等

no-cache: 响应不会被缓存,而是实时向服务器端请求资源

no-store :在任何条件下,响应都不会被缓存,并且不会被写入到客户端的磁盘里,这也是基于安全考虑的某些敏感的响应才会使用这个。

Private:指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当前用户的部分响应消息,此响应消息对于其他用户的请求无效。不能再用户间共享。

Public:响应会被缓存,并且在多用户间共享。正常情况, 如果要求 HTTP 认证,响应会自动设置为 private。

max-age:指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应,例如: Cache-control: max-age=5 表示当访问此网页后的5秒内再次访问不会去服务器。

must-revalidate :响应在特定条件下会被重用,以满足接下来的请求,但是它必须到服务器端去验证它是不是仍然是最新的(强制所有缓存都验证响应)。

proxy-revalidate :类似于 must-revalidate, 它要求对公共缓存进行验证

Connection(连接):

server 是否支持长连接;如果keep-alive 说明web的server支持长连接。

但是TCP 的长连接是双向的;必须是client和server 都支持长连接;才可以建立长连接。

一般client 【浏览器】都是默认支持长连接;所以只要sever端支持长连接;就可以建立长连接。

通过curl的-w参数我们可以自定义curl的输出,%{http_code}代表http状态码

技术分享

本文出自 “IT技术助手” 博客,请务必保留此出处http://zpf666.blog.51cto.com/11248677/1920794

http协议分析