Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[笔记] - HTTP & HTTPs #32

Open
zhaofeihao opened this issue May 4, 2020 · 0 comments
Open

[笔记] - HTTP & HTTPs #32

zhaofeihao opened this issue May 4, 2020 · 0 comments
Labels

Comments

@zhaofeihao
Copy link
Owner

[TOC]

http1.0、http1.1、http2.0、https分析对比

http1.0

  • 超文本传输协议,不仅可以传输文字,还可传输视频、图片、二进制文件
  • 增加POST和HEAD命令
  • 增加状态码、缓存等

http1.0存在问题

每个tcp连接只能发送一个请求,下一个请求发送需要重新建立tcp连接,性能很差

http1.1

针对http1.0的问题,http1.1做了很大的优化

长连接

http1.1默认connection:keep-alive,一个tcp连接可以持续传输请求。

管道机制

因为http1.1支持长连接,发送一个请求之后还可以发送第二个请求,如果第二个请求要等待第一个请求返回之后才发送,效率就很低,所以引入了管道机制,多个请求可以按顺序同时发送,响应按顺序返回

Content-Length

因为一个tcp可以同时发送多个请求,我们需要一个字段来区分多个请求,Content-length表示当前请求响应共有多少字段,超过这个值的响应就不是该请求的响应

分块传输

因为http1.1是按顺序发送请求和响应,如果一个顺序靠前的请求响应时间较长,会阻碍后面请求的响应,造成很大的延迟,这就是线头阻塞。故http1.1支持分块传输:Transfer-Encoding: chunked,每个响应头前都有一个16进制数字表示该块儿大小,如果为0表示本次分块数据传输完成

其他功能

新增PUT、PATCH、HEAD、 OPTIONS、DELETE请求方法

客户端请求头新增Host字段,有了Host字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础。

http1.1存在问题

主要还是线头阻塞问题,为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。这导致了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。如果HTTP协议设计得更好一些,这些额外的工作是可以避免的。

http1.1和http1.0对比

  • 缓存处理:http1.0中只有if-Modified-Since、Expires,http1.1中增加了E-tag、if-None-match、等
  • 优化带宽和网络请求:如果我们的请求的只是一个资源的一部分,http1.0会全部返回整个资源,造成带宽的浪费,http1.1中增加了range字段,允许请求资源的某部分
  • 错误通知机制:新增了24个错误状态码
  • Host名增加:http1.0认为域名和主机是一一对应的,http1.1增加Host字段,支持多个域名对应一个机器,为虚拟主机的发展奠定了基础
  • 长连接:支持长连接和管道机制,一定程度上弥补了http1.0每次请求都要重建tcp连接的缺陷

http2.0/SPDY

http2.0是基于SPDY的,两者没有太大的区别,主要是header压缩方式以及http2.0支持明文传输。

对比http1.1,主要区别有以下几个

多路复用

http2.0一个tcp连接支持多个stream流同时传输
546da8c3ae827b1ff00cc658d15f33e2.png

请求优先级

多路复用可能会带来一个新的问题,多个请求并发可能导致关键请求被阻塞,故http2.0支持request设置优先级

header压缩

header中的一些信息是重复的,采用合适的压缩算法减少请求大小

服务端推送

正常文档流请求style.css后服务端会主动推送script.js到客户端,服务端请求的时候直接从缓存读取

https

https是运行在tcp协议上基于SSL/TLS的安全通信机制,其实整个加密过程比较简单,通过一张图就能很清晰,但是一些细节还是值得探究的。先上图:
4e67a8675ee0a61080968aa421fcdb0a.png

  1. Client发送请求到Server
  2. Server生成一对公钥秘钥
  3. Server返回安全证书和公钥
  4. Client验证证书是否有效,若无效,直接弹出警告页面,有效的话随机生成一个秘钥
  5. 用证书的公钥加密生成的秘钥,并发送给Server
  6. Server用秘钥解开公钥,拿到秘钥
  7. 用秘钥加密发送的内容
  8. Client用秘钥解密内容,拿到请求数据

SSL/TLS

TLS是在SSL基础上发展过来的,实质上是一个东西。那么TLS主要做的几件事:

  1. 加密
  2. 证书验证

加密机制实际上是在tcp链接三次握手基础上实现的:
1deb1bea3497add1bfc8c055ce093ba2.png

前面是正常的tcp连接过程:

  1. Client发送SYN和seq码给Server
  2. Server收到seq并将其+1赋值给ACK确认码,同时生成自己的SYN码,一同发送给Client
  3. Client收到seq,将其+1并赋值给ACK确认码

如果是正常的http连接,直接将ACK确认码发送给Server,Server收到就可以建立连接了。但是Https在这里才真正的开始。
4. Client1: Client将ACK确认码+TLS版本号+所支持加密套件列表+希望使用的TLS选项发送给Server
5. Server1: Server收到后从加密套件列表中选择合适的加密套件,将选择的加密套件+自己的公钥+自己的安全证书+希望使用的TLS选项(+要求Client证书)发送给Client
6. Client2: CLient经过一系列验证和加密后,将(Client自己的证书+)经过公钥加密后的秘钥发送给Server
7. Server2: Server使用私钥进行解密后得到秘钥,发送加密的Finish消息,表明完成握手

证书机制/证书验证

Client拿到Server证书后需要验证证书的有效性,流程一般是:

站点证书颁发者-->中间证书颁发者-->根证书颁发者
4753885329939c9d1786a76c71f0f825.png

验证策略
CRL

CRL(Certificate Revocation List)即证书撤销名单。证书颁发者会提供一份已经失效证书的名单,供浏览器验证证书使用。当然这份名单是巨长无比的,浏览器不可能每次TLS都去下载,所以常用的做法是浏览器会缓存这份名单,定期做后台更新。这样虽然后台更新存在时间间隔,证书失效不实时,但一般也OK

OCSP

OCSP(Online Certificate StatusProtocol)即在线证书状态协议。除了离线文件,证书颁发者也会提供实时的查询接口,查询某个特定证书目前是否有效。实时查询的问题在于浏览器需要等待这个查询结束才能继续TLS握手,延迟会更大

参考资料:
http总结

全面解读HTTP&HTTPS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant