HTTP协议备忘录

HTTP

Posted by HandsomeWalker on April 11, 2022

HTTP 协议

本文用于归纳自己所学的 HTTP 知识, HTTP 协议的知识众多, 平时的点点滴滴的积累最终就能分解并吸收这些内容, 因此也是出于这个目的

常见状态码

100 Continue:上传大文件前使用

101 Switch Protocols:协议升级使用

102 Processing:服务器已经收到并正在处理请求,但无响应可用

200 OK:成功返回响应

201 Created:有新资源在服务器端被成功创建

202 Accepted:服务器接受并开始处理请求,但请求未处理完成

206 Partial Content:使用 range 协议时返回部分响应内容时的响

300:是一个特殊的重定向状态码,会返回一个有多个链接选项的页面,由用户自行选择

301: 永久重定向

302: 临时重定向

303:类似于 302,重定向后的请求方法改为 GET 方法

304:是一个特殊的重定向状态码,服务端验证过期缓存有效后,要求客户端使用该缓存

307:类似于 302,含义比 302 更明确,重定向后请求的方法和实体不允许变动

308:类似于 301,代表永久重定向,重定向后请求的方法和实体不允许变动

400 Bad Request:服务器认为客户端出现了错误,但不明确,一般是 HTTP 请求格式错误

401 Unauthorized:用户认证信息确实或者不正确

403 Forbidden:服务器理解请求的含义,但没有权限执行

404 Not Found:服务器没有找到对应的资源

405 请求方法不支持

407 Proxy Authentication Required:对需要经由代理的请求,认证信息未通过代理服务器的验证

408 Request Timeout:服务器接收请求超时

500 Internal Server Error:服务器内部错误,且不属于以下错误类型

502 Bad Gateway:代理服务器无法获取到合法响应

503 Service Unavailable:服务器资源尚未准备好处理当前请求

505 HTTP Version Not Supported:请求使用的 HTTP 协议版本不支持

GET 和 POST 的区别

主要是以下区别

GET 的特点

GET 请求参数放在 URL, 安全性较于 POST 略差, 且 URL 的参数长度在各个浏览器的实现中有最大限制(chrome4K), 请求能被缓存, 可以保存在浏览器历史记录中,也可以置于收藏夹中, 这种请求是无副作用的, 也就是幂等的, 常用于向服务器获取数据

POST 的特点

POST 请求的参数是放在 body 中的, 参数可以是任意的类型, 无大小限制, 安全性比 GET 好,请求无法被缓存, 也无法保存在收藏夹; 这样的请求是有副作用的, 也就是非幂等的, 用途广泛, 可以修改服务器的数据

TCP 的链接建立

TCP 通过三次握手建立连接, 通过四次挥手断开连接

三次握手

:::tip 概念 TCP(Transmission Control Protocol)传输控制协议 :::

TCP 是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:

位码即 tcp 标志位,有 6 种标示:

  • SYN(synchronous 建立联机)
  • ACK(acknowledgement 确认)
  • PSH(push 传送)
  • FIN(finish 结束)
  • RST(reset 重置)
  • URG(urgent 紧急)
  • Sequence number(顺序号码)
  • Acknowledge number(确认号码)

第一次握手:主机 A 发送位码为 syn = 1,随机产生 seq number=X(1234567) 的数据包到服务器,主机 B 由 SYN=1 知道,A 要求建立联机;

第二次握手:主机 B 收到请求后要确认联机信息,向 A 发送 ack number=(主机 A 的 seq+1),syn=1,ack=1,随机产生 seq=7654321 的包;

第三次握手:主机 A 收到后检查 ack number 是否正确,即第一次发送的 seq number+1,以及位码 ack 是否为 1,若正确,主机 A 会再发送 ack number=(主机 B 的 seq+1),ack=1,主机 B 收到后确认 seq 值与 ack=1 则连接建立成功。

客户端发起连接请求,发送 SYN 包(SYN=i)到服务器,并进入到 SYN-SEND 状态,等待服务器确认

服务器收到 SYN 包后,必须确认客户的 SYN(ack=i+1),同时自己也发送一个 SYN 包(SYN=k),即 SYN+ACK 包,此时服务器进入 SYN-RECV 状态

