HTTP 协议笔记

回顾市场上面,基本上现在所有 app 都基于网络,电子商务,图片浏览,视频聊天,浏览网页无一不和网络密切相关。而网络请求,绝大部分都是基于 HTTP 协议,所以对 HTTP 的认知显得尤为重要。

1. HTTP 请求方法

1.1 方法列表

HTTP 方法除了我们熟悉的 GET POST PUT DELETE 外,还有一些其他方法,比如 HEAD CONNECT TRACE OPTIONS.

  • GET,请求服务器返回给定资源,不会对服务器发生修改。
  • POST,服务器提交数据,通常用在表单提交里面。
  • PUT,创建一个资源,比如 PUT /article/feel-fine-with-android 会创建一个 feel-fine-with-android 的资源。内容是请求的请求体。
  • DELETE,请求服务器删除地址资源。
  • HEAD,HEAD 方法和 GET 方法一样,区别在于该方法只会返回头部信息,没有内容。通常用来检查资源的状态。
  • CONNECT,HTTP/1.1协议预留,能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接与非加密的HTTP代理服务器的通信。
  • TRACE,调试用途,响应内容里面会包含请求处理路径。
  • OPTIONS,请求服务器输出自己支持的 HTTP 方法。

1.2 安全方法

安全方法是指不会给服务器带来影响的方法,比如说 GET 和 HEAD 方法,就是安全方法,他们只会要求服务器输出资源,不会修改服务器的状态。

1.3 等幂性

等幂性是指多次重复的请求能否保证资源的状态的一致性。比如说,GET 和 HEAD 请求,无论客户端请求多少次一样的 URL,得到的结果和服务器的状态都不会发生变化,所以他们是等幂的。而 POST 请求,一般情况下,都会提交数据给服务器修改服务器状态,多次提交就会多次修改状态,不具备等幂性。

其实请求方法是否具有等幂性在于程序的实现,一般情况下,我们需要把 GET PUT DELETE HEAD 等设计成等幂性。

1.4 PUT versus POST

PUT 与 POST 常常会被认为很相似,其实他们是不同的,比较下面两个例子。

1
2
3
PUT /article/i-am-a-aricle

POST /article

通过对比可以看到,PUT 方法操作是相对于具体的资源,POST 操作则是对于资源的集合。而且 PUT 方法具有等幂性,多次 PUT 一个文章,服务器都会回存在这一个文章,而多次 POST 就很危险了。

2. HTTP 状态码

2.1 分类

  • 1xx 提示信息
  • 2xx 成功
  • 3xx 资源被转移
  • 4xx 客户端错误
  • 5xx 服务端错误

3. HTTP 报文格式

请求和响应的报文格式大体类似,基本格式如下

1
2
3
4
<start line>\r\n
<headers>\r\n
\r\n
<body>\r\n

都是由 start line, header, body 构成,主要区别在于 start line.

3.1 Request 格式

请求的 start line 由方法、请求路径和 HTTP 版本构成。

1
2
3
4
<method> <url> <version>
<header>

<body>

例子

1
2
GET /abc.html HTTP/1.1
Host: 127.0.0.1

3.2 Response 格式

响应的 start line 由 HTTP 版本、状态码和状态描述信息构成。

1
2
3
4
<version> <status> <phase>
<header>

<body>

例子

1
2
3
4
5
6
7
8
9
10
11
12
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accept-Ranges: bytes
ETag: W/"223-1460337344000"
Last-Modified: Mon, 11 Apr 2016 01:15:44 GMT
Content-Type: text/html
Content-Length: 223
Date: Thu, 02 Jun 2016 03:41:58 GMT

<html>
...
</html>

4. HTTP 传输

HTTP 报文传输是基于 TCP 协议与 IP 协议的,数据传输从建立 TCP 连接开始。

4.1 请求处理流程

假设我们现在要访问 http://caodongping.me, 相应的流程如下。

1、 解析出 url 中的域名, caodongping.me

2、通过 DNS 解析查询域名对应的 IP,192.30.252.153

3、解析出 url 中的端口,默认端口 80

4、通过 IP 和端口号,建立 TCP 连接,192.30.252.153:80

5、通过 TCP 连接传输 HTTP 请求报文给服务器,

1
2
GET / HTTP/1.1
Host: caodongping.me

6、服务器输出 HTTP 响应报文给客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HTTP/1.1 200 OK
Server: GitHub.com
Date: Thu, 02 Jun 2016 12:00:45 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 12692
Last-Modified: Wed, 25 May 2016 12:48:09 GMT
Access-Control-Allow-Origin: *
Expires: Thu, 02 Jun 2016 12:10:45 GMT
Cache-Control: max-age=600
Accept-Ranges: bytes
X-GitHub-Request-Id: 74F77098:7A86:3F0D6D4E:57501FED

<!DOCTYPE html>
...

7、客户端关闭连接