HTTP/1.0、HTTP/1.1、HTTP/2、HTTPS 总结笔记

前言

最近回顾网络的时候发现自己对于 HTTP1.x HTTP/2 HTTPS 协议有些模糊,之前学习的过程中没有完全消化好,借这次好好对 HTTP1.x HTTP/2 HTTPS 进行一个总结,对之前看过的几个博客进行归纳,也算是为了补补之前这块薄弱的基础。

HTTP

超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。

HTTP 属于 OSI 网络协议中应用层协议,是一个无状态的协议 ( HTTP无状态协议,是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快 ) 。

从浏览器输入地址到呈现页面中间发生了什么事情(简化版本)

  1. 浏览器(客户端)进行地址解析。
  2. 将解析出的域名进行dns解析。
  3. 通过ip寻址和arp,找到目标(服务器)地址。
  4. 进行tcp三次握手,建立tcp连接。
  5. 浏览器发送数据,等待服务器响应。
  6. 服务器处理请求,并对请求做出响应。
  7. 浏览器收到服务器响应,得到html代码。
  8. 渲染页面。

HTTP 的请求消息

一个来自客户端的HTTP请求包括:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。

  • 请求行:请求报文的第一行,用来说明以什么方式请求、请求的地址和HTTP版本
  • 头部字段:每个头部字段都包含一个名字和值,二者之间采用“:”连接,如:Connection:Keep-Alive
  • 请求数据:请求的主体根据不同的请求方式请求主体不同

如下所示:

1
2
3
4
5
6
7
8
9
10
11
GET  codingcms.cn HTTP/1.1
Host: codingcms.cn
Proxy-Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
---body---

HTTP 的响应消息

一个来自服务器的HTTP响应包括:状态行、消息报头、空行和响应正文组成

  • 状态行:由HTTP版本、响应状态码、响应状态描述;如:HTTP/1.1 200 OK
  • 响应报文头部:使用关键字和值表示,二者使用“:”隔开;如:Content-Type:text/html
  • 响应内容:请求空行之后就是请求内容

如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
HTTP/1.1 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Age: 8
Cache-Control: max-age=600
Content-Encoding: gzip
Content-Length: 11172
Content-Type: text/html; charset=utf-8
Date: Wed, 12 Aug 2020 16:01:48 GMT
Etag: W/"5f3172ad-febc"
Expires: Wed, 12 Aug 2020 15:56:37 GMT
Keep-Alive: timeout=58
Last-Modified: Mon, 10 Aug 2020 16:15:41 GMT
Server: GitHub.com
Vary: Accept-Encoding
Via: 1.1 varnish
X-Cache: HIT
X-Cache-Hits: 1
X-Fastly-Request-Id: 747d4cb4a9a20c4d9a8a26fffc9e2442204a5946
X-Github-Request-Id: 208A:4D2F:3238A9:34E6AD:5F340EDD
X-Proxy-Cache: MISS
X-Served-By: cache-tyo19941-TYO
X-Timer: S1597248109.570225,VS0,VE0

---body---

常用的状态码

