HTTP详解
HTTP
请求
< request-line >(请求消息行)
< headers >(请求消息头)
< blank line >(空行)
< request-body >(请求消息数据)
content-type 是请求消息头中的一个请求参数, 标识请求消息数据的格式.
响应
HTTP 消息头允许客户端和服务器通过 request 和 response 传递附加信息。
< status-line >(状态行)
< headers >(消息报头)
< blank line >(空行)
< response-body >(响应正文) content-type 是响应消息报头中的一个参数,标识响应正文数据的格式
根据不同上下文, 可将消息头分为:
同时适用于请求和响应消息,但与最终消息主体中传输的数据无关的消息头。
包含更多有关要获取的资源或客户端本身信息的消息头。
包含有关响应的补充信息,如其位置或服务器本身(名称和版本等)的消息头。
包含有关实体主体的更多信息,比如主体长(Content-Length)度或其 MIME 类型。
根据代理对其的处理方式分为: 端到端消息头
http 分析详解
影响一个 HTTP 网络请求的因素主要有两个: 带宽和延迟
带宽:
延迟:
浏览器堵塞: 浏览器会因为一些原因堵塞请求.浏览器对于同一个域名,同时只有 4 个连接.
dns 查询:浏览器需要知道目标 ip 才能建立连接.
建立连接: http 是基于 tcp 协议, 浏览器最快也要在第三次握手时才能捎带 http 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动.
https 和 http 区别
安全性不同 https 可以有效的防止运营商劫持,解决了防劫持的一个大问题.
网站申请流程不同
https 协议需要到 CA 申请证书,一般免费证书很少,需要交费,Web 服务器启用 SSL 需要获得一个服务器证书并将该证书与要使用 SSL 的服务器绑定。
默认端口不同
http 和 https 使用的是完全不同的连接方式,同时使用的端口也不同,http 使用的是 80 端口,https 使用的是 443 端口。在网络模型中,HTTP 工作于应用层,而 HTTPS 工作在传输层。
对搜索排名的提升
这也是很多站长所关注的地方。百度和谷歌两大搜索引擎都已经明确表示,HTTPS 网站将会作为搜索排名的一个重要权重指标。也就是说 HTTPS 网站比起 HTTP 网站在搜索排名中更有优势。
HTTPS 网站相比起 HTTP 网站拥有着多种的优势,HTTP 明显已经不能适应当今这个互联网时代,可以预见到 HTTP 在不久的将来将会全面被 HTTPS 所取代。
http
HTTP 协议也就是超文本传输协议,是一种使用明文数据传输的网络协议
https
为了解决 HTTP 协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议 HTTPS,为了数据传输的安全,HTTPS 在 HTTP 的基础上加入了 SSL/TLS 协议,SSL/TLS 依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。HTTPS 协议可以理解为 HTTP 协议的升级,就是在 HTTP 的基础上增加了数据加密。在数据进行传输之前,对数据进行加密,然后再发送到服务器。这样,就算数据被第三者所截获,但是由于数据是加密的,所以你的个人信息仍然是安全的。这就是 HTTP 和 HTTPS 的最大区别。
SSL/TLS 运行机制
SSL/TLS 的基本思路是公钥加密法:客户端先向服务器索要并验证公钥,然后用公钥加密传输来协商生成“对话秘钥”(非对称加密),双方采用“对话秘钥”进行加密通信(对称加密)。
通信过程如下:
客户端发出请求:给出支持的协议版本、支持的加密方法(如 RSA 公钥加密)以及一个客户端生成的随机数(Client random);
服务端回应:确认双方通信的协议版本、加密方法,并给出服务器证书以及一个服务器生成的随机数(Server random);
客户端回应:客户端确认证书有效,取出证书中的公钥,然后生成一个新的随机数(Premaster secret),使用公钥加密这个随机数,发送给服务端;
服务端回应:服务端使用自己的私钥解密客户端发来的随机数(Premaster secret),客户端和服务端根据约定的加密方法,使用三个随机数,生成“对话秘钥”;
会话通信:客户端和服务端使用“对话秘钥”加密通信,这个过程完全使用普通的 HTTP 协议,只不过用“会话秘钥”加密内容。
TLS 的交换密钥的过程:
客户端发送一个请求给服务器
服务器生成一对非对称的公钥和私钥, 然后把公钥附加到一个 CA 数字证书上,返回给客户端。
客户端校验该证书是否合法(通过浏览器内置的厂商跟证书等手段校验),然后从根证书中提取出公钥
客户端生成一个随机数,然后使用公钥对这个随机数进行加密后发送给服务器;
服务器利用私钥 对收到的随机数密文进行揭秘得到 key;
后续客户端和服务器传输数据使用该 key 进行加密后再传输;
数字证书包含什么
通常包含了: 1.公钥 2.持有者信息 3.证书认证机构(CA)的信息 4.证书的有效期 5.CA 对这份文件的数字签名以及使用的算法; 6.还有一些其他额外信息,比如证书的序列号,证书的版本号等等。
数字证书是个啥玩意
证书是一个文件,里面包含有目标网站的各种信息
例如:网站的域名,证书的有效期,签发机构等
其中最重要的是这两个:
用于生成对称密钥的公钥 2.由上级证书签发的签名
证书文件的格式叫做 X.509,由 RFC5280 规范详细定义。存储上分为两种,一种叫做 DER,是二进制的,还有一种叫做 PEM,是基于 Base64 的。
关于 RSA 的公钥和私钥记住一点就行:我们可以使用算法生成一对钥匙,他们满足一个性质:公钥加密的私钥可以解开,私钥加密的公钥可以解开。
证书,顾名思义,是用来证明自己身份的。因为发送证书的时候是明文的(这一步也没法加密),所以证书内容是可以被中间设备篡改的。
怎么验证证书内容是不是被中间设备篡改:解决办法是采用「信任链」
首先,有一批证书颁发机构(Certificate Authority,简称为 CA),由他们生成秘钥对,其中私钥保存好,公钥以证书的格式安装在我们的操作系统中,这就是 根证书。
我们的手机、电脑、电视机的操作系统中都预装了 CA 的根证书,他们是所有信任构建的基石。当然,我们也可以自己下载任意的根证书进行安装。
比如说,我们收到了服务器发过来的 C 证书,我们验证了 C 是由 B 签发的,然后又验证了 B 是由 A 签发的,而 A 在我们的系统中存在,那也就证明了 C 这个证书的有效性
得益于 RSA 的非对称性质,验证 A 是否签发了 B 证书很简单:
计算 B 的 hash 值(算法随便,比如 SHA1) 使用 A 的 私钥 对该 hash 进行加密,加密以后的内容叫做「签名(Signature)」 将该「签名」附在 B 证书中
http1.0 vs http1.1
连接无法复用 http1.0 传输数据时,每次都需要重新建立连接,增加延迟. http1.1 加入了 Connection: keep-alive 可复用一部分连接,但域名分片等情况下任然需要建立多个 connection, 耗费资源,给服务器带来压力.
head-of-line blocking(HOLB) 指一系列包(package) 因为第一个包被阻塞;当页面中需要请求很多资源的时候,holb 会导致在达到最大请求数量时,剩余资源需要等待其他请求完成后才能发起请求. http1.0 下一个请求必须在前一个请求返回后才能发出. 如果某个请求长时间没有返回,那么接下来的请求就全部阻塞 http1.1 尝试使用 pipeling 来解决,即浏览器可以一次性发出多个请求(同个域名,同一条 TCP 链接).但请求还是按顺序返回的,如果前一个请求很耗时, 即使后面的请求服务器已经处理完,仍要等待前面的请求处理完才可以按序返回.
协议开销大
安全因素
在 http1.1 和 http1.0 的区别
缓存处理:HTTP/1.0 使用 Pragma:no-cache + Last-Modified/If-Modified-Since 来作为缓存判断的标准;HTTP/1.1 引入了更多的缓存控制策略:Cache-Control、Etag/If-None-Match 等。
错误状态管理:HTTP/1.1 新增了 24 个错误状态响应码,如 409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
范围请求:HTTP/1.1 在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接,支持断点续传。
Host 头:HTTP1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的 URL 并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个 IP 地址。HTTP1.1 的请求消息和响应消息都应支持 Host 头域,且请求消息中如果没有 Host 头域会报告一个错误(400 Bad Request)。有了 Host 字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础。
持久连接:HTTP/1.1 最大的变化就是引入了持久连接(persistent connection),在 HTTP/1.1 中默认开启 Connection: keep-alive,即 TCP 连接默认不关闭,可以被多个请求复用。 因为进行 tcp 三次握手连接是很耗费时间的
客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送 Connection: close,明确要求服务器关闭 TCP 连接。客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送 Connection: close,明确要求服务器关闭 TCP 连接。
管道机制:HTTP/1.1 中引入了管道机制(pipelining),即在同一个 TCP 连接中,客户端可以同时发送多个请求。
http2.0
二进制传输 二进制格式传输数据,而非 http1.x 的文本格式,二进制协议解析起来更高效 将请求和响应数据分割为更小的帧,并且它们采用二进制编码
多路复用 解决了浏览器限制同个域名下的请求数量的问题,同时也更容易实现全速传输 在 http2.0 中域名下所有通信都在单个连接上完成,
采用二进制传输的原因: 单个连接可以承载任意数量的双向数据流, 数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧可以乱序发送,因为根据帧首部的流标识可以重新组装.
同个域名只需要占用一个 TCP 连接,使用一个连接并行发送多个请求和响应,消除了因多个 TCP 连接而带来的延时和内存消耗。
并行交错地发送多个请求,请求之间互不影响。
并行交错地发送多个响应,响应之间互不干扰。
在 HTTP/2 中,每个请求都可以带一个 31bit 的优先值,0 表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。
多路复用的技术可以只通过一个 TCP 连接就可以传输所有的请求数据。
Header 压缩
http/2 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送;
首部表在 HTTP/2 的连接存续期内始终存在,由客户端和服务器共同渐进地更新;
每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值
Server Push 服务端能通过 push 的方式将客户端需要的内容预先推送出去, 也叫"cache push".
http3.0
google 搞了一个基于 UDP 协议的 QUIC 协议,并且使用在了 HTTP/3 上, 在之前名为 HTTP-over-QUIC, QUIC 的意思是“快速 UDP Internet 连接”。协议的这种更改将极大地加快连接建立和数据传输的时间。但是,UDP 当然更快,更简单,但是它不具备 TCP 的可靠性和错误处理能力。
HTTP3 是 HTTP2 的复用和压缩功能,协议从 TCP 更改为 UDP。然后,Google 家伙在协议中添加了他们的层,以确保稳定性,数据包接收顺序以及安全性。
因此,HTTP3 在保持 QUIC 稳定性的同时使用 UDP 来保持高速,而又不会忘记 TLS 的安全性。
多路复用
加密认证的报文
向前纠错机制
QUIC 与 TCP 的主要区别:
传输层协议:
TCP: 传统的传输控制协议,位于操作系统内核空间。
QUIC: 基于 UDP,在用户空间实现,提供更大的灵活性和可扩展性。
连接建立:
TCP: 需要三次握手来建立连接,过程相对较慢。
QUIC: 通过减少握手次数,加速了连接的建立过程,降低了延迟。
多路复用:
TCP: 支持多路复用,但存在队头阻塞问题,即一个流的延迟可能影响其他流。
QUIC: 支持多路复用,且避免了队头阻塞问题,提高了传输效率。
加密:
TCP: 通常与 TLS/SSL 配合使用来提供加密功能。
QUIC: 内置加密功能,提供与 TLS/SSL 相当的安全性。
拥塞控制:
TCP: 拥塞控制算法在内核空间实现,修改和优化相对困难。
QUIC: 拥塞控制算法在用户空间实现,易于修改和优化。
看重点: http1.x 和 http1.0 相比 多了长连接, connection : keep-alive
http1.x 和 http2.0 多路复用: 只通过一个 tcp 可以发送多个请求,不用按照顺序--对应,避免了"队头堵塞"
HTTP/2 协议只在 HTTPS 环境下才有效,升级到 HTTP/2,必须先启用 HTTPS。
常见的几个问题
现代浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开
在 HTTP/1.0 中,一个服务器在发送完一个 HTTP 响应后,会断开 TCP 链接。在 1.1 中加入 connection: keep-alive 默认开启
所以第一个问题的答案是:默认情况下建立 TCP 连接不会断开,只有在请求报头中声明 Connection: close 才会在请求完成后关闭连接
:一个 TCP 连接可以对应几个 HTTP 请求
了解了第一个问题之后,其实这个问题已经有了答案,如果维持连接,一个 TCP 连接是可以发送多个 HTTP 请求的。
第三个问题:一个 TCP 连接中 HTTP 请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)
HTTP/1.1 存在一个问题,单个 TCP 连接在同一时刻只能处理一个请求,意思是说:两个请求的生命周期不能重叠,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠。 虽然 HTTP/1.1 规范中规定了 Pipelining 来试图解决这个问题,但是这个功能在浏览器中默认是关闭的。
但是,HTTP2 提供了 Multiplexing 多路传输特性,可以在一个 TCP 连接中同时完成多个 HTTP 请求。至于 Multiplexing 具体怎么实现的就是另一个问题了。我们可以看一下使用 HTTP2 的效果。
浏览器对同一 Host 建立 TCP 连接到数量有没有限制
有。Chrome 最多允许对同一个 Host 建立六个 TCP 连接。不同的浏览器有一些区别。
https 运用了那种加密
答案是两种都用到了
首先随机生成单次请求加密密钥(clientAesKey,长度为 16 位,可以用 26 个字母和数字组成)
RSA 负责加密一个字符(clientAesKey)
AES 负责用这个字符串(clientAesKey)、明文加密一个密文
解密时首先要用 RSA 获取这个字符串(clientAesKey)
然后用 AES 解密密文
HTTPS 在进行数据传输之前会与网站服务器和 web 浏览器进行一次握手,在握手时确定双方的加密密码信息
Web 浏览器将支持的加密信息发送给网站服务器
网站服务器会选择出一套加密算法和哈希算法,将验证身份的信息以证书(证书发布 CA 机构、证书有效期、公钥、证书所有者、签名等)的形式发送给 Web 浏览器
当 Web 浏览器收到证书之后首先需要验证证书的合法性,如果证书受到浏览器信任则在浏览器地址栏会有标志显示,否则就会显示不受信的标识。
当网站服务器接收到浏览器发送过来的数据后,会使用网站本身的私钥将信息解密确定密码,然后通过密码解密 Web 浏览器发送过来的握手信息,并验证哈希是否与 Web 浏览器一致。
最后浏览器解密并计算经过哈希算法加密的握手消息,如果与服务发送过来的哈希一致,则此握手过程结束后,服务器与浏览器会使用之前浏览器生成的随机密码和对称加密算法进行加密交换数据。
HTTPS 运用了非对称加密:加密使用的密钥和解密使用的密钥是不相同的,分别称为:公钥、私钥,公钥和算法都是公开的,私钥是保密的。非对称加密算法性能较低,但是安全性超强,由于其加密特性,非对称加密算法能加密的数据长度也是有限的。 例如:RSA、DSA、ECDSA、 DH、ECDHE 等。
HSTS
HSTS(HTTP Strict-Transport-Security)它是一个 Web 安全策略机制,网站采用 HSTS 后,用户访问时无需手动在地址栏中输入 HTTPS,浏览器会自动采用 HTTPS 访问网站地址,从而保证用户始终访问到网站的加密链接,保护数据传输安全。
服务器需要认证的通信过程
http1.0 和 http1.1 的区别
连接管理(Connection Management)
HTTP/1.0: 每个请求/响应都需要建立一个独立的 TCP 连接,完成请求后即关闭连接。这会导致较高的延迟和资源浪费,因为每次请求都需要重新建立连接。
HTTP/1.1: 引入了 持久连接(Persistent Connection),默认情况下,HTTP/1.1 连接在响应之后保持打开,直到客户端或服务器明确关闭连接。这减少了建立新连接的开销,提高了性能。
请求和响应头(Headers)
HTTP/1.0: 请求和响应头中的一些字段是可选的,且每个请求和响应都有独立的头部信息,可能会有冗余数据,导致不必要的带宽消耗。
HTTP/1.1: 所有的请求和响应都需要包含 Host 头字段,这使得 HTTP/1.1 可以在同一服务器上承载多个网站(虚拟主机)。此外,HTTP/1.1 支持了更多的优化头部(例如:Connection、Cache-Control)来提高缓存和连接管理的效率。
缓存机制(Caching)
HTTP/1.0: 使用的是较为简单的缓存机制,通常通过 Expires 头来控制缓存。
HTTP/1.1: 引入了更加复杂和灵活的缓存机制,例如 Cache-Control 头部,允许更精确地控制缓存策略,包括公共缓存、私有缓存、过期时间、协商缓存等。
带宽优化(Bandwidth Optimization)
HTTP/1.0: 每个请求/响应都需要独立的 TCP 连接,因此带宽的使用效率较低。
HTTP/1.1: 引入了 管道化(Pipelining) 机制,允许客户端在一个连接上发起多个请求,而不必等待每个请求的响应。尽管管道化能提高效率,但由于浏览器的支持不统一,实际应用中并未广泛采用。
错误处理(Error Handling)
HTTP/1.0: 错误处理相对简单,使用较少的状态码。
HTTP/1.1: 引入了更多的状态码来表示更详细的错误信息,增强了错误处理的灵活性。例如,404、403、407 等状态码更加精确地指明了请求失败的原因。
多媒体传输(Multipart)
HTTP/1.0: 对多部分消息的支持不如 HTTP/1.1 强大。
HTTP/1.1: 提供了对 多部分传输(Multipart) 的更好支持,允许在同一请求中传输不同类型的数据(例如:图像、文本和文件)。这对于上传文件和传输复合数据类型特别有用。
http1.1 和 http2 的区别
数据传输格式:
HTTP/1.1: 使用基于文本的协议,数据以明文形式传输,解析时需要逐字符读取,效率较低。
HTTP/2: 采用二进制协议,将数据分割为小的帧进行传输,解析更高效,减少了延迟。
多路复用:
HTTP/1.1: 每个请求需要建立独立的 TCP 连接,存在队头阻塞问题,即一个请求的延迟可能影响后续请求的处理。
HTTP/2: 允许在单个 TCP 连接上并行处理多个请求和响应,解决了队头阻塞问题,提高了并发性能。
头部压缩:
HTTP/1.1: 每次请求和响应都会重复发送相同的头部信息,增加了网络开销。
HTTP/2: 使用 HPACK 算法对头部信息进行压缩,减少了数据传输量,提高了传输效率。
服务器推送:
HTTP/1.1: 服务器只能响应客户端的请求,无法主动发送数据。
HTTP/2: 服务器可以在客户端请求之前主动推送资源,减少了请求次数,加快了页面加载速度。
连接管理:
HTTP/1.1: 支持持久连接(Keep-Alive),但仍可能因连接数过多导致性能下降。
HTTP/2: 通过多路复用和头部压缩,减少了对多个连接的依赖,提高了连接的利用率
总结: HTTP/2 相较于 HTTP/1.1 在性能和效率上有显著提升,主要体现在二进制传输、多路复用、头部压缩和服务器推送等方面。
http2 和 http3 的区别
传输层协议:
HTTP/2: 基于传统的传输控制协议(TCP)。
HTTP/3: 基于 QUIC 协议,QUIC 是一种在用户空间实现的传输层协议,运行在用户数据报协议(UDP)之上。
多路复用:
HTTP/2: 支持在单个 TCP 连接上并行处理多个请求和响应,但由于 TCP 的队头阻塞问题,可能导致性能瓶颈。
HTTP/3: 通过 QUIC 协议,避免了 TCP 的队头阻塞问题,实现了更高效的多路复用。
连接建立和关闭:
HTTP/2: 使用 TLS 握手来建立连接,连接建立和关闭相对较慢。
HTTP/3: QUIC 协议在建立连接时集成了加密功能,减少了握手次数,加快了连接建立速度。
头部压缩:
HTTP/2: 使用 HPACK 算法对头部信息进行压缩。
HTTP/3: 使用 QPACK 算法对头部信息进行压缩,QPACK 是为 QUIC 设计的头部压缩算法
https 握手过程
客户端发起请求:
客户端向服务器发送一个包含支持的 SSL/TLS 版本、加密算法套件(Cipher Suites)和一个随机数的 ClientHello 消息。
服务器响应:
服务器收到 ClientHello 后,选择一个双方都支持的 SSL/TLS 版本和加密算法套件,并生成一个随机数。
服务器将其数字证书(包含公钥)发送给客户端。
客户端验证证书: 客户端使用预先安装的受信任的证书颁发机构(CA)的公钥验证服务器证书的有效性,包括证书的签名、有效期和域名匹配等。
生成会话密钥:
客户端生成一个预主密钥(Pre-Master Secret),使用服务器的公钥对其进行加密,并发送给服务器。
服务器使用其私钥解密,得到预主密钥。
客户端和服务器基于预主密钥和之前交换的随机数,使用特定的算法生成会话密钥(Session Key)。
加密通信:
双方使用会话密钥对后续的通信数据进行加密,确保数据的机密性和完整性。
注意:
在整个握手过程中,客户端和服务器都使用非对称加密(公钥和私钥)来交换密钥和验证身份。 一旦会话密钥生成,后续的通信使用对称加密,以提高性能。
https 能不能抓包
可以,HTTPS 可以抓包,但因为通信内容是加密的,需要解密后才能查看。
其原理是通过一个中间人,伪造服务器证书,并取得客户端的信任,然后将客户端的请求转发给服务器,将服务器的响应转发给客户端,完成中间人攻击。
常用的抓包工具有 Wireshark、Fiddler、Charles 等。
最后更新于
这有帮助吗?