http(HyperText Transfer Protocol)是一个应用层协议,由请求和响应构成,是标准的客户端服务器模型。http/1.1协议目前在服务器领域还是有着广泛的应用,尽管现在越来越多的网站和服务使用https协议(http承载于TLS或SSL协议层之上),包括新的http/2协议。
http连接的建立
http是一个无状态的协议,基于tcp协议来实现。
以下是浏览器访问http://www.suninf.net/links.html 建立连接的抓包截图:
http连接的第一步是tcp的三次握手:
- 本机A(192.168.0.101)向服务器B(45.78.27.83)发送随机seq=0的[SYN]包请求建立连接;
- B收到请求后要确认联机信息,发送ack=1(A的seq+1),随机seq=0的[SYN,ACK]的包;
- 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
其中
- Method表示请求方法;
- Request-URI是一个统一资源标识符;
- HTTP-Version表示请求的HTTP协议版本;
- CRLF表示回车和换行
请求方法有多种,解释如下:
- GET 请求获取Request-URI所标识的资源
- POST 在Request-URI所标识的资源后附加新的数据
- HEAD 请求获取由Request-URI所标识的资源的响应消息报头
- PUT 请求服务器存储一个资源,并用Request-URI作为其标识
- DELETE 请求服务器删除Request-URI所标识的资源
- TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
- CONNECT 保留将来使用
- OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
最常见的是 GET 和 POST 的请求。
比如:
- 浏览器的地址栏中输入网址的方式访问网页时,浏览器采用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
其中
- HTTP-Version 表示服务器HTTP协议的版本;
- Status-Code 表示服务器发回的响应状态代码;
- Reason-Phrase 表示状态代码的文本描述。
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
- 1xx:指示信息,表示请求已接收,继续处理
- 2xx:成功,表示请求已被成功接收、理解、接受
- 3xx:重定向,要完成请求必须进行更进一步的操作
- 4xx:客户端错误,请求有语法错误或请求无法实现
- 5xx:服务器端错误,服务器未能实现合法的请求
常见状态代码、状态描述、说明:
- 200 OK //客户端请求成功
- 400 Bad Request //客户端请求有语法错误,不能被服务器所理解
- 401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
- 403 Forbidden //服务器收到请求,但是拒绝提供服务
- 404 Not Found //请求资源不存在
- 500 Internal Server Error //服务器发生不可预期的错误
- 503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
消息报头 & 响应正文
常见的响应头:
- 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
- 实体报头域给出响应过期的日期和时间。