http(HyperText Transfer Protocol)是一个应用层协议,由请求和响应构成,是标准的客户端服务器模型。http/1.1协议目前在服务器领域还是有着广泛的应用,尽管现在越来越多的网站和服务使用https协议(http承载于TLS或SSL协议层之上),包括新的http/2协议。

http连接的建立

http是一个无状态的协议,基于tcp协议来实现。

以下是浏览器访问http://www.suninf.net/links.html 建立连接的抓包截图:

http连接的第一步是tcp的三次握手:

  1. 本机A(192.168.0.101)向服务器B(45.78.27.83)发送随机seq=0的[SYN]包请求建立连接;
  2. B收到请求后要确认联机信息,发送ack=1(A的seq+1),随机seq=0的[SYN,ACK]的包;
  3. A收到后检查ack是否正确(第一次发送的seq+1)以及ACK标记是否设置,若正确,则向B发送ack=1(B的seq+1)的[ACK]包,B收到后见检查seq值和ACK标记是否正确,正确则建立连接开始传送数据。

请求

http请求由三部分组成,分别是:请求行、消息报头、请求正文

访问 http://www.suninf.net/links.html 的抓包数据:

请求行

请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:

Method Request-URI HTTP-Version CRLF

其中

请求方法有多种,解释如下:

最常见的是 GET 和 POST 的请求。

比如:

消息报头 & 请求正文

参考前面的抓包数据:

GET /links.html HTTP/1.1
Host: www.suninf.net
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4

HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Sun, 15 May 2016 23:49:07 GMT
Content-Type: text/html
Last-Modified: Sun, 15 May 2016 12:24:38 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip

常见的请求头:

Host
指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的位置
Referer
允许客户端指定请求uri的源资源地址,这可以允许服务器生成回退链表,可用来登陆、优化cache等。如果请求的uri没有自己的uri地址,Referer不能被发送。
Cookie
客户端将服务器设置的Cookie返回到服务器
User-Agent
内容包含发出请求的用户信息,如操作系统和浏览器版本
Cache-Control
指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。
Accept
请求报头域用于指定客户端接受哪些类型的信息。eg:Accept:image/gif,表明客户端希望接受GIF图象格式的资源
Accept-Encoding
请求报头域类似于Accept,但是它是用于指定可接受的内容编码。如:Accept-Encoding:gzip
Accept-Language
请求报头域类似于Accept,但是它是用于指定一种自然语言。如:Accept-Language:zh-cn
Authorization
请求报头域主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为401(未授权),可以发送一个包含Authorization请求报头域的请求,要求服务器对其进行验证

响应

HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文

状态行

HTTP-Version Status-Code Reason-Phrase CRLF

其中

状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:

常见状态代码、状态描述、说明:

消息报头 & 响应正文

常见的响应头:

Location
响应报头域用于重定向接受者到一个新的位置
Server
响应报头域包含了服务器用来处理请求的软件信息
Allow
服务器支持哪些请求方法(如GET、POST等)
Set-Cookie
服务器向客户端设置Cookie
Content-Encoding
实体报头域被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。Content-Encoding这样用于记录文档的压缩方法,如:Content-Encoding:gzip
Content-Language
实体报头域描述了资源所用的自然语言。
Content-Length
实体报头域用于指明实体正文的长度,以字节方式存储的十进制数字来表示
Content-Type
实体报头域用语指明发送给接收者的实体正文的媒体类型。如:Content-Type:text/html;charset=GB2312
Last-Modified
实体报头域用于指示资源的最后修改日期和时间。
Expires
实体报头域给出响应过期的日期和时间。

参考