seo网站外包,钉子 wordpress,潍坊seo管理,做爰动态视频网站HTTP 基本概念 一、HTTP 是什么#xff1f;
HTTP(HyperText Transfer Protocol) #xff1a;超文本传输协议。
HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。
「HTTP 是用于从互联网服务器传输超文本到本… HTTP 基本概念 一、HTTP 是什么
HTTP(HyperText Transfer Protocol) 超文本传输协议。
HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。
「HTTP 是用于从互联网服务器传输超文本到本地浏览器的协议」这种说法正确吗
不正确。因为也可以是「服务器 -- 服务器」所以采用两点之间的描述会更准确。 二、HTTP 常见的状态码 2xx成功 「200 OK」是最常见的成功状态码表示一切正常。如果是非 HEAD 请求服务器返回的响应头都会有 body 数据。 「204 No Content」与 200 OK 基本相同但响应头没有 body 数据。 「206 Partial Content」是应用于 HTTP 分块下载或断点续传表示响应返回的 body 数据并不是资源的全部而是其中的一部分也是服务器处理成功的状态。
3xx重定向 「301 Moved Permanently」永久重定向请求的资源已经不存在了需改用新的 URL 再次访问。 「302 Found」临时重定向请求的资源还在但暂时需要用另一个 URL 来访问。
301 和 302 都会在响应头里使用字段 Location指明后续要跳转的 URL浏览器会自动重定向新的 URL。
「304 Not Modified」不具有跳转的含义表示资源未修改重定向已存在的缓冲文件也称缓存重定向也就是告诉客户端可以继续使用缓存资源用于缓存控制。
4xx客户端错误 「400 Bad Request」客户端请求的报文有错误但只是个笼统的错误。 「403 Forbidden」服务器禁止访问资源并不是客户端的请求出错。 「404 Not Found」请求的资源在服务器上不存在或未找到。
5xx服务器错误 「500 Internal Server Error」服务器笼统的通用错误码。 「501 Not Implemented」客户端请求的功能还不支持类似“即将开业敬请期待”。 「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码表示服务器自身工作正常访问后端服务器发生了错误。 「503 Service Unavailable」服务器当前很忙暂时无法响应。 三、HTTP 常见字段
1.Hostwww.example.com
客户端发送请求时用于指定服务器的域名,可以将请求发往「同一台」服务器上的不同网站。
2.Content-Length1000
服务器返回数据时表示本次回应的数据长度是 1000 个字节后面的字节属于下一个回应。
(HTTP 基于 TCP 传输协议进行通信而使用了 TCP 协议会存在“粘包”问题于是HTTP 协议通过设置回车符、换行符作为 HTTP header 的边界通过 Content-Length 字段作为 HTTP body 的边界来解决“粘包”问题。)
3.ConnectionKeep-Alive
客户端发送请求时用于保持连接当客户端发送另一个请求时会使用同一个连接一直持续到客户端或服务器端提出断开连接。
HTTP/1.1 版本的默认连接都是长连接但为了兼容老版本的 HTTP需要指定ConnectionKeep-Alive
注意
HTTP Keep-Alive 和 TCP Keepalive并不相同
HTTP Keep-Alive保持连接
TCP Keepalive检查连接是否有效
4.Content-Type: text/html; Charsetutf-8
服务器返回数据时表示数据格式(这里表示发送网页编码是UTF-8)
5.Accept: */*
客户端发送请求时声明自己可接受的数据格式(这里表示可接受任何格式)
6.Content-Encodinggzip
服务器返回数据时使用的数据压缩方法。
7.Accept-Encoding: gzip, deflate
客户端发送请求时声明自己可接受的压缩方法。 GET 与 POST GET 从服务器获取指定的资源。
POST 根据请求负荷报文body对指定的资源做出处理。 GET 和 POST 方法都是安全和幂等的吗 在 HTTP 协议里安全和幂等的概念
「安全」请求方法不会「破坏」服务器上的资源。「幂等」多次执行相同的操作结果都是「相同」的。
从 RFC 规范定义的语义来看
GET 方法安全且幂等的因为它是「只读」操作无论操作多少次服务器上的数据都是安全的且每次的结果都是相同的。所以可以对 GET 请求的数据做缓存这个缓存可以做到浏览器本身上彻底避免浏览器发请求也可以做到代理上如nginx而且在浏览器中 GET 请求可以保存为书签。POST 因为是「新增或提交数据」的操作会修改服务器上的资源所以是不安全的且多次提交数据就会创建多个资源所以不是幂等的。所以浏览器一般不会缓存 POST 请求也不能把 POST 请求保存为书签。
GET 方法是安全、幂等、可被缓存的。
POST 不安全不幂等大部分实现不可缓存。
但是实际过程中开发者不一定会按照 RFC 规范定义的语义来实现 GET 和 POST 方法。比如
用 GET 方法实现新增或删除数据的请求这样实现的 GET 方法就不是安全和幂等。用 POST 方法实现查询数据的请求这样实现的 POST 方法就是安全和幂等。 并不能说 GET 不如 POST 安全的。
因为 HTTP 传输的内容都是明文的虽然在浏览器地址拦看不到 POST 提交的 body 数据但是只要抓个包就都能看到了。
所以要避免传输过程中数据被窃取就要使用 HTTPS 协议这样所有 HTTP 的数据都会被加密传输。 GET 请求可以带 body 吗 理论上任何请求都可以带 body 。只是因为 RFC 规范定义的 GET 请求是获取资源所以根据这个语义不需要用到 body。
另外URL 中的查询参数也不是 GET 所独有的POST 请求的 URL 中也可以有参数的。 HTTP 缓存机制 一、强制缓存
只要浏览器判断缓存没有过期则直接使用浏览器的本地缓存而无需再请求服务器。
强制缓存是利用下面这两个 HTTP 响应头部Response Header字段实现的它们都用来表示资源在客户端缓存的有效期
Cache-Control 是一个相对时间Expires是一个绝对时间
如果 HTTP 响应头部同时有 Cache-Control 和 Expires 字段的话Cache-Control 的优先级高于 Expires 。
Cache-control 选项更多一些设置更加精细所以建议使用 Cache-Control 来实现强制缓存。具体的实现流程如下
当浏览器第一次请求访问服务器资源时服务器会在返回这个资源的同时在 Response 头部加上 Cache-ControlCache-Control 中设置了过期时间大小浏览器再次请求访问服务器中的该资源时会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小来计算出该资源是否过期如果没有则使用该缓存否则重新请求服务器服务器再次收到请求后会再次更新 Response 头部的 Cache-Control。 二、协商缓存
与服务端协商之后通过协商结果来判断是否使用本地缓存。 协商缓存可以基于两种头部来实现。
第一种请求头部中的 If-Modified-Since 字段与响应头部中的Last-Modified字段 (基于时间实现)
响应头部中的 Last-Modified标示这个响应资源的最后修改时间请求头部中的 If-Modified-Since当资源过期了发现响应头中具有 Last-Modified 声明则再次发起请求的时候带上 Last-Modified 的时间服务器收到请求后发现有 If-Modified-Since 则与被请求资源的最后修改时间进行对比Last-Modified。如果最后修改时间较早说明资源又被改过则返回最新资源HTTP 200 OK如果最后修改时间较小说明资源无新修改响应 HTTP 304 走缓存。
第二种请求头部中的 If-None-Match 字段与响应头部中的 ETag 字段 (基于一个唯一标识实现能更准确地判断文件内容是否被修改)
响应头部中ETag唯一标识响应资源请求头部中的 If-None-Match当资源过期时浏览器发现响应头里有 Etag则再次向服务器发起请求时会将请求头 If-None-Match 值设置为 Etag 的值。服务器收到请求后进行比对如果资源没有变化返回 304如果资源变化了返回 200。 如果在第一次请求资源的时候服务端返回的 HTTP 响应头部同时有 Etag 和 Last-Modified 字段那么客户端再下一次请求的时候如果带上了 ETag 和 Last-Modified 字段信息给服务端这时 Etag 的优先级更高也就是服务端先会判断 Etag 是否变化了如果 Etag 有变化就不用在判断 Last-Modified 了如果 Etag 没有变化然后再看 Last-Modified。 为什么 ETag 的优先级更高 这是因为 ETag 主要能解决 Last-Modified 几个比较难以解决的问题
在没有修改文件内容情况下文件的最后修改时间可能也会改变这会导致客户端认为这文件被改动了从而重新请求可能有些文件是在秒级以内修改的If-Modified-Since 能检查到的粒度是秒级的使用 Etag就能够保证这种需求下客户端在 1 秒内能刷新多次有些服务器不能精确获取文件的最后修改时间。
注意协商缓存这两个字段都需要配合强制缓存中 Cache-Control 字段来使用只有在未能命中强制缓存的时候才能发起带有协商缓存字段的请求。 HTTP缓存如果通过查询Cache-Control字段或Expires字段发现资源没有过期那么会先走强制缓存如果过期了就走协商缓存协商缓存有两种形式一种是基于时间实现的请求头部中的 If-Modified-Since 字段与响应头部中的Last-Modified字段资源过期时发送请求时If-Modified-Since 字段会带上Last-Modified字段服务器收到后对Last-Modified字段进行比对如果最后修改时间较早说明资源又被改过则返回最新资源HTTP 200 OK如果最后修改时间较小说明资源无新修改响应 HTTP 304 走缓存。第二种是请求头部中的 If-None-Match 字段与响应头部中的 ETag 字段发起请求时会将请求头 If-None-Match 值设置为 Etag 的值。服务器收到请求后进行比对如果资源没有变化返回 304如果资源变化了返回 200。两种方式可以并存此时Etag的优先级更高。 HTTP/1.1 特性 HTTP/1.1 的优点有哪些 「简单、灵活和易于扩展、应用广泛和跨平台」
1. 简单
HTTP 基本的报文格式就是 header body头部信息也是 key-value 简单文本的形式易于理解。
2. 灵活和易于扩展
HTTP 协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死都允许开发人员自定义和扩充。
同时 HTTP 由于是工作在应用层 OSI 第七层则它下层可以随意变化比如
HTTPS 就是在 HTTP 与 TCP 层之间增加了 SSL/TLS 安全传输层HTTP/1.1 和 HTTP/2.0 传输协议使用的是 TCP 协议而到了 HTTP/3.0 传输协议改用了 UDP 协议。
3. 应用广泛和跨平台 HTTP/1.1 的缺点有哪些 HTTP 协议里有优缺点一体的双刃剑分别是「无状态、明文传输」同时还有一大缺点「不安全」。
1. 无状态双刃剑
无状态的好处因为服务器不会去记忆 HTTP 的状态所以不需要额外的资源来记录状态信息这能减轻服务器的负担。
无状态的坏处没有记忆能力那么在完成有关联性的操作时会非常麻烦。
例如登录-添加购物车-下单-结算-支付这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的每次都要问一遍身份信息。
通常使用 Cookie 技术来解决无状态问题。
Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。
相当于在客户端第一次请求后服务器会下发一个装有客户信息的「小贴纸」后续客户端请求服务器的时候带上「小贴纸」服务器就能认得了
2. 明文传输双刃剑
明文传输虽然易于阅读但也增加了信息泄露的风险。 HTTP/1.1 的性能如何 HTTP 协议是基于 TCP/IP并且使用了「请求 - 应答」的通信模式所以性能的关键就在这两点里。
1. 长连接
早期 HTTP/1.0 性能上的一个很大的问题那就是每发起一个请求都要新建一次 TCP 连接三次握手而且是串行请求做了无谓的 TCP 连接建立和断开增加了通信开销。
HTTP/1.1 提出了长连接的通信方式也叫持久连接。这种方式减少了 TCP 连接的重复建立和断开所造成的额外开销减轻了服务器端的负载。
持久连接的特点是只要任意一端没有明确提出断开连接则保持 TCP 连接状态。
如果某个 HTTP 长连接超过一定时间没有任何数据交互服务端就会主动断开这个连接。
2. 管道网络传输
HTTP/1.1 采用了长连接的方式这使得管道pipeline网络传输成为了可能。
即可在同一个 TCP 连接里面客户端可以发起多个请求只要第一个请求发出去了不必等其回来就可以发第二个请求出去可以减少整体的响应时间。
举例来说客户端需要请求两个资源。以前的做法是在同一个 TCP 连接里面先发送 A 请求然后等待服务器做出回应收到后再发出 B 请求。那么管道机制则是允许浏览器同时发出 A 请求和 B 请求如下图 但是服务器必须按照接收请求的顺序发送对这些管道化请求的响应。
如果服务端在处理 A 请求时耗时比较长那么后续的请求的处理都会被阻塞住这称为「队头堵塞」。
所以HTTP/1.1 管道解决了请求的队头阻塞但是没有解决响应的队头阻塞。 注意
实际上 HTTP/1.1 管道化技术不是默认开启而且浏览器基本都没有支持知道有这个功能但是没有被使用就行了。
3. 队头阻塞
「请求 - 应答」的模式会造成 HTTP 的性能问题。
当顺序发送的请求序列中的一个请求因为某种原因被阻塞时在后面排队的所有请求也一同被阻塞了会招致客户端一直请求不到数据这就是「队头阻塞」好比上班的路上塞车。 总之 HTTP/1.1 的性能一般后续的 HTTP/2 和 HTTP/3 就是在优化 HTTP 的性能。 HTTP/1.1采用了长连接来提高性能只要客户端和服务器端没有一方主动断开连接就会在一定时间内保持连接从而避免了多次连接和断开产生的开销长连接使得管道网络传输成为可能之前的情况是必须等第一个请求得到响应时才能发送第二个请求如果使用管道网络传输那么就可以在发送的第一个请求没有得到响应时就发送第二个请求但是服务器必须按照接收请求的顺序发送对这些管道化请求的响应如果服务端在处理某一个请求时耗时比较长那么后续的请求的处理都会被阻塞住这称为「队头堵塞」就和堵车一样会导致客户端一直请求不到数据。
所以HTTP/1.1 管道解决了请求的队头阻塞但是没有解决响应的队头阻塞不过管道网络传输默认关闭且大多数浏览器没有支持知道就行。 HTTP 和 HTTPS 一、HTTP
1.明文传输不安全
2.默认端口号80
3.TCP三次握手即可 二、HTTPS
1.加密传输更安全(在HTTP层与TCP层之间加上了SSL/TTL安全协议) SSL和TTL是在不同时期的两种叫法含义相同。 2.默认端口号443
3.TCP三次握手SSL/TTL四次握手(RSA算法和ECDHE算法)
4.采用对称加密和非对称加密结合的「混合加密」方式
在通信建立前采用非对称加密的方式交换「会话秘钥」。在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。
采用「混合加密」的方式的原因
对称加密只使用一个密钥运算速度快密钥必须保密无法做到安全的密钥交换。非对称加密使用两个密钥公钥和私钥公钥可以任意分发而私钥保密更安全但速度慢(公钥加密私钥解密)。
5.摘要算法 数字签名
为了保证传输的内容不被篡改会先对内容计算出一个「指纹」再把「指纹」和内容一起传输给对方。
对方收到后先是对内容也计算出一个「指纹」然后跟发送方发送的「指纹」做一个比较如果「指纹」相同说明内容没有被篡改。
在计算机里会用摘要算法哈希函数来计算出内容的哈希值也就是内容的「指纹」这个哈希值是唯一的且无法通过哈希值推导出内容。
通过哈希算法可以确保内容不会被篡改但是并不能保证「内容 哈希值」不会被中间人替换因为这里缺少对客户端收到的消息是否来源于服务端的证明。
所以需要通过非对称加密「公钥加密私钥解密」的方式来确认消息的身份。
6.需要向 CA证书权威机构申请数字证书防止公钥和私钥被同时伪造
数字证书中含有公钥和CA的数字签名(CA相当于权威认证如果CA签名可信那么公钥就可信) HTTPS 是如何建立连接的其间交互了什么 SSL/TLS 协议基本流程
客户端向服务器索要并验证服务器的公钥。双方协商生产「会话秘钥」。双方采用「会话秘钥」进行加密通信。
前两步也就是 SSL/TLS 的建立过程也就是 TLS 握手阶段。
TLS 的「握手阶段」涉及四次通信使用不同的密钥交换算法TLS 握手流程也会不一样的常用的密钥交换算法有两种RSA 算法和 ECDHE 算法 。
TLS 协议建立的详细流程
1. ClientHello
首先由客户端向服务器发起加密通信请求也就是 ClientHello 请求。
在这一步客户端主要向服务器发送以下信息
1客户端支持的 TLS 协议版本如 TLS 1.2 版本。
2客户端生产的随机数Client Random后面用于生成「会话秘钥」条件之一。
3客户端支持的密码套件列表如 RSA 加密算法。
2. SeverHello
服务器收到客户端请求后向客户端发出响应也就是 SeverHello。服务器回应的内容有如下内容
1确认 TLS 协议版本如果浏览器不支持则关闭加密通信。
2服务器生产的随机数Server Random也是后面用于生产「会话秘钥」条件之一。
3确认的密码套件列表如 RSA 加密算法。
4服务器的数字证书。
3.客户端回应
客户端收到服务器的回应之后首先通过浏览器或者操作系统中的 CA 公钥确认服务器的数字证书的真实性。
如果证书没有问题客户端会从数字证书中取出服务器的公钥然后使用它加密报文向服务器发送如下信息
1一个随机数pre-master key。该随机数会被服务器公钥加密。
2加密通信算法改变通知表示随后的信息都将用「会话秘钥」加密通信。
3客户端握手结束通知表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要用来供服务端校验。
上面第一项的随机数是整个握手阶段的第三个随机数会发给服务端所以这个随机数客户端和服务端都是一样的。
服务器和客户端有了这三个随机数Client Random、Server Random、pre-master key接着就用双方协商的加密算法各自生成本次通信的「会话秘钥」。
4. 服务器的最后回应
服务器收到客户端的第三个随机数pre-master key之后通过协商的加密算法计算出本次通信的「会话秘钥」。
然后向客户端发送最后的信息
1加密通信算法改变通知表示随后的信息都将用「会话秘钥」加密通信。
2服务器握手结束通知表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要用来供客户端校验。
至此整个 TLS 的握手阶段全部结束。接下来客户端与服务器进入加密通信就完全是使用普通的 HTTP 协议只不过用「会话秘钥」加密内容。
不过基于 RSA 算法的 HTTPS 存在「前向安全」的问题如果服务端的私钥泄漏了过去被第三方截获的所有 TLS 通讯密文都会被破解。
为了解决这个问题后面就出现了 ECDHE 密钥协商算法现在大多数网站使用的正是 ECDHE 密钥协商算法。 客户端校验数字证书的流程是怎样的 CA 签发证书的过程
首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包然后对这些信息进行 Hash 计算得到一个 Hash 值然后 CA 会使用自己的私钥将该 Hash 值加密生成 Certificate Signature也就是 CA 对证书做了签名最后将 Certificate Signature 添加在文件证书上形成数字证书
客户端校验服务端的数字证书的过程
首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1通常浏览器和操作系统中集成了 CA 的公钥信息浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容得到一个 Hash 值 H2 最后比较 H1 和 H2如果值相同则为可信赖的证书否则则认为证书不可信。
但事实上证书的验证过程中还存在一个证书信任链的问题因为我们向 CA 申请的证书一般不是根证书签发的而是由中间证书签发的比如百度的证书从下图你可以看到证书的层级有三级 对于这种三级层级关系的证书的验证过程如下
客户端收到 baidu.com 的证书后发现这个证书的签发者不是根证书就无法根据本地已有的根证书中的公钥去验证 baidu.com 证书是否可信。于是客户端根据 baidu.com 证书中的签发者找到该证书的颁发机构是 “GlobalSign Organization Validation CA - SHA256 - G2”然后向 CA 请求该中间证书。请求到证书后发现 “GlobalSign Organization Validation CA - SHA256 - G2” 证书是由 “GlobalSign Root CA” 签发的由于 “GlobalSign Root CA” 没有再上级签发机构说明它是根证书也就是自签证书。应用软件会检查此证书有否已预载于根证书清单上如果有则可以利用根证书中的公钥去验证 “GlobalSign Organization Validation CA - SHA256 - G2” 证书如果发现验证通过就认为该中间证书是可信的。“GlobalSign Organization Validation CA - SHA256 - G2” 证书被信任后可以使用 “GlobalSign Organization Validation CA - SHA256 - G2” 证书中的公钥去验证 baidu.com 证书的可信性如果验证通过就可以信任 baidu.com 证书。
在这四个步骤中最开始客户端只信任根证书 GlobalSign Root CA 证书的然后 “GlobalSign Root CA” 证书信任 “GlobalSign Organization Validation CA - SHA256 - G2” 证书而 “GlobalSign Organization Validation CA - SHA256 - G2” 证书又信任 baidu.com 证书于是客户端也信任 baidu.com 证书。
总括来说由于用户信任 GlobalSign所以由 GlobalSign 所担保的 baidu.com 可以被信任另外由于用户信任操作系统或浏览器的软件商所以由软件商预载了根证书的 GlobalSign 都可被信任。
过程就是从最下级找到最上级再用最上级的公钥验证下一级是否可信再用下一级的公钥验证下下一级是否可信以此类推。 为什么需要证书链这么麻烦的流程Root CA 为什么不直接颁发证书而是要搞那么多中间层级呢 这是为了确保根证书的绝对安全性将根证书隔离地越严格越好不然根证书如果失守了那么整个信任链都会有问题。 HTTPS 的应用数据是如何保证完整性的 TLS 在实现上分为握手协议和记录协议两层
TLS 握手协议就是我们前面说的 TLS 四次握手的过程负责协商加密算法和生成对称密钥后续用此密钥来保护应用程序数据即 HTTP 数据TLS 记录协议负责保护应用程序数据并验证其完整性和来源所以对 HTTP 数据加密是使用记录协议
TLS 记录协议主要负责消息HTTP 数据的压缩加密及数据的认证过程如下图 具体过程如下 首先消息被分割成多个较短的片段,然后分别对每个片段进行压缩。 接下来经过压缩的片段会被加上消息认证码MAC 值这个是通过哈希算法生成的这是为了保证完整性并进行数据的认证。通过附加消息认证码的 MAC 值可以识别出篡改。与此同时为了防止重放攻击在计算消息认证码时还加上了片段的编码。 再接下来经过压缩的片段再加上消息认证码会一起通过对称密码进行加密。 最后上述经过加密的数据再加上由数据类型、版本号、压缩后的长度组成的报头就是最终的报文数据。
记录协议完成后最终的报文数据将传递到传输控制协议 (TCP) 层进行传输。 消息被分割成多个较短的片段,然后分别对每个片段进行压缩每个被压缩的片段都会被加上由哈希算法生成的MAC值也就是消息认证码之后进行对称加密生成密文最后为密文加上由数据类型、版本号、压缩后的长度组成的报头形成最终的报文数据然后就可以传递到传输控制协议 (TCP) 层进行传输。 三、HTTPS的可靠性
HTTPS 协议本身到目前为止还是没有任何漏洞的即使你成功进行中间人攻击本质上是利用了客户端的漏洞用户点击继续访问或者被恶意导入伪造的根证书并不是 HTTPS 不够安全。
客户端漏洞如下
客户端通过浏览器向服务端发起 HTTPS 请求时被「假基站」转发到了一个「中间人服务器」于是客户端是和「中间人服务器」完成了 TLS 握手然后这个「中间人服务器」再与真正的服务端完成 TLS 握手。 问题产生的原因
1.执意信任网站 2.电脑中毒被恶意导入了中间人的根证书 解决方法
1.防范病毒不要点击任何证书非法的网站。
2. HTTPS 双向认证一般我们的 HTTPS 是单向认证客户端只会验证了服务端的身份但是服务端并不会验证客户端的身份。 为什么抓包工具能截取 HTTPS 数据 工作原理与中间人一致的。
对于 HTTPS 连接来说中间人要满足以下两点才能实现真正的明文代理:
中间人作为客户端与真实服务端建立连接这一步不会有问题因为服务端不会校验客户端的身份中间人作为服务端与真实客户端建立连接这里会有客户端信任服务端的问题也就是服务端必须有对应域名的私钥
中间人要拿到私钥只能通过如下方式
去网站服务端拿到私钥去CA处拿域名签发私钥自己签发证书切要被浏览器信任
抓包工具只能使用第三种方式取得中间人的身份。 HTTP/1.1 相比 HTTP/1.0 提高了什么性能 HTTP/1.1 相比 HTTP/1.0 性能上的改进
使用长连接改善了短连接造成的性能开销。支持管道网络传输只要第一个请求发出去了不必等其回来就可以发第二个请求出去减少整体的响应时间。
但 HTTP/1.1 还是有性能瓶颈
请求 / 响应头部Header未经压缩就发送首部信息越多延迟越大。只能压缩 Body 的部分发送冗长的首部。每次互相发送相同的首部造成的浪费较多服务器是按请求的顺序响应的如果服务器响应慢会招致客户端一直请求不到数据也就是队头阻塞没有请求优先级控制请求只能从客户端开始服务器只能被动响应。 HTTP/2 做了什么优化 HTTP/2 协议是基于 HTTPS 的。 那 HTTP/2 相比 HTTP/1.1 性能上的改进
头部压缩二进制格式并发传输服务器主动推送资源
1. 头部压缩
HTTP/2 会压缩头Header如果你同时发出多个请求他们的头是一样的或是相似的那么协议会帮你消除重复的部分。
这就是所谓的 HPACK 算法在客户端和服务器同时维护一张头信息表所有字段都会存入这个表生成一个索引号以后就不发送同样字段了只发送索引号来提高速度。
2. 二进制格式
HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文而是全面采用了二进制格式头信息和数据体都是二进制并且统称为帧frame头信息帧Headers Frame和数据帧Data Frame。
这样虽然对人不友好但是对计算机非常友好因为计算机只懂二进制那么收到报文后无需再将明文的报文转成二进制而是直接解析二进制报文这增加了数据传输的效率。
比如状态码 200 在 HTTP/1.1 是用 200 三个字符来表示二进制00110010 00110000 00110000共用了 3 个字节在 HTTP/2 对于状态码 200 的二进制编码是 10001000只用了 1 字节就能表示相比于 HTTP/1.1 节省了 2 个字节。
3. 并发传输
我们都知道 HTTP/1.1 的实现是基于请求-响应模型的。同一个连接中HTTP 完成一个事务请求与响应才能处理下一个事务也就是说在发出请求等待响应的过程中是没办法做其他事情的如果响应迟迟不来那么后续的请求是无法发送的也造成了队头阻塞的问题。
而 HTTP/2 引出了 Stream 概念多个 Stream 复用在一条 TCP 连接。 从上图可以看到1 个 TCP 连接包含多个 StreamStream 里可以包含 1 个或多个 MessageMessage 对应 HTTP/1 中的请求或响应由 HTTP 头部和包体构成。Message 里包含一条或者多个 FrameFrame 是 HTTP/2 最小单位以二进制压缩格式存放 HTTP/1 中的内容头部和包体。
针对不同的 HTTP 请求用独一无二的 Stream ID 来区分接收端可以通过 Stream ID 有序组装成 HTTP 消息不同 Stream 的帧是可以乱序发送的因此可以并发不同的 Stream 也就是 HTTP/2 可以并行交错地发送请求和响应。
比如下图服务端并行交错地发送了两个响应 Stream 1 和 Stream 3这两个 Stream 都是跑在一个 TCP 连接上客户端收到后会根据相同的 Stream ID 有序组装成 HTTP 消息。 4、服务器推送
HTTP/2 的服务端可以主动向客户端发送消息。
客户端和服务器双方都可以建立 Stream Stream ID 也是有区别的客户端建立的 Stream 必须是奇数号而服务器建立的 Stream 必须是偶数号。
比如下图Stream 1 是客户端向服务端请求的资源属于客户端建立的 Stream所以该 Stream 的 ID 是奇数数字 1Stream 2 和 4 都是服务端主动向客户端推送的资源属于服务端建立的 Stream所以这两个 Stream 的 ID 是偶数数字 2 和 4。 再比如客户端通过 HTTP/1.1 请求从服务器那获取到了 HTML 文件而 HTML 可能还需要依赖 CSS 来渲染页面这时客户端还要再发起获取 CSS 文件的请求需要两次消息往返而在 HTTP/2 中客户端在访问 HTML 时服务器可以直接主动推送 CSS 文件减少了消息传递的次数。 HTTP/2 有什么缺陷 HTTP/2 通过 Stream 的并发能力解决了 HTTP/1 在HTTP 这一层面队头阻塞的问题但是 HTTP/2 还是存在 TCP 这一层面的队头阻塞。
HTTP/2 是基于 TCP 协议来传输数据的TCP 是字节流协议TCP 层必须保证收到的字节数据是完整且连续的这样内核才会将缓冲区里的数据返回给 HTTP 应用那么当「前 1 个字节数据」没有到达时后收到的字节数据只能存放在内核缓冲区里只有等到这 1 个字节数据到达时HTTP/2 应用层才能从内核中拿到数据这就是 HTTP/2 队头阻塞问题。 举个例子如下图 图中发送方发送了很多个 packet每个 packet 都有自己的序号你可以认为是 TCP 的序列号其中 packet 3 在网络中丢失了即使 packet 4-6 被接收方收到后由于内核中的 TCP 数据不是连续的于是接收方的应用层就无法从内核中读取到只有等到 packet 3 重传后接收方的应用层才可以从内核中读取到数据这就是 HTTP/2 的队头阻塞问题是在 TCP 层面发生的。
所以一旦发生了丢包现象就会触发 TCP 的重传机制这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来。 HTTP/3 做了哪些优化 前面提到 HTTP/1.1 和 HTTP/2 都有队头阻塞的问题
HTTP/1.1 中的管道虽然解决了请求的队头阻塞但是没有解决响应的队头阻塞因为服务端需要按顺序响应收到的请求如果服务端处理某个请求消耗的时间比较长那么只能等响应完这个请求后 才能处理下一个请求这属于 HTTP 层队头阻塞。HTTP/2 虽然通过多个请求复用一个 TCP 连接解决了 HTTP 的队头阻塞 但是一旦发生丢包就会阻塞住所有的 HTTP 请求这属于 TCP 层队头阻塞。
HTTP/2 队头阻塞的问题是因为 TCP所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP。 UDP 发送是不管顺序也不管丢包的所以不会出现像 HTTP/2 队头阻塞的问题。
虽然 UDP 是不可靠传输的但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。
QUIC 有以下 3 个特点。
无队头阻塞更快的连接建立连接迁移
1、无队头阻塞
QUIC 协议也有类似 HTTP/2 Stream 与多路复用的概念也是可以在同一条连接上并发传输多个 StreamStream 可以认为就是一条 HTTP 请求。
QUIC 连接上的多个 Stream 之间是独立的当某个流发生丢包时只会阻塞这个流其他流不会受到影响不存在队头阻塞问题。
而HTTP/2 只要某个流中的数据包丢失了其他流也会受影响。 2、更快的连接建立
对于 HTTP/1 和 HTTP/2 协议TCP 和 TLS 是分层的分别属于内核实现的传输层、openssl 库实现的表示层因此它们需要分批次来握手先 TCP 握手再 TLS 握手。
HTTP/3 在传输数据前虽然需要 QUIC 协议握手但是这个握手过程只需要 1 RTT握手的目的是为确认双方的「连接 ID」连接迁移就是基于连接 ID 实现的。
但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层而是 QUIC 内部包含了 TLS它在自己的帧会携带 TLS 里的“记录”再加上 QUIC 使用的是 TLS/1.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 密钥等就可以“无缝”地复用原连接消除重连的成本没有丝毫卡顿感达到了连接迁移的功能。
所以 QUIC 是一个在 UDP 之上的伪 TCP TLS HTTP/2 的多路复用的协议。
QUIC 是新协议对于很多网络设备根本不知道什么是 QUIC只会当做 UDP这样会出现新的问题因为有的网络设备是会丢掉 UDP 包的而 QUIC 是基于 UDP 实现的那么如果网络设备无法识别这个是 QUIC 包那么就会当作 UDP包然后被丢弃。
HTTP/3 现在普及的进度非常的缓慢不知道未来 UDP 是否能够逆袭 TCP。 HTTP/1.1相较于HTTP/1.0新增了长连接解决了请求时的队头阻塞但没有解决响应时的队头阻塞。
而HTTP/2进行了头部压缩以及二进制格式传输并基于HTTPS将多个 Stream 复用在一条 TCP 连接中解决了HTTP层面请求和响应的队头阻塞通过Stream ID来区分不同的流并且不同 Stream 的帧是可以乱序发送的再由接收端通过 Stream ID 有序组装成 HTTP 消息但没有解决TCP层面的队头阻塞如果一个Stream中的包丢了就会触发 TCP 的重传机制这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来。HTTP/2 的服务端可以主动向客户端发送消息。
HTTP/3通过在TCP层使用UDP而不是TCP来解决HTTP/2在TCP层存在的队头阻塞并且基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。QUIC 连接上的多个 Stream 之间是独立的当某个流发生丢包时只会阻塞这个流其他流不会受到影响不存在队头阻塞问题。对于 HTTP/1 和 HTTP/2 协议TCP 和 TLS 是分层的需要先 TCP 握手再 TLS 握手而HTTP/3 的 QUIC 协议并不是与 TLS 分层而是 QUIC 内部包含了 TLS所以只需要QUIC 协议握手。连接迁移上QUIC 协议没有用四元组的方式来“绑定”连接而是通过连接 ID 来标记通信的两个端点客户端和服务器可以各自选择一组 ID 来标记自己因此即使移动设备的网络变化后导致 IP 地址变化了只要仍保有上下文信息比如连接 ID、TLS 密钥等就可以“无缝”地复用原连接消除重连的成本没有丝毫卡顿感达到了连接迁移的功能。但HTTP/3 现在普及的进度非常的缓慢不知道未来 UDP 是否能够逆袭 TCP。