状态码 说明
200 OK 表示从客户端发送给服务器的请求被正常处理并返回
204 No Content 表示客户端发送给客户端的请求得到了成功处理,但在返回的响应报文中不含实体的主体部分(没有资源可以返回)
206 Patial Content 表示客户端进行了范围请求,并且服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。
301 Moved Permanently 永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL
302 Found 临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL
303 See Other 表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源
304 Not Modified 表示客户端发送附带条件(是指采用GET方法的请求报文中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的请求时,服务器端允许访问资源,但是请求为满足条件的情况下返回改状态码
307 Temporary Redirect 临时重定向,与303有着相同的含义,307会遵照浏览器标准不会从POST变成GET;(不同浏览器可能会出现不同的情况)
400 Bad Request 表示请求报文中存在语法错误
401 Unauthorized 未经许可,需要通过HTTP认证
403 Forbidden 服务器拒绝该次访问(访问权限出现问题)
404 Not Found 表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用
500 Inter Server Error 表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时
503 Server Unavailable 表示服务器暂时处于超负载或正在进行停机维护,无法处理请求

HTTP1.1

HTTP/1.1:1997年1月发布,进一步完善HTTP协议,是目前最流行的版本,与 HTTP 1 的主要区别如下:

  • 缓存处理:HTTP/1.0 使用 Pragma:no-cache + Last-Modified/If-Modified-Since来作为缓存判断的标准;HTTP/1.1 引入了更多的缓存控制策略:Cache-Control、Etag/If-None-Match等
  • 错误状态管理:HTTP/1.1新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
  • 范围请求:HTTP/1.1在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接,支持断点续传
  • Host头:HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。有了Host字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础
  • 持久连接:HTTP/1.1 最大的变化就是引入了持久连接(persistent connection),在HTTP/1.1中默认开启 Connection: keep-alive,即TCP连接默认不关闭,可以被多个请求复用,客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接。客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接
  • 管道机制:HTTP/1.1中引入了http管道(http pipeline)概念,将浏览器的FIFO队列移动到了服务端,浏览器会将请求全部都发送给服务端,然后等着接受就ok了。这样服务器处理完第一个就处理第二个,不会有空闲等待了。

HTTP 1.1 的问题

  • 服务端收到多个管道请求后,需要按接受顺序一个一个处理,如果第一个请求特别慢,后续所有相应都会跟着阻塞。这种情况就是队首阻塞问题(head of line blocking)

  • 服务端为了保证按顺序回传,需要缓存多个响应,从而占用更多服务器资源

  • 如果浏览器连续发送多个请求,中间因为网络导致断开,无法得知服务器处理情况,只能进行全部重试导致服务器重复处理

  • http/1.x时代的http header请求头总是重复和冗余的,协议头部使用纯文本格式,没有任何压缩,且包含很多冗余信息(例如 Cookie、UserAgent 每次都会携带)这造成了大量没有必要的网络开销,导致tcp的拥塞窗口快速填充,这回导致当在一个新的TCP连接上发出多个请求时,造成过多的延迟.

HTTP 2

HTTP/2以Google发布的SPDY协议为基础,于2015年发布。它不叫HTTP/2.0,因为标准委员会不打算再发布子版本了,下一个新版本将是HTTP/3。HTTP/2协议只在HTTPS环境下才有效,升级到HTTP/2,必须先启用HTTPS。HTTP/2解决了HTTP/1.1的性能问题,主要特点如下:

  • 二进制分帧:HTTP/1.1的头信息是文本(ASCII编码),数据体可以是文本,也可以是二进制;HTTP/2 头信息和数据体都是二进制,统称为“帧”:头信息帧和数据帧;
  • 多路复用(双工通信):通过单一的 HTTP/2 连接发起多重的请求-响应消息,即在一个连接里,客户端和浏览器都可以同时发送多个请求和响应,而不用按照顺序一一对应,这样避免了“队头堵塞”。HTTP/2 把 HTTP 协议通信的基本单位缩小为一个一个的帧,这些帧对应着逻辑流中的消息。并行地在同一个 TCP 连接上双向交换消息。
  • 数据流:因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。另外还规定,客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数。数据流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM帧),取消这个数据流。HTTP/1.1取消数据流的唯一方法,就是关闭TCP连接。这就是说,HTTP/2 可以取消某一次请求,同时保证TCP连接还打开着,可以被其他请求使用。客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。
  • 首部压缩:HTTP 协议不带有状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这一点做了优化,引入了头信息压缩机制(header compression)。一方面,头信息压缩后再发送(SPDY 使用的是通用的DEFLATE 算法,而 HTTP/2 则使用了专门为首部压缩而设计的 HPACK 算法)。;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
  • 服务端推送:HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)。常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。

HTTPS

HTTPS可以说是安全版的HTTP,HTTPS基于安全SSL/TLS(安全套接层Secure Sockets Layer/安全传输层Transport Layer Security)层,即在传统的HTTP和TCP之间加了一层用于加密解密的SSL/TLS层。HTTP默认使用80端口,HTTPS默认使用443端口。

不使用SSL/TLS的HTTP通信,所有信息明文传播,会带来三大风险:

窃听风险:第三方可以获取通信内容;篡改风险:第三方可以修改通信内容;冒充风险:第三方可以冒充他人进行通信。SSL/TLS协议是为了解决这三大风险而设计的,以期达到:

信息加密传输:第三方无法窃听;校验机制:一旦被篡改,通信双方会立刻发现;身份证书:防止身份被冒充。

SSL/TLS运行机制
SSL/TLS的基本思路是公钥加密法:客户端先向服务器索要并验证公钥,然后用公钥加密传输来协商生成“对话秘钥”(非对称加密),双方采用“对话秘钥”进行加密通信(对称加密)。

通信过程如下:

  1. 客户端发出请求:给出支持的协议版本、支持的加密方法(如RSA公钥加密)以及一个客户端生成的随机数(Client random);
  2. 服务端回应:确认双方通信的协议版本、加密方法,并给出服务器证书以及一个服务器生成的随机数(Server random);
  3. 客户端回应:客户端确认证书有效,取出证书中的公钥,然后生成一个新的随机数(Premaster secret),使用公钥加密这个随机数,发送给服务端;
  4. 服务端回应:服务端使用自己的私钥解密客户端发来的随机数(Premaster secret),客户端和服务端根据约定的加密方法,使用三个随机数,生成“对话秘钥”;
  5. 会话通信:客户端和服务端使用“对话秘钥”加密通信,这个过程完全使用普通的HTTP协议,只不过用“会话秘钥”加密内容。

参考资料