客户端收到服务器的 SYN+ACK 包,向服务器发送确认报 ACK(ack=k+1),此后客户端和服务器进入 ESTABLISHED 状态,双方可以开始传送数据

四次挥手

四次挥手

第一次挥手: 发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧)

第二次挥手: 被动方发送报文,Ack、Seq,表示同意关闭请求。此时主机发起方进入 FIN_WAIT_2 状态。(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)

第三次挥手: 被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧)

第四次挥手: 发起方向被动方发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)

SSL/TLS 的链接建立

SSL/TLS的握手

SSL/TLS 协议建立的详细流程:

ClientHello

首先,由客户端向服务器发起加密通信请求,也就是 ClientHello 请求。

在这一步,客户端主要向服务器发送以下信息:

(1)客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本。

(2)客户端生产的随机数(Client Random),后面用于生产「会话秘钥」。

(3)客户端支持的密码套件列表,如 RSA 加密算法。

:::tip 密码套件 密码套件由密钥交换算法, 数据加密算法, 消息验证算法组成 :::

SeverHello

服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello。服务器回应的内容有如下内容:

(1)确认 SSL/ TLS 协议版本,如果浏览器不支持,则关闭加密通信。

(2)服务器生产的随机数(Server Random),后面用于生产「会话秘钥」。

(3)确认的密码套件列表,如 RSA 加密算法。

(4)服务器的数字证书。

客户端回应

客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。

如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:

(1)一个随机数(pre-master key)。该随机数会被服务器公钥加密。

(2)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。

(3)客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。

上面第一项的随机数是整个握手阶段的第三个随机数,这样服务器和客户端就同时有三个随机数,接着就用双方协商的加密算法,各自生成本次通信的「会话秘钥」。

服务器的最后回应

服务器收到客户端的第三个随机数(pre-master key)之后,通过协商的加密算法,计算出本次通信的「会话秘钥」。然后,向客户端发生最后的信息:

(1)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。

(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。

至此,整个 SSL/TLS 的握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用「会话秘钥」加密内容。

HTTP2 的特点

HTTP2 解决了很多 HTTP1 的问题, 主要表现以下几个方面

  • 头部压缩

解决了 HTTP1 中的头部无法压缩的问题, 头部压缩采用 HPACK 算法, 间接提高传输速度

  • 二进制格式

头信息和数据体都是二进制,并且统称为帧(frame):头信息帧和数据帧

  • 数据流优先级

客户端还可以指定数据流的优先级。优先级高的请求,服务器就先响应该请求

  • 多路复用

HTTP/2 是可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应

  • 服务器推送

HTTP/2 还在一定程度上改善了传统的「请求 - 应答」工作模式,服务不再是被动地响应,也可以主动向客户端发送消息

HTTP3 的特点

HTTP2 虽然解决了很多历史遗留问题, 但是最致命的还是一旦丢包就会导致 TCP 的重传 多个 HTTP 请求在复用一个 TCP 连接,下层的 TCP 协议是不知道有多少个 HTTP 请求的。 所以一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来

  • 底层传输协议 QUIC

HTTP/3 把 HTTP 下层的 TCP 协议改成了 QUIC 协议, 它是基于 UDP 的一种协议, 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响。

  • 加密协议升级为 TLS1.3

TL3 升级成了最新的 1.3 版本,头部压缩算法也升级成了 QPac

  • 握手次数变为 3 次

HTTPS 要建立一个连接,要花费 6 次交互,先是建立三次握手,然后是 TLS/1.3 的三次握手。QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合并成了 3 次,减少了交互次数

TCP 和 UDP 的区别

TCP 和 UDP 都是传输层的协议,但二者有着截然不同的基因。

TCP

  • 面向连接
  • 面向字节流
  • 有状态
  • 保证可靠交付
  • 具备拥塞控制
  • 点对点传播
  • 有序

UDP

  • 无连接
  • 面向数据报
  • 无状态
  • 不保证可靠交付
  • 不具备拥塞控制
  • 广播、多播
  • 无序