HTTP1.0、HTTP2.0、HTTP3.0、HTTPS、SSL
作者:互联网
之前陆陆续续更新了C++面经、数据结构与算法相关面经、STL原理剖析、操作系统等总结,有需要的小伙伴可以翻翻之前上传的博客,接下来将继续更新有关于计算机网络的相关知识点。
四、计算机网络
1、HTTP
1.1、概念:
超文本传输协议,HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。HTTP协议工作于客户端-服务端(C/S)架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即Web服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。HTTP协议是以明文方式发送信息的,如果有人截取了web浏览器和服务器之间的传输报文,就可以直接获得其中的信息。
1.2、HTTP请求过程
一次HTTP操作称为一个事务,其工作过程可分为四步:
1)首先客户机与服务器需要建立连接。只要单击某个超级链接,HTTP的工作开始。
2)建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。
3)服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
4)客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接
1.3、HTTP的状态码
HTTP无状态是指不能保存客户信息,响应一次就断开。状态码是用于表示HTTP的状态 。
常见的状态码:
100 continue 表明到目前为止都很正常,客户端可以继续发生请求或忽略该响应
200 OK //客户端请求成功,如果是⾮ HEAD 请求,服务器返回的响应头都会有 body数据
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
408 Request Timeout //请求超时
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
100 | Continue | 继续。客户端应继续其请求 |
---|---|---|
101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 |
200 | OK | 请求成功。一般用于GET与POST请求 |
201 | Created | 已创建。成功请求并创建了新的资源 |
202 | Accepted | 已接受。已经接受请求,但未处理完成 |
203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档 |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 |
206 | Partial Content | 部分内容。服务器成功处理了部分GET请求 |
300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 |
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
303 | See Other | 查看其它地址。与301类似。使用GET和POST请求查看 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
306 | Unused | 已经被废弃的HTTP状态码 |
307 | Temporary Redirect | 临时重定向。与302类似。使用GET请求重定向 |
400 | Bad Request | 客户端请求的语法错误,服务器无法理解 |
401 | Unauthorized | 请求要求用户的身份认证 |
402 | Payment Required | 保留,将来使用 |
403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面 |
405 | Method Not Allowed | 客户端请求中的方法被禁止 |
406 | Not Acceptable | 服务器无法根据客户端请求的内容特性完成请求 |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
409 | Conflict | 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突 |
410 | Gone | 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置 |
411 | Length Required | 服务器无法处理客户端发送的不带Content-Length的请求信息 |
412 | Precondition Failed | 客户端请求信息的先决条件错误 |
413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 |
414 | Request-URI Too Large | 请求的URI过长(URI通常为网址),服务器无法处理 |
415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式 |
416 | Requested range not satisfiable | 客户端请求的范围无效 |
417 | Expectation Failed | 服务器无法满足Expect的请求头信息 |
500 | Internal Server Error | 服务器内部错误,无法完成请求 |
501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
502 | Bad Gateway | 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,无法完成处理 |
1.4、HTTP请求报文
一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成。
Host:将请求发往「同⼀台」服务器上的不同⽹站
Content-Length:服务器在返回数据时,表明本次回应的数据⻓度
Connection:⽤于客户端要求服务器使⽤ TCP 持久连接,以便其他请求复⽤,keep_alive
Content-Type:⽤于服务器回应时,告诉客户端,本次数据是什么格式
Accept:声明自己可以接受那些数据格式
Content-Encoding :说明数据的压缩⽅法,表示服务器返回的数据使⽤了什么压缩格式
1.5、Get和Post的区别
HTTP/1.1 定义的请求方法有8种:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。
1、get和post的区别
Get是请求从服务器获取资源,这个资源可以是静态的⽂本、⻚⾯、图⽚视频等。
Post是向 URI 指定的资源提交数据,数据就放在报⽂的 body ⾥
get是向URL添加数据,post有request body
- 对于后退按钮/刷新:get是无害的,post数据会被重新提交(所以浏览器应该告知用户数据会被重新提交);
- 书签:get可收藏为数千,post不行;
- 历史:get参数保留在浏览器历史中,post参数不会保存在浏览器历史中;
- 对数据长度的限制:发送的时候GET向URL添加数据(URL的长度是受限制的,最大长度是2048个字符),POST没有限制;
- 安全性:GET安全性更差,因为所发送的数据是URL的一部分(在发送密码或其他敏感信息不要使用GET),POST更安全(参数不会被保存在浏览器历史或web服务器日志中);
- GET产生一个TCP数据包,浏览器会把http header和data一并发送出去,服务器响应200(返回数据); POST产生两个TCP数据包,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)
2、get和post的本质
-
HTTP的底层是TCP/IP ,所以get和post的底层也是TCP/IP。所以从原理上来说,给get加上request body,post加上URL参数,都是完全可行的。但是,HTTP准则就这么规定的,就相当于是交通规则,只是要求get和post这么做,其实他们的实现还是用TCP做的。
-
关于参数长度的限制,数据量太大对于浏览器和服务器都是很大的负担,通常浏览器会限制URL长度在2K个字节,大多数服务器最多处理64K大小的URL,超过的部分就不处理了。要是用get加上request body,不同的服务器处理方式不同,有些服务器会读出数据,有些就直接忽略了,所以,虽然GET可以带上request body,但是不能保证一定会被收到;
3、GET 和 POST 都是安全和幂等的吗?
先说明下安全和幂等的概念:
-
在 HTTP 协议⾥,所谓的「安全」是指请求⽅法不会「破坏」服务器上的资源。
-
所谓的「幂等」,意思是多次执⾏相同的操作,结果都是「相同」的。
那么很明显 GET ⽅法就是安全且幂等的,因为它是「只读」操作,⽆论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的。POST 因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的。
1.6、Cookie和Session
因为HTTP协议是无状态的,所以需要用到cookie和session来记录用户信息,用来跟踪浏览器用户身份的会话方式, cookies 机制采用的是客户端保持状态的方案,session 采用在服务器端保持的方案。但时,客户量大的时候,采用session的会话方式,因为数据保存在服务器端,服务器的压力会较大。
1、Cookie
举个例子:网上购物的时候,开始的时候先登录,选中商品加入到购物车这个过程,可以通过以下4步描述:
客户端带着登录信息请求服务器端;
服务器端响应(登录成功与否)到客户端;
客户端发送购物车里的信息到服务器端;
然后服务器端返回添加成功与否到服务器端;
问题的关键就是在第二次请求加入购物车的时候,因为HTTP客户端请求服务端是一种无状态的连接,那服务器怎么直到是谁以及加入谁的购物车;解决办法就是在request到达服务器的时候,服务器在response中加入一个小饼干,cookies包含用户登录时的一些基本信息,当第二次客户端发起请求的时候,服务器端检查小饼干,识别出客户端,找到相应的缓存,缓存中放着用户名、密码和一些用户设置项。
2、Session
session也有cookie,但其中保存的不再是直接的数据,而是一个ID,在服务器端,服务器根据客户端的JsessinID来判断。服务器端是以键值对的方式来保存数据的,key就是JsessionID,根据key来获得value,要是没有jsessionID ,就创建一个加入MAP中。
1.7、长连接和短连接
没有数据传也要保持TCP连接就是长连接,反之则为短链接。比如HTTP就是无状态的短连接,浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。也可以这么说短连接就是SOCKET连接后,发送接受完的数据就马上断开连接;
长连接是至建立SOCKET连接之后不管使用与否都保持连接,直到某一方关闭连接,安全性较差。建立长连接不关闭socket就行。
1、适用情况
1)长连接主要用于操作频繁,点对点通讯,并且连接数不多的情况下。因为每个TCP链接都需要三次握手,这需要时间,要是每个操作都先连接再操作的话处理速度就会降低很多,所以每个操作完之后都不用断开,次处理的时候直接发送数据包就可以了。
2)短连接可以节省资源,在每个用户无需频繁操作情况下使用短连接比较好。因为长连接对于服务端来说会耗费一定的资源,像Web网站这么频繁的成千上万客户端的连接用短连接会更节省资源,要是使用长连接,每个用户都占一个连接的话,太占资源了。所以并发量大,但每个用户无需频繁访问操作情况下用短连接比较好。
2、长连接的实现
socket中有个API是socket.keepAlive(true);就是让TCP保持连接不断开,但是这个仅仅只是在两个小时内没有通信,底层会发一个心跳,看看对方是不是还活着。两小时发一次,也就是说,没有实际数据通信的时候,把网线拔了,对方要两个小时才能知道。其实会有很多情况导致socket不可用:a)某一段关闭了socket,主动关闭的一方会发送 FIN,通知对方要关闭 TCP 连接。在这种情况下,另一端如果去读 socket,将会读到 EoF。于是我们知道对方关闭了 socket;b)应用程序崩溃,socket会由内核关闭,情况和上面一样;c)系统崩溃,这时候系统是来不及发送FIN的,对方无法知道你这边什么情况,读数据之类的就会返回read time out;d)电线被挖断、网线被拔,就跟上面一直情况差不多,如果没有对socket进行读写,两边都不会知道发生了事故。
就以上可能出现的情景中,有一个共同点就是,只要读、写socket,就能知道异常,所以我们要实现长连接,就需要的是不断地给对方写数据,然后读对方的数据就好啦,这个心跳的时间需要根据实际时间来决定,只需要在数据前面加个type,识别是心跳还是真实数据就好。
长连接的心跳机制,项目中用不上心跳机制,因为每次都是在一定时间内传输大量的数据,这段时间内只要保持不断就可以,就总的来说,在我需要发送的时候,发送一次是200ms,那我在很多很多次的200ms内,一个三次握手建立连接的时间,是可以忽略不记的
1.8、HTTP的特性
HTTP 最凸出的优点是「简单、灵活和易于扩展、应⽤⼴泛和跨平台」。
1、简单
HTTP 基本的报⽂格式就是 header + body ,头部信息也是 key-value 简单⽂本的形式,易于理解,降低了学习和使⽤的⻔槛。
2、灵活和易于扩展
HTTP协议⾥的各类请求⽅法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发⼈员⾃定义和扩充。
比如说:HTTPS 也就是在 HTTP 与 TCP 层之间增加了 SSL/TLS 安全传输层,HTTP/3 甚⾄把 TCP 层换成了基于 UDP 的QUIC。
1.9、在浏览器输入URL后执行的全过程
1、域名解析。根据用户输入的网址去寻找它对应的IP地址
先从浏览器缓存里找IP,因为浏览器会缓存DNS(域名系统)记录一段时间;若没找到,从Hosts查找是否有该域名和IP;再没找到,从路由器缓存查找;再从DNS缓存查找;若再没有找到,浏览器域名服务器向根域名服务器查找对应IP,还没找到就把请求转发到下一级,直到找到IP
2、建立TCP连接
首先客户端发起请求:
使用应用层发起HTTP请求(可根据本身输入URL访问时,用什么协议就发起对应协议去进行请求);然后是传输层的TCP协议为传输报文提供可靠的字节流服务,使用了TCP三次握手;网络层将TCP分割好的各种数据包传送给接收方(要保证确实能传到接收方还需要接收方的MAC地址);最后链路层将数据发送到数据链路层传输
服务器接收请求处理:
链路层->网络层->传输层->应用层
3、根据后台业务返回数据,并把数据填充到HTML页面上,然后返回给浏览器
4、浏览器进行处理。服务器通过后台语言程序处理,找到数据返回给浏览器,断开TCP连接,然后绘制页面
2、HTTP的演变
2.1、HTTP1.1
1、长连接–HTTP1.0是短连接
早期 HTTP/1.0 性能上的⼀个很⼤的问题,那就是每发起⼀个请求,都要新建⼀次 TCP 连接(三次握⼿),⽽且是串⾏请求,做了⽆谓的 TCP 连接建⽴和断开,增加了通信开销。
为了解决上述 TCP 连接问题,HTTP/1.1 提出了⻓连接的通信⽅式,也叫持久连接。这种⽅式的好处在于减少了TCP 连接的重复建⽴和断开所造成的额外开销,减轻了服务器端的负载。
持久连接的特点是,只要任意⼀端没有明确提出断开连接,则保持 TCP 连接状态。
2、管道网络传输
长连接使管道Pipeling网络传输成为可能。即可在同⼀个 TCP 连接⾥⾯,客户端可以发起多个请求,只要第⼀个请求发出去了,不必等其回来,就可以发第⼆个请求出去,可以减少整体的响应时间。
举例来说,客户端需要请求两个资源。以前的做法是,在同⼀个TCP连接⾥⾯,先发送 A 请求,然后等待服务器做出回应,收到后再发出 B 请求。管道机制则是允许浏览器同时发出 A 请求和 B 请求。
但是服务器还是按照顺序,先回应 A 请求,完成后再回应 B 请求。要是前⾯的回应特别慢,后⾯就会有许多请求排队等着。这称为「队头堵塞」。
3、对头阻塞
「请求 - 应答」的模式加剧了 HTTP 的性能问题。因为当顺序发送的请求序列中的⼀个请求因为某种原因被阻塞时,在后⾯排队的所有请求也⼀同被阻塞了,会招致客户端⼀直请求不到数据,这也就是「队头阻塞」
总结HTTP/1.0与HTTP/1.1 区别
1)HTTP/1.1 相⽐ HTTP/1.0 性能上的改进:
-
使⽤ TCP ⻓连接的⽅式改善了 HTTP/1.0 短连接造成的性能开销。(长连接)
-
⽀持管道(pipeline)⽹络传输,只要第⼀个请求发出去了,不必等其回来,就可以发第⼆个请求出去,可以减少整体的响应时间。(管道网络传输)
2) HTTP/1.1 还是有性能瓶颈:
-
请求 / 响应头部(Header)未经压缩就发送,⾸部信息越多延迟越⼤。只能压缩 Body 的部分;(头部未压缩)
-
发送冗⻓的⾸部。每次互相发送相同的⾸部造成的浪费较多;(首部冗余)
-
服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端⼀直请求不到数据,也就是队头阻塞;(对头阻塞)
-
没有请求优先级控制;(无请求优先级)
-
请求只能从客户端开始,服务器只能被动响应。(被动响应)
2.2、HTTP2.0
1、HTTP2.0相当于HTTP1.0的改进
1)头部压缩
-
HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是⼀样的或是相似的,那么,协议会帮你消除重复的部分。
-
这就是所谓的 HPACK 算法:在客户端和服务器同时维护⼀张头信息表,所有字段都会存⼊这个表,⽣成⼀个索引号,以后就不发送同样字段了,只发送索引号,这样就提⾼速度了。
- HPACK算法:
2)二进制格式
- HTTP/2 不再像 HTTP/1.1 ⾥的纯文本形式的报⽂,⽽是全⾯采⽤了⼆进制格式,头信息和数据体都是⼆进制,并且统称为帧(frame):头信息帧和数据帧。
3)数据流
-
HTTP/2 的数据包不是按顺序发送的,同⼀个连接⾥⾯连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。
-
每个请求或回应的所有数据包,称为⼀个数据流( Stream )。每个数据流都标记着⼀个独⼀⽆⼆的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数
-
客户端还可以指定数据流的优先级。优先级⾼的请求,服务器就先响应该请求
4)多路复用
2、HTTP2.0中存在的问题
1)HTTP/2 对头阻塞
所谓的对头阻塞是因为HTTP是C/S模型,多个HTTP请求在一个TCP连接中实现,那么就存在一个问题,当发生TCP丢包时,整个TCP都需要等待重传,那么就会导致该TCP中的其他所有请求被阻塞。因为TCP是字节流协议,TCP层协议必须保证收到的字节数据完整且有序,如果序列号较低的TCP段在网络传输过程中发生了丢包,即使序列号较高的TCP段已经被接收了,应用层也无法从内核中读取到这部分数据,从HTTP的视角上看,就是请求被阻塞了。
2)TCP与TLS的握手时延迟
发起 HTTP 请求时,需要经过 TCP 三次握⼿和 TLS 四次握⼿(TLS 1.2)的过程,因此共需要 3 个 RTT 的时延才能发出请求数据。另外, TCP 由于具有「拥塞控制」的特性,所以刚建⽴连接的 TCP 会有个「慢启动」的过程,它会对 TCP 连接产⽣"减速"效果。
3)网络迁移需要重新连接
⼀个 TCP 连接是由四元组(源 IP 地址,源端⼝,⽬标 IP 地址,⽬标端⼝)确定的,这意味着如果 IP 地址或者端⼝变动了,就会导致需要 TCP 与 TLS 重新握⼿,这不利于移动设备切换⽹络的场景,⽐如 4G ⽹络环境切换成WIFI。这些问题都是 TCP 协议固有的问题,⽆论应⽤层的 HTTP/2 在怎么设计都⽆法逃脱。要解决这个问题,就必须把传输层协议替换成 UDP,这个⼤胆的决定,HTTP/3 做了。(将TCP换为UDP,实现无连接传输)
2.3、HTTP3.0
UDP 是⼀个面向报文的、简单、不可靠的传输协议,⽽且是 UDP 包之间是⽆序的,也没有依赖关系。
UDP 是不需要连接的,也就不需要握⼿和挥⼿的过程,所以天然的就⽐ TCP 快。
HTTP3.0不仅将TCP传输协议替换成UDP协议,而且还基于UDP协议在应用层上实现了QUIC协议,QUIC协议具有与TCP类似的连接管理、拥塞窗口、流量控制的网络特性,相当于把不可靠的UDP协议变得“可靠”了。
1、QUIC协议
QUIC(quick UDP internet connection)特点:无对头阻塞、更快建立连接、连接迁移
1)无对头阻塞
多路复用:QUIC 协议也有类似 HTTP/2 Stream 与多路复⽤的概念,也是可以在同⼀条连接上并发传输多个 Stream,Stream可以认为就是⼀条 HTTP 请求。
**不care丢包:**由于 QUIC 使⽤的传输协议是 UDP,UDP 不关⼼数据包的顺序,如果数据包丢失,UDP 也不关⼼。
保证可靠传输:不过 QUIC 协议会保证数据包的可靠性,每个数据包都有⼀个序号唯⼀标识。当某个流中的⼀个数据包丢失了,即使该流的其他数据包到达了,数据也⽆法被 HTTP/3 读取,直到 QUIC 重传丢失的报⽂,数据才会交给 HTTP/3。⽽其他流的数据报⽂只要被完整接收,HTTP/3 就可以读取到数据。这与 HTTP/2 不同,HTTP/2 只要某个流中的数据包丢失了,其他流也会因此受影响**(对数据包做标识,如果发生丢包,则只需重传丢包的数据包,不影响其他stream数据包的接收)**
**stream之间相互独立:**QUIC 连接上的多个 Stream 之间并没有依赖,都是独⽴的,某个流发⽣丢包了,只会影响该流,其他流不受影响。
2)更快建立连接
TCP与TLS分层:对于 HTTP/1 和 HTTP/2 协议,TCP 和 TLS 是分层的,分别属于内核实现的传输层、openssl 库实现的表示层,因此它们难以合并在⼀起,需要分批次来握⼿,先 TCP 握⼿,再 TLS 握⼿。
**QUIC握手只是确认ID:**HTTP/3 在传输数据前虽然需要 QUIC 协议握⼿,这个握⼿过程只需要 1 RTT,握⼿的⽬的是为确认双⽅的「连接ID」,连接迁移就是基于连接 ID 实现的。
但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层,⽽是QUIC 内部包含了 TLS,它在⾃⼰的帧会携带 TLS ⾥的“记录”,再加上 QUIC 使⽤的是 TLS1.3,因此仅需 1 个 RTT 就可以「同时」完成建⽴连接与密钥协商,甚⾄在第⼆次连接的时候,应⽤数据包可以和 QUIC 握⼿信息(连接信息 + TLS 信息)⼀起发送,达到 0-RTT 的效果。**
即HTTP/3 当会话恢复时,有效负载数据与第⼀个数据包⼀起发送,可以做到 0-RTT。
3)连接迁移
在前⾯我们提到,基于 TCP 传输协议的 HTTP 协议,由于是通过四元组(源 IP、源端⼝、⽬的 IP、⽬的端⼝)确定⼀条 TCP 连接,那么当移动设备的⽹络从 4G 切换到 WIFI 时,意味着 IP 地址变化了,那么就必须要断开连接,然后重新建⽴连接,⽽建⽴连接的过程包含 TCP 三次握⼿和 TLS 四次握⼿的时延,以及 TCP 慢启动的减速过程,给⽤户的感觉就是⽹络突然卡顿了⼀下,因此连接的迁移成本是很⾼的。⽽ QUIC 协议没有⽤四元组的⽅式来“绑定”连接,⽽是通过连接 ID来标记通信的两个端点,客户端和服务器可以各自选择⼀组 ID来标记⾃⼰,因此即使移动设备的⽹络变化后,导致 IP 地址变化了,只要仍保有上下⽂信息(⽐如连接 ID、TLS 密钥等),就可以“⽆缝”地复⽤原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。
2、HTTP3.0协议
HTTP/3 同 HTTP/2 ⼀样采⽤⼆进制帧的结构,不同的地⽅在于 HTTP/2 的⼆进制帧⾥需要定义 Stream,⽽ HTTP/3 ⾃身不需要再定义 Stream,直接使⽤ QUIC ⾥的 Stream,于是 HTTP/3 的帧的结构也变简单了**(HTTP2.0需要定义stream,HTTP3.0直接使用QUIC中stream)。**
从上图可以看到,HTTP/3 帧头只有两个字段:类型和⻓度。
根据帧类型的不同,⼤体上分为数据帧和控制帧两⼤类,HEADERS 帧(HTTP 头部)和 DATA 帧(HTTP 包体)属于数据帧。
HTTP/3 在头部压缩算法这⼀⽅便也做了升级,升级成了 QPACK。与 HTTP/2 中的 HPACK 编码⽅式相似,HTTP/3 中的 QPACK 也采⽤了静态表、动态表及 Huffman 编码。
-
对于静态表的变化,HTTP/2 中的 HPACK 的静态表只有 61 项,⽽ HTTP/3 中的 QPACK 的静态表扩⼤到 91 项。
-
HTTP/2 和HTTP/3 的 Huffman 编码并没有多⼤不同,但是动态表编解码⽅式不同。
-
所谓的动态表,在⾸次请求-响应后,双⽅会将未包含在静态表中的 Header 项更新各自的动态表,接着后续传输时仅⽤ 1 个数字表示,然后对⽅可以根据这 1 个数字从动态表查到对应的数据,就不必每次都传输长长的数据,⼤⼤提升了编码效率。
可以看到,动态表是具有时序性的,如果⾸次出现的请求发⽣了丢包,后续的收到请求,对⽅就⽆法解码出HPACK 头部,因为对⽅还没建⽴好动态表,因此后续的请求解码会阻塞到⾸次请求中丢失的数据包重传过来。
HTTP/3 的 QPACK 解决了这⼀问题,那它是如何解决的呢?
QUIC 会有两个特殊的单向流,所谓的单项流只有⼀端可以发送消息,双向则指两端都可以发送消息,传输 HTTP消息时⽤的是双向流,这两个单向流的⽤法:
-
⼀个叫 QPACK Encoder Stream, ⽤于将⼀个字典(key-value)传递给对⽅,⽐如⾯对不属于静态表的HTTP 请求头部,客户端可以通过这个 Stream 发送字典;
-
⼀个叫 QPACK Decoder Stream,⽤于响应对⽅,告诉它刚发的字典已经更新到⾃⼰的本地动态表了,后续就可以使⽤这个字典来编码了。
这两个特殊的单向流是⽤来同步双⽅的动态表,编码⽅收到解码⽅更新确认的通知后,才使⽤动态表编码 HTTP 头部。
**总结**HTTP/2.0与HTTP/3.0区别
HTTP/2 虽然具有多个流并发传输的能⼒,但是传输层是 TCP 协议,于是存在以下缺陷:
-
队头阻塞,HTTP/2 多个请求跑在⼀个 TCP 连接中,如果序列号较低的 TCP 段在⽹络传输中丢失了,即使序列号较⾼的 TCP 段已经被接收了,应⽤层也⽆法从内核中读取到这部分数据,从 HTTP 视⻆看,就是多个请求被阻塞了;
-
TCP 和 TLS 握⼿时延,TCL 三次握⼿和 TLS 四次握⼿,共有 3-RTT 的时延;
-
连接迁移需要重新连接,移动设备从 4G ⽹络环境切换到 WIFI 时,由于 TCP 是基于四元组来确认⼀条 TCP连接的,那么⽹络环境变化后,就会导致 IP 地址或端⼝变化,于是 TCP 只能断开连接,然后再᯿新建⽴连接,切换⽹络环境的成本⾼;
HTTP/3 就将传输层从 TCP 替换成了 UDP,并在 UDP 协议上开发了 QUIC 协议,来保证数据的可靠传输。
QUIC 协议的特点:
-
⽆队头阻塞,QUIC 连接上的多个 Stream 之间并没有依赖,都是独⽴的,也不会有底层协议限制,某个流发⽣丢包了,只会影响该流,其他流不受影响;
-
建⽴连接速度快,因为 QUIC 内部包含 TLS1.3,因此仅需 1 个 RTT 就可以「同时」完成建⽴连接与 TLS 密钥协商,甚⾄在第⼆次连接的时候,应⽤数据包可以和 QUIC 握⼿信息(连接信息 + TLS 信息)⼀起发送,达到 0-RTT 的效果。
-
连接迁移,QUIC 协议没有⽤四元组的⽅式来“绑定”连接,⽽是通过「连接 ID 」来标记通信的两个端点,客户端和服务器可以各⾃选择⼀组 ID 来标记⾃⼰,因此即使移动设备的⽹络变化后,导致 IP 地址变化了,只要仍保有上下⽂信息(⽐如连接 ID、TLS 密钥等),就可以“⽆缝”地复⽤原连接,消除᯿连的成本;
另外 HTTP/3 的 QPACK 通过两个特殊的单向流来同步双⽅的动态表,解决了 HTTP/2 的 HPACK 队头阻塞问题。
3、HTTPS
3.1、HTTPS实现
1、混合加密
混合加密的⽅式实现信息的机密性,解决了窃听的⻛险。
1)HTTPS 采⽤的是对称加密和⾮对称加密结合的「混合加密」⽅式:
- 在通信建⽴前采⽤非对称加密的⽅式交换「会话秘钥」,后续就不再使⽤⾮对称加密。(非对称加密–密钥)
- 在通信过程中全部使⽤对称加密的「会话秘钥」的⽅式加密明⽂数据。(对称加密–明文)
2)采⽤「混合加密」的⽅式的原因:
-
对称加密只使⽤⼀个密钥,运算速度快,密钥必须保密,⽆法做到安全的密钥交换。
-
⾮对称加密使⽤两个密钥:公钥和私钥,公钥可以任意分发⽽私钥保密,解决了密钥交换问题但速度慢。
2、摘要算法
摘要算法的⽅式来实现完整性,它能够为数据⽣成独⼀⽆⼆的「指纹」,指纹(摘要)⽤于校验数据的完整性,解决了篡改的⻛险。
客户端在发送明⽂之前会通过摘要算法算出明⽂的「指纹」,发送的时候把「指纹 + 明⽂」⼀同加密成密⽂后,发送给服务器,服务器解密后,⽤相同的摘要算法算出发送过来的明⽂,通过⽐较客户端携带的「指纹」和当前算出的「指纹」做⽐较,若「指纹」相同,说明数据是完整的。
3、数字证书
数字证书一般包含:公钥、持有者信息、证书认证机构CA的信息、CA对这份文件的数字签名及使用的算法、证书有效期…
1)什么是数字签名?
当服务器向客户端发送信息时,会将报文生成报文摘要,同时对报文摘要进行hash计算,得到hash值,然后对hash值进行加密,然后将加密的hash值放置在报文后面,这个加密后的hash值就称为签名。
服务器将报文、签名和数字证书一同发送给客户端。客户端收到这些信息后,会首先验证签名,利用签名算法对签名进行解密,得到报文摘要的hash值,然后将得到的报文生成报文摘要并利用签名hash算法生成新的hash值,通过对比这两个hash值是否一致,就能判断信息是否完整,是否是由真正的服务器发送的。可知签名有两个作用确认消息发送方可靠,确认消息完整准确。
2)数字证书的作用
用来认证公钥持有者的身份,防止第三方冒充,简单的来说就是告诉客户端,该服务端是否合法,只有证书合法,才能保证服务端身份是可信的。
为了让服务端的公钥被⼤家信任,服务端的证书都是由 CA (Certificate Authority,证书认证机构)签名的,CA就是⽹络世界⾥的公安局、公证中⼼,具有极⾼的可信度,所以由它来给各个公钥签名,信任的⼀⽅签发的证书,那必然证书也是被信任的。签名的作用可以避免中间人在获取证书时对证书内容的篡改。
3)证书是如何产生的?
证书的颁发过程:
- ⾸先 CA 会把持有者的公钥、⽤途、颁发者、有效时间等信息打成⼀个包,然后对这些信息进⾏ Hash 计算,得到⼀个 Hash 值;
- 然后 CA 会使⽤⾃⼰的私钥将该 Hash 值加密,⽣成 Certificate Signature,也就是 CA 对证书做了签名;
- 最后将 Certificate Signature 添加在⽂件证书上,形成数字证书;
4)客户端是如何验证CA证书是可信任的?
- ⾸先客户端会使⽤同样的 Hash 算法获取该证书的 Hash 值 H1;
- 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使⽤ CA 的公钥解密 Certificate Signature 内容,得到⼀个 Hash 值 H2 ;
- 最后⽐较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信
问题一:如何保证公钥不被篡改和信任度?
- 这⾥就需要借助第三⽅权威机构 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。
3.2、SSL
1、SSL/TLS协议基本流程
-
客户端向服务器索要并验证服务器的公钥。
-
双⽅协商⽣产「会话秘钥」。
-
双⽅采⽤「会话秘钥」进⾏加密通信。
2、SSL握手过程
SSL/TLS 协议建⽴的详细流程:
1)ClientHello
⾸先,由客户端向服务器发起加密通信请求,也就是 ClientHello 请求。在这⼀步,客户端主要向服务器发送以下信息:
-
客户端⽀持的 SSL/TLS 协议版本,如 TLS 1.2 版本。
-
客户端⽣产的随机数( Client Random ),后⾯⽤于⽣产「会话秘钥」。
-
客户端⽀持的密码套件列表,如 RSA 加密算法。
2)SeverHello
服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello 。服务器回应的内容有如下内容:
-
确认 SSL/ TLS 协议版本,如果浏览器不⽀持,则关闭加密通信。
-
服务器⽣产的随机数( Server Random ),后⾯⽤于⽣产「会话秘钥」。
-
确认的密码套件列表,如 RSA 加密算法。
-
服务器的数字证书。
3)客户端回应
客户端收到服务器的回应之后,⾸先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。
如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使⽤它加密报⽂,向服务器发送如下信息:
-
⼀个随机数( pre-master key )。该随机数会被服务器公钥加密。
-
加密通信算法改变通知,表示随后的信息都将⽤「会话秘钥」加密通信。
-
客户端握⼿结束通知,表示客户端的握⼿阶段已经结束。这⼀项同时把之前所有内容的发⽣的数据做个摘要,⽤来供服务端校验。上⾯第⼀项的随机数是整个握⼿阶段的第三个随机数,这样服务器和客户端就同时有三个随机数,接着就⽤双⽅协商的加密算法,各⾃⽣成本次通信的「会话秘钥」。
4)服务器的最后回应
服务器收到客户端的第三个随机数( pre-master key )之后,通过协商的加密算法,计算出本次通信的「会话秘钥」。然后,向客户端发⽣最后的信息:
-
加密通信算法改变通知,表示随后的信息都将⽤「会话秘钥」加密通信。
-
服务器握⼿结束通知,表示服务器的握⼿阶段已经结束。这⼀项同时把之前所有内容的发⽣的数据做个摘要,⽤来供客户端校验。
⾄此,整个 SSL/TLS 的握⼿阶段全部结束。接下来,客户端与服务器进⼊加密通信,就完全是使⽤普通的 HTTP协议,只不过⽤「会话秘钥」加密内容。
3.3、对称加密和非对称加密
HTTPS 采⽤的是对称加密和⾮对称加密结合的「混合加密」⽅式:
- 在通信建⽴前采⽤非对称加密的⽅式交换「会话秘钥」,后续就不再使⽤⾮对称加密。(非对称加密–密钥)
- 在通信过程中全部使⽤对称加密的「会话秘钥」的⽅式加密明⽂数据。(对称加密–明文)
对称加密就是发送双发使用相同的密钥对消息进行加解密,常见的对称加密为DES、3DES,AES等。
非对称加密是发送双方各自拥有一对公钥私钥,其中公钥是公开的,私钥是保密的。当发送方向接收方发送消息时,发送方利用接收方的公钥对消息进行加密,接收方收到消息后,利用自己的私钥解密就能得到消息的明文。其中非对称加密方法有RSA、Elgamal、ECC等
1、对称加密
2、非对称加密
3.4、相关算法
1、RSA
传统的 TLS 握⼿基本都是使⽤ RSA 算法来实现密钥交换的,在将 TLS 证书部署服务端时,证书⽂件中包含⼀对公私钥,其中公钥会在 TLS 握⼿阶段传递给客户端,私钥则⼀直留在服务端,⼀定要确保私钥不能被窃取。
在 RSA 密钥协商算法中,客户端会⽣成随机密钥,并使⽤服务端的公钥加密后再传给服务端。根据⾮对称加密算法,公钥加密的消息仅能通过私钥解密,这样服务端解密后,双⽅就得到了相同的密钥,再⽤它加密应⽤消息。
2、ECDHE算法
3.5、中间人攻击:
针对SSL的中间人攻击主要分为:SSL劫持攻击和SSL剥离攻击。
1)SSL劫持攻击:
- 攻击者在传输过程中伪造服务器的证书,将服务器的公钥替换成自己的公钥;但是对于客户端来说,如果中间人伪造了证书,在校验证书过程中会提示证书错误。
2)SSL剥离攻击:
- 中间人和服务器之间仍然保持HTTPS服务器;之后将HTTPS范文替换为HTTP返回给浏览器。
http和https连接时有多少个rtt
断点续传如何实现的
标签:HTTP1.0,HTTP,请求,TCP,SSL,HTTP3.0,服务器,连接,客户端 来源: https://blog.csdn.net/loytuls/article/details/123426213