HTTP简介

340 阅读11分钟

HTTP(Hypertext Transfer Protocol,超文本传输协议, 是在万维网上进行通信时 所使用的协议方案。

一、HTTP协议的诞生

计算机科学家提出一个构想:创建一个以超文本系统为基础的项目,允许在不同计算机之间分享信息,其目的是方便研究人员分享及更新信息。这个构想最终成了WWW(World Wide Web)万维网的基础,彻底改变了人类社会的沟通交流方式。

二、HTTP基本信息

超文本传输协议(HTTP)是应用层的一个协议,是万维网生态系统的核心,在OSI 七层模型中在最上层,它并不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。

(1)特点

1. BS 架构

HTTP 协议采用 BS 架构,也就是浏览器到服务器的架构,客户端通过浏览器发送 HTTP 请求给服务器,服务器经过解析响应客户端的请求。

2.简单快速

客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

3.灵活

HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type(Content-Type是HTTP包中用来表示内容类型的标识)加以标记。

4. 无连接

无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

5. 无状态

HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

(2)http事务

一个 HTTP 事务由一条(从客户端发往服务器的)请求命令和一个(从服务器 发回客户端的)响应结果组成。这种通信是通过名为 HTTP 报文(HTTP message) 的格式化数据块进行的

截图.png

http报文

HTTP 报文是由一行一行的简单字符串组成的。HTTP 报文都是纯文本,不是二进 1 制代码,所以人们可以很方便地对其进行读写

截图2.png

三、HTTP的发展

1. 最早版本HTTP 0.9

HTTP 的 1991 原型版本称为 HTTP/0.9。这个协议有很多严重的设计缺陷,只应该用于与老客户端的交互。 HTTP/0.9 只支持 GET 方法,不支持多媒体内容的 MIME 类型、各种 HTTP 首部,或者版本号。HTTP/0.9 定义的初衷是为了获取 简单的 HTML 对象(不能回应别的格式),它很快就被 HTTP/1.0 取代了。

2. HTTP 1.0

HTTP/1.0 版本发布,增加了POST命令和HEAD命令,丰富了浏览器与服务器的互动手段。这个版本HTTP协议可以发送任何格式的内容,包括传输文字、图像、视频、文件。 HTTP/1.0 除了增加了请求方法以及对发送文件的支持之外,还增加了格式的改变。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。另外还增加了状态码、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等等。

缺点: 每一次建立TCP连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。如果多次请求,势必就会对服务器产生较大的资源性能损耗(tcp三次握手四次挥手)。

3. HTTP 1.1

HTTP/1.1 版本最大的变化就是将持久化连接加入了 HTTP 标准,即TCP连接默认不关闭,可以被多个请求复用。此外,HTTP/1.1版还新增了许多方法,例如:PUT、PATCH、HEAD、 OPTIONS、DELETE。得到进一步完善的HTTP/1.1 版本,一直沿用至今。

4. https

HTTP 协议的诞生主要是为了解决信息传递和共享的问题,并没有考虑安全问题,HTTP协议不具备任何数据加密、身份校验等机制,使用HTTP协议传递的数据以明文形式在网络中传输,任意节点的第三方都可以随意劫持流量、篡改数据或窃取信息,无法确保数据的保密性、完整性和真实性,已经不能适应现代互联网应用的安全需求。

SSL/TLS SSL(Secure SocketsLayer)/TLS(Transport Layer Security)安全传输层协议 ,是介于TCP和HTTP之间的一层安全协议。应用层数据不再直接传递给传输层而是传递给SSL层,SSL层对从应用层收到的数据进行加密,利用数据加密、身份验证和消息完整性验证机制,为网络上数据的传输提供安全性保证。

5. HTTP2.0

特点是:在不改动HTTP语义、方法、状态码、URI及首部字段的情况下,大幅度提高了web性能。

1. 二进制传输

(1.x是文本传输)二进制传输,实现方便且健壮

2. 多路复用 帧(frame)和流(stream)

所谓多路复用,即在一个TCP连接中存在多个流,即可以同时发送多个请求,对端可以通过帧中的表示知道该帧属于哪个请求。

3.Header压缩

在HTTP1.0中,我们使用文本的形式传输header,在header中携带cookie的话,每次都需要重复传输几百到几千的字节,这着实是一笔不小的开销。 在HTTP2.0中,我们使用了HPACK(HTTP2头部压缩算法)压缩格式对传输的header进行编码,减少了header的大小。并在两端维护了索引表,用于记录出现过的header,后面在传输过程中就可以传输已经记录过的header的键名,对端收到数据后就可以通过键名找到对应的值。

4.服务器Push

在HTTP2.0中,服务端可以在客户端某个请求后,主动推送其他资源。(相对减少一点延迟时间) 在浏览器兼容的情况下也可以使用prefetch。

5.更安全

使用了tls的拓展ALPN做为协议升级。TTP2.0对tls的安全性做了近一步加强

思考:http如何开启2.0?(ALPN)

6. http3.0(QUIC协议)

因为http2.0帧和流的概念,每一个TCP连接中承载了多个双向流通的流,每一个流都有一个独一无二的标识和优先级,而流就是由二进制帧组成的。二进制帧的头部信息会标识自己属于哪一个流,所以这些帧是可以交错传输,然后在接收端通过帧头的信息组装成完整的数据。这样就解决了阻塞的问题,同时也提高了网络速度的利用率。

但是HTTP2.0 也是基于TCP协议的,tcp协议在处理包时是有严格顺序的。一个包出错可以计算出,并重传该包,如果两个以上出错,就所有重传。当其中一个数据包遇到问题,TCP连接需要等待整个包完成重传之后才能继续进行,虽然HTTP2.0通过多个stream,使得逻辑上一个tcp连接上的并行内容,进行多路数据的传输,然而这中间没有关联的数据,一前一后,前面stream2的帧没有收到,后面stream1的帧也会因此堵塞。

于是google提出的 QUIC协议从TCP切换到UDP,特点如下:

1. udp连接

一条tcp连接是由四元组标识的,分别是源ip、源端口、目的端口,一旦一个元素发生变化时,就会断开重连,重新连接。tcp三次握手建立链接,导致一定时延。

UDP不再以四元组标识,而是以一个64位的随机数作为ID来标识,UDP是无连接的,所以当ip或者端口变化的时候,只要ID不变,就不需要重新建立连接

2. 自定义重传机制

QUIC有个序列号,是递增的,任何一个序列号的包只发送一次,下次就要加1。 QUIC既然是面向连接的,也就像TCP一样,是一个数据流,发送的数据在这个数据流里面有个偏移量offset,可以通过offset查看数据发送到了那里,这样只有这个offset的包没有来,就要重发。如果来了,按照offset拼接,还是能够拼成一个流。

3. 无阻塞的多路复用

有了自定义的连接和重传机制,就可以解决上面HTTP2.0的多路复用问题 同HTTP2.0一样,同一条 QUIC连接上可以创建多个stream,来发送多个HTTP请求,但是,QUIC是基于UDP的,一个连接上的多个stream之间没有依赖。这样,假如stream2丢了一个UDP包,后面跟着stream3的一个UDP包,虽然stream2的那个包需要重新传,但是stream3的包无需等待,就可以发给用户。

4.自定义流量控制

TCP的流量控制是通过滑动窗口协议。QUIC的流量控制也是通过window_update,来告诉对端它可以接受的字节数。但是QUIC的窗口是适应自己的多路复用机制的,不但在一个连接上控制窗口,还在一个连接中的每个steam控制窗口。 QUIC的ACK是基于offset的,每个offset的包来了,进了缓存,就可以应答,应答后就不会重发,中间的空档会等待到来或者重发,而窗口的起始位置为当前收到的最大offset,从这个offset到当前的stream所能容纳的最大缓存,是真正的窗口的大小

四、https是安全的吗?

SSL/TLS协议的基本思路是采用公钥加密法(Public-key cryptography),也可以叫非对称加密(asymmetric cryptography),客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

但涉及到两个问题:

  1. 如何确保公钥未被篡改?
  2. 公钥加解密对速度敏感:(耗费时间)

解决办法

  1. 将公钥放在数字证书中,只要证书是可信的,就认为公钥是可信的
  2. 每一次对话(session),客户端和服务器端都生成一个"对话密钥"(session key),用它来加密信息。由于"对话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话密钥"本身,这样就减少了加密运算的消耗时间。

因此,SSL/TLS协议基本过程为:

  1. 客户端向服务器端索要并验证公钥(证书颁发机构)
  2. 双方协商生成"对话密钥"
  3. 双方采用"对话密钥"进行加密通信

截图3.png

思考问题:

1. 为什么数据传输是用对称加密?

2. 为什么需要 CA 认证机构颁发证书?

HTTPS 协议主要解决的便是网络传输的安全性问题。 首先我们假设不存在认证机构,任何人都可以制作证书,这带来的安全风险便是经典的“中间人攻击”问题。

截图4.png

由于缺少对证书的验证,所以客户端虽然发起的是 HTTPS 请求,但客户端完全不知道自己的网络已被拦截,传输内容被中间人全部窃取。

3.浏览器是如何确保 CA 证书的合法性?

(1)证书包含什么信息?

证书包含信息如下:

  • 颁发机构信息
  • 公钥
  • 公司信息
  • 域名
  • 有效期
  • 指纹
  • ...... 要是权威机构生成的证书,我们就认为是合法的。

(2)浏览器如何验证证书的合法性?

  • 验证域名、有效期等信息是否正确。 证书上都有包含这些信息,比较容易完成验证。
  • 判断证书来源是否合法。 每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发证书完成来源验证。
  • 判断证书是否被篡改。 需要与 CA 服务器进行校验。(检查签名)
  • 判断证书是否已吊销。 通过 CRL(Certificate Revocation List 证书注销列表)和 OCSP(Online Certificate Status Protocol 在线证书状态协议)实现。

其中 OCSP 可用于第 3 步中以减少与 CA 服务器的交互,提高验证效率。 证书里都会有签发者(根证书签发者是根证书机构),签发者可以用自己的公钥,根据特定的算法,生成唯一的签名。签名是证书的一部分。也就是签发者拿到自己签发的证书,可以根据算法生成签名,从而校验证书是否是第三方伪造的。虽然中间人可以得到证书,但私钥是无法获取的。