02 April 2020

常见状态码(常见的不说了,只说几个需要特别记住的)

  • 304 Not Mondified - 客户端有缓存,询问服务器资源是否修改(If Modified Since),服务器比较 Last Modified 和 If Modified Since , 如果未修改,直接返回304 - 资源未修改。
  • 499 client has closed connection - 客户端主动断开连接
  • 502 Bad Gateway - 服务器作为网关或代理,自身工作正常,访问后端服务器发生错误(比如PHP-FPM达到最大子进程数)
  • 503 Service Unavailable - 服务器忙,无法响应
  • 504 Gateway Timeout - 服务器作为网关或代理,未及时从后端服务器接收请求(通常与nginx配置有关,例如fastcgi_connect_timeout)

常用字段

  • 请求
    • GET /http/2020/04/02/http HTTP/1.1
    • Host: chaojidan.github.io
    • Connection: keep-alive
    • User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
    • Accept: */*
    • Referer: http://chaojidan.github.io/
    • Accept-Encoding: gzip, deflate
  • 响应
    • HTTP/1.0 200 OK
    • Content-Length: 1000
    • Content-Type: text/html; charset=utf-8
    • Server: GitHub.com
    • Content-Encoding: gzip
    • Expires: Fri, 03 Apr 2020 01:06:49 GMT
    • Last-Modified: Thu, 02 Apr 2020 10:38:59 GMT
    • Access-Control-Allow-Origin: *

GET 和 POST的区别

  • GET在浏览器回退时是无害的(幂等),而POST会再次提交请求(非幂等)。

  • GET产生的URL地址可以被Bookmark,而POST不可以。

  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。

  • GET请求只能进行url编码,而POST支持多种编码方式。

  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

  • GET请求在URL中传送的参数是有长度限制的,而POST么有。

  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

  • GET参数通过URL传递,POST放在Request body中。

  • POST时如果数据量比较大,客户端可能会分两次发送,先发送请求头,如果服务器回复“100 - Continue”,则继续发送请求体。

HTTP的特点

  • 简单,灵活,易扩展
  • 应用广泛,跨平台
  • 无状态
  • 明文传输

HTTPS 相关

特点:

  • 加密传输,在TCP和HTTP之间加入 SSL/TLS 安全协议。 SSL 是 “Secure Sockets Layer” 的缩写,中文意思为“安全套接层”,而 TLS 则是标准化之后的 SSL。
  • 除了TCP三次握手,还需要进行 SSL/TLS 握手
  • 端口号443
  • 需要向CA(证书权威机构)申请数字证书。

https解决了以下问题:

  • 防窃听 - 加密传输 - 混合加密机制 - 非对称加密和对称加密
  • 防篡改 - 校验机制 - 摘要算法
  • 防冒充 - 身份证书 - 如何保证服务器公钥不被篡改?借助第三方权威机构(CA),将服务器公钥放入数字证书中

混合加密机制:

  • 先用非对称加密方式交换"会话密钥"
  • 通信过程中全部使用对称加密的"会话密钥"加密明文数据

SSL/TLS 四次握手

  1. ClientHello,客户端->服务器,包含以下信息:
    • 客户端支持的 SSL/TLS 协议版本
    • 客户端生产的随机数
    • 客户端支持的加密算法
  2. ServerHello,服务器->客户端,包含以下信息:
    • 确认 SSL/TLS 协议版本,如客户端不支持则关闭加密通信
    • 服务器生产的随机数
    • 确认双方使用的加密算法
    • 服务器的数字证书
  3. 客户端回应
    • 通过浏览器或操作系统中的CA公钥,确认服务器数字证书的真实性
    • 取出数字证书中的公钥。
    • 生成一个随机数(pre-master key),用公钥加密,发给服务器
    • 用三个随机数生成"会话密钥",发送加密通信算法改变通知,表示随后的信息都将用"会话密钥"加密通信
    • 客户端握手结束通知,包含之前所有握手数据摘要,共服务器校验
  4. 服务器端最后回应
    • 接收客户端的第三个随机数(pre-master key),通过协商的加密算法,算出本次通信的"会话密钥"
    • 发送加密通信算法改变通知。
    • 服务器握手结束通知,包含之前所有握手数据摘要,共客户端校验

之后就可以用普通HTTP协议进行通信,只不过用"会话密钥"加密内容。

另外,以上加密过程的通话安全只取决于第三个随机数(pre-master key),为了足够安全,可以把默认的RSA算法改成 Diffie-Hellman算法(简称DH算法)。

采用DH算法后,Premaster secret不需要传递,双方只要交换各自的参数,就可以算出这个随机数。

TLS 1.3 与之前版本的差异:

  • 相比过去的的版本,引入了新的密钥协商机制 — PSK
  • 支持 0-RTT 数据传输,在建立连接时节省了往返时间
  • 废弃了 3DES、RC4、AES-CBC 等加密组件,废弃了 SHA1、MD5 等哈希算法
  • ServerHello 之后的所有握手消息采取了加密操作,可见明文大大减少
  • 不再允许对加密报文进行压缩、不再允许双方发起重协商
  • DSA 证书不再允许在 TLS 1.3 中使用

TLS 1.3的两大优势

  • 更快的访问速度(快将近100ms)。 TLS 1.2 需要两次往返( 2-RTT )才能完成握手,TLS 1.3 的握手不再支持静态的 RSA 密钥交换, 这意味着必须使用带有前向安全的 Diffie-Hellman 进行全面握手, 所以使用 TLS 1.3 协议只需要一次往返( 1-RTT )就可以完成握手。
  • 更强的安全性,删除了不安全的加密算法

HTTP/1.1、HTTP/2、HTTP/3 的演变

HTTP/1.1 相比 HTTP/1.0的改进

  • 支持长连接
  • 管道(pipeline)网络传输:同一个TCP连接,客户端可发起多个请求,不必等前一个请求返回就可以发下一个请求 (但服务器还是按照顺序返回的,如果前一个请求响应慢,后面的请求会排队等待,造成队头阻塞)

HTTP/1.1的性能瓶颈

  • 请求/响应头部不能压缩,只能压缩body部分。
  • 每次发送相同头部造成浪费
  • 队头阻塞 Head-Of-Line Blocking(HOLB)问题
  • 没有请求优先级控制
  • 请求只能从客户端开始,服务器只能被动响应

HTTP/2 相比于 HTTP/1.1 的改进

  • 头部压缩,HPACK算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不用发送同样字段了, 只发送索引号即可。
  • 二进制格式,统称为帧(frame),头信息帧和数据帧,增加传输效率
  • 数据流(Stream)。数据包不是按顺序发送的,同一个连接里面连续的数据包可能属于不同的响应。因此必须对数据包做标记,指出它属于哪个回应。
    每个请求或回应的所有数据包,称为一个数据流。
    每个数据流都有一个唯一编号,客户端发出的数据流编号为奇数,服务器端发出的数据流编号为偶数。
    客户端可指定数据流的优先级。
  • 多路复用,可以在一个连接中并发多个请求或回应,不用按照循序一一对应,不会出现队头阻塞问题。
  • 服务器推送(Server Push),服务器不再是被动响应,可以主动向客户端发送消息。

HTTP/2的问题

多个HTTP请求复用一个TCP连接,下层TCP协议不知道有多少个HTTP请求,一旦发生丢包现象,就会出发TCP重传机制,在一个TCP连接中的所有 HTTP请求都必须等这个丢了的包被重传回来,后面的所有数据都被阻塞了,这种情况下 HTTP/2 的表现反倒不如 HTTP/1 了, 和HTTP/1.1中的管道队头阻塞问题类似,这都是TCP协议本身造成的。 另外,延迟(Latency)的升高对HTTP/2的影响比较大,主要原因是HTTP/2 的7层和3层都有ack的设计。 Server Push 和 HPACK压缩会带来一些其他问题,比如已缓存数据的重复推送和针对HTTP/2的攻击等。

HTTP/3的改进

HTTP/3把HTTP下层的TCP改成了UDP,UDP不管顺序,也不管丢包,所以不会出现队头阻塞和丢包重传问题。 基于UDP协议的QUIC协议可以实现类似TCP的可靠性传输。
TLS升级成1.3
头部压缩算法升级成QPack