HTTP 天生具有明文的特点,整个传输过程完全透明,任何人都能够在链路中截获、修改或者伪造请求 / 响应报文,数据不具有安全性。仅凭HTTP 自身是无法解决的,需要引入新的HTTPS协议,简单的说就是不安全。
HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立安全信道,加密数据包。
HTTPS 是一个“非常简单”的协议,RFC 文档很小,只有短短的 7 页,里面规定了新的协议名“https”,默认端口号 443,至于其他的什么请求 - 应答模式、报文结构、请求方法、URI、头字段、连接管理等等都完全沿用 HTTP,没有任何新的东西。
也就是说,除了协议名http和端口号 80 这两点不同,HTTPS 协议在语法、语义上和 HTTP 完全一样,优缺点也照单全收(当然要除去明文和不安全)
秘密就在于 HTTPS 名字里的“S”,它把 HTTP 下层的传输协议由 TCP/IP 换成了 SSL/TLS,由HTTP over TCP/IP变成了HTTP over SSL/TLS,让 HTTP 运行在了安全的 SSL/TLS 协议上,收发报文不再使用 Socket API,而是调用专门的安全接口。
HTTPS 并不是一个新的应用层协议,它其实就是 HTTP + TLS/SSL 协议组合而成,而安全性的保证正是 SSL/TLS 所做的工作 。 https = http + ssl/tls
SSL 即安全套接层(Secure Sockets Layer),在 OSI 模型中处于第 5 层(会话层),由网景公司于 1994 年发明,有 v2 和 v3 两个版本,而 v1 因为有严重的缺陷从未公开过。
SSL 发展到 v3 时已经证明了它自身是一个非常好的安全通信协议,于是互联网工程组 IETF 在 1999 年把它改名为 TLS(传输层安全,Transport Layer Security),正式标准化,版本号从 1.0 重新算起,所以 TLS1.0 实际上就是 SSLv3.1。
简单的理解就是安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性的作用。
TLS 协议包括两个协议组―― TLS 记录协议和 TLS 握手协议
TLS 由记录协议、握手协议、警告协议、变更密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术,具体可以查阅相关资料进一步了解。
你一定很想知道,为什么 HTTP/2 不像之前的1.0、1.1、那样叫2.0呢?
这个也是很多初次接触 HTTP/2 的人问的最多的一个问题,对此 HTTP/2 工作组特别给出了解释。
他们认为以前的1.0、1.1造成了很多的混乱和误解,让人在实际的使用中难以区分差异,所以就决定 HTTP 协议不再使用小版本号,只使用大版本号,从今往后 HTTP 协议不会出现 HTTP/2.0、2.1,只会有HTTP/2,HTTP/3……
目前还是很多公司都升级到了HTTP/2 比如 苹果官网、腾讯网、csdn、掘金 等
由于 HTTPS 已经在安全方面做的非常好了,所以 HTTP/2 的唯一目标就是改进性能,且兼容HTTP1.x 版本的。
头部压缩
HTTP/2 对报文的头部做了一个大的改变,由于报文Head一般会携带 User-Agent、Cookie、Accept、Server、Range 等许多固定的字段,多达几百甚至几千字节,而 Body 却经常只有几十字节,所以导致头部偏重。HTTP/2 使用HPACK
算法进行头部压缩。
二进制分帧
二进制分帧指的是传输的都是二进制,而帧只是一个传输单位。把原来的Header+Body的消息报文格式,拆分为一个一个的二进制“帧”(Frame),
用HEADERS帧存放头数据、DATA帧存放实体数据。
这样子的话,就是一堆乱序的二进制帧,它们不存在先后关系,因此不需要排队等待,解决了HTTP队头阻塞问题。
虚拟的流--多路复用
二进制分帧把数据都拆分为一个一个的二进制数据包,那么传输过去之后数据怎么组装起来呢?
HTTP/2 为此定义了一个流(Stream)的概念,它是二进制帧的双向传输序列,同一个消息往返的帧会分配一个唯一的流 ID。你可以把它想象成是一个虚拟的“数据流”,在里面流动的是一串有先后顺序的数据帧,这些数据帧按照次序组装起来就是 HTTP/1 里的请求报文和响应报文。
因为流是虚拟的,实际上并不存在,所以 HTTP/2 就可以在一个 TCP 连接上用流同时发送多个拆分之后的二进制帧数据包,这就是常说的多路复用( Multiplexing)——多个往返通信都复用一个连接来处理。
客户端将多个请求分成不同的流,然后每个流里面在切成一个个二进制帧,发送的时候是按二进制帧发送。每个帧存着一个流ID来表示它属于的流,服务端收到请求的时候将帧按流ID进行拼接。
从传输的角度来看流是不存在的,只是看到了一个个帧,所以说流是虚拟的,如图https 是大势所趋,通常所能见到的 HTTP/2 都是使用“https”协议名,跑在 TLS 上面。
为了区分“加密”和“明文”这两个不同的版本,HTTP/2 协议定义了两个字符串标识符:
1、h2表示加密的 HTTP/2
2、h2c表示明文的 HTTP/2,多出的那个字母c的意思是clear text
HTTP2 的核心就是二进制分帧、流概念、多路复用(永远都只在一个TCP 连接里面,因为一个TCP 中虚拟了很多流,一个请求-响应就对应一个流)
从HTTP/1.0诞生,一直到HTTP/2,在这24年里,HTTP协议已经做过了三次升级,但是有一个关键的技术点是不变的,那就是这所有的HTTP协议,都是基于TCP协议实现的。流水的HTTP,铁打的TCP,这是因为相对于UDP协议,TCP协议更加可靠。
HTTP/2废弃了管道化的方式,而是创新性的引入了帧、消息和数据流等概念。客户端和服务器可以把 HTTP 消息分解为互不依赖的帧,然后乱序发送,最后再在另一端把它们重新组合起来。因为没有顺序了,所以就不阻塞了,就有效的解决了HTTP对头阻塞的问题。
但是,HTTP/2仍然会存在对头阻塞的问题,那是因为HTTP/2其实还是依赖TCP协议实现的。
TCP传输过程中会把数据拆分为一个个按照顺序排列的数据包,这些数据包通过网络传输到了接收端,接收端再按照顺序将这些数据包组合成原始数据,这样就完成了数据传输。
但是如果其中的某一个数据包没有按照顺序到达,接收端会一直保持连接等待数据包返回(丢包重传机制),这时候就会阻塞后续请求。这就发生了TCP队头阻塞。
http/2 只是解决http 的对头阻塞,并没有解决tcp 的对头阻塞,队头阻塞分为两个层面,一个是HTTP 队头阻塞,一个是TCP 队头阻塞。
HTTP 是一个请求-应答的模式,类似一个队列,先进先出的模式,后面的一个请求只能等前面的请求好了,才发出请求。
如果队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求也不得不跟着一起等待,结果就是其他的请求承担了不应有的时间成本,造成了阻塞。
在HTTP1.1 中针对HTTP对头阻塞,增加了并发连接的规则,这也算是空间换时间的思路,浏览器与服务器建立多个TCP连接,现在比较常用的并发连接数已经增加到 6 - 8个,不同的浏览器应该不同的实现。
在HTTP2 中增加了流、以及二进制分帧、多路复用,让数据包之间可以是乱序的发送,数据包之间没有顺序的依赖关系,解决HTTP 对头阻塞的问题,但是底层还是基于TCP 协议,所以还存在TCP 对头阻塞问题,所以HTTP3 来了。
HTTP3的基本思路,应该跟处理这个HTTP 对头阻塞差不多,让各个数据包之间没有依赖关系,其中一个有问题,不会影响其他连接。
在HTTP/2 中应用层向下传输的数据是做到了乱序,二进制,但是TCP层的数据包还是有序传输,中间一个数据包丢失,会等待该数据包重传,造成后面的数据包的阻塞,这也就是丢包重传机制,因为TCP在丢包的情况下必须等待重传确认,此时其他包就算到达缓冲区,上层应用也是无法拿出来的。
做兴趣使然的Hero,发现问题,解决问题。