HTTP协议学习笔记--http1.0、http1.1、http2.0、https、http3

参考文章《HTTP协议:菜鸟入门系列》 - 老_张 - 博客园
参考文章 HTTP2 详解 - 简书
参考文章 HTTP2.0协议全文翻译
参考文章 探索HTTP/2: 流的状态(原) - John Jiang - BlogJava


HTTP/1.x

http1.x是基于文本的通信协议,分为start line(请求行),http header(请求头)和http body(请求体)三个部分。
根据发起方的不同

  • start line又分为request line(请求行) 、status line(状态行)
  • http header又分为request header(请求头) 、response header(响应头)
  • http body又分为request body(请求体)、response body(响应体)

*进行http通讯之前必须先建立tcp连接,完成三次握手

请求行

http请求的第一行是请求行,记录请求类型(get、post等)、请求URI、协议版本(http1.0、http1.1等),在http请求的第一行,以\n结尾,第二行开始才是请求头

请求头

请求头从第二行开始,用来标识

  • 请求体长度(必传)
  • 能够接受的数据类型
  • 语言
  • 浏览器信息
  • 压缩方式
  • 编码方式
  • host
  • cookie

请求头是变长的,以连续两个\n为结束标识(即空一行)
不同类型的请求请求头不一样,相同类型下有些请求头字段可以不传

请求体

请求体没有格式要求,可以根据应用实际情况灵活处理,唯一一点要求就是必须要和请求头之间空一行。

状态行

响应的第一行是状态行,返回该次响应的协议版本(http1.0、http1.1等)、请求的状态(200、404、500等)、状态描述

响应头

响应头与请求头类似,都包含了一些关于请求本身的信息,可能包括

  • 重定向时的新地址
  • 服务器信息
  • 编码格式
  • 响应体长度
  • 响应体语言
  • 过期时间

响应头是变长的,以连续两个\n为结束标识(即空一行)

响应体

响应体也没有格式要求,可以根据实际情况灵活处理,唯一一点要求仍然是必须要和响应头之间空一行。

http请求头内容是http协议中非常重要的一块内容,知识点也很多。这几篇文章详细介绍了请求头的内容
http协议(六)报文首部 - 老_张 - 博客园
http协议(七)通用首部字段 - 老_张 - 博客园
http协议(八)请求首部字段 - 老_张 - 博客园
http协议(九)响应首部字段 - 老_张 - 博客园
http协议(十)实体首部字段 - 老_张 - 博客园


HTTP/1.0与HTTP/1.1的区别

  1. 支持的请求方法不同,http1.0不支持OPTIONS、TRACE、CONNECT三种请求方式,http1.1不支持LINK和UNLINK两种请求方式。其中,CONNECT(隧道协议)方式用来进行SSL\TLS加密通讯,所以http1.0自然也不支持https。
  2. http1.0没有host请求头,意味着http1.0不支持在一台http服务器上搭建多个web站点。比如,你不能同时在一台服务器上托管www.baidu.com和www.taobao.com两个域名。而http1.1协议里host一定要传
  3. http1.0默认都是非持久连接,一次http请求完成后就会断开;http1.1默认都是持久连接,一次连接后可以持续发送请求,直到一方断开连接
  4. http1.1支持长链接,自然地会发展出管线化技术(pipeline),http1.0只有部分服务器通过非标准手段实现了长链接,所以不一定支持管线化
  5. HTTP/1.1加入了一个新的状态码100(Continue)。
  6. HTTP/1.1加入了一些cache的新特性,当缓存对象的Age超过Expire时变为stale对象,cache不需要直接抛弃stale对象,而是与源服务器进行重新激活(revalidation)。
  7. HTTP/1.1引入了Chunked transfer-coding来将消息分割成若干个任意大小的数据块,避免缓冲整个消息带来的过载。

http1.1主要是在1.0的基础上优化性能,以及通过扩展http header的方式增加了部分功能。1.1相当于1.0的特性增强版


HTTP/2.0

http2.0是基于SPDY协议设计出来的、基于二进制帧流的通信协议。(SPDY协议与http2差别不大,就不单独介绍了)
每一个二进制帧都分为length(24bit)、type(8bit)、flags(8bit)、预留位(1bit)、streamID(31bit)、payload(任意长度)六个部分。其中length、type、flags、预留位、streamID组成了帧头(frame header),固定长9字节(72比特)。

  • length:表示payload部分的长度,默认大小为0~16,384(214)
  • type:表示此帧的类型,一共10种
  • flags:重要参数位,没一bit位代表一个参数
  • 预留位:预留
  • streamID:表示此帧的顺序,用作流控制
  • payload:正文

http2.0的帧是比http1.1中的请求更小的传输单位,且http1.1的请求可以被封装到http2.0的帧里。每一个请求都可能对应多个帧的交互。
每一帧的正文长度默认都不超过16384(214)比特,除非接收方通知了SETTINGS_MAX_FRAME_SIZE(一般在214到224之间)

帧的种类(type):

类型对应类型码说明
DATA0x0数据帧,传输应用需要的数据
HEADERS0x1消息头帧,传输头信息,包括请求头、响应头等
PRIORITY0x2优先级帧,设定流优先级
RST_STREAM0x3流终止帧,中断流或者表示发生了一个错误,不中断连接
SETTINGS0x4设置帧,设置该连接的参数,作用于整个连接
PUSH_PROMISE0x5推送帧,服务端推送时使用,客户端可以返回一个RST_STREAM 帧来拒绝推
PING0x6PING帧,判断空闲连接是否可用,测量最小往返时间 (RTT)
GOAWAY0x7GOAWAY帧,发起关闭连接,或者警示严重错误。关闭连接前会处理完已建立的流
WINDOW_UPDATE0x8窗口更新帧,流量控制。可以针对某个流,也可以针对整个连接
CONTINUATION0x9延续帧,示意继续传输数据
每一种类型的帧都有特定的格式,详细的格式在另一篇文章中有说明(还没写)

其中HEADERS帧和DATA帧用来兼容http1.x,分别对应1.x中的消息头和消息体。

流和多路复用

流(stream)是一个逻辑概念,表示双向交换的独立的帧序列,由帧头(frame header)中的streamID标识。http2.0定义了高度独立的流来实现高效率的多路复用,任意流的阻塞不会影响其他流的处理。并且每一个流都可以有一个独立的优先级,用来帮助对端分配资源,挑选重要的信息优先传输。
流是有状态的,并且在整个交互周期内会出现状态的流转,流的状态流转是通过不同类型的帧来控制的。详细情况在另一篇文章中有说明(还没写)

流量控制

请求发起方可以主动要求服务器只传输指定大小的数据,服务端在传输完成后会暂停流,直到客户端要求继续传输后面的数据。在某些场景下,这种机制可以极大的缓解网络压力,并且降低网页感知渲染时间。

服务器主动推送

有了高度独立的流和多路复用机制,http2.0可以很容易的实现服务器主动推送的功能。即在tcp连接上服务端主动发起一个PUSH流,当然客户端也可以拒绝。

压缩消息头

http2.0针对消息头做了很大程度的压缩:

  • 通讯双方各自维护一份索引表(头列表),将常用的请求头维护到索引表中,通讯时直接发送索引号,而不是字符串,部分常用请求头信息的索引是硬编码的,不需要动态维护
  • 需要发送字符串的情况下,使用哈夫曼编码压缩字符串

http2.0中的头字段与1.1的格式一样。当通讯双方需要交换头列表时,先将若干个头字段集合成头列表,再通过HPACK压缩算法压缩成头部块,然后将过大的头部块拆成若干头部块段,通过HEADERS帧、PUSH_PROMISE帧、或者CONTINUATION帧的payload进行传输。而Cookie字段比较特殊,需要特殊处理,详见Hypertext Transfer Protocol Version 2 (HTTP/2)

加密

http2.0协议不强制要求信息加密。对于没有安全层的http2.0实现,称其为 HTTP/2 Cleartext (h2c)
目前,各大浏览器都不打算支持h2c,所以常见的http2.0基本都是基于https的
很多http2.0的工具和类库同时支持 h2 和 h2c,支持的工具清单

不足之处
  1. 单连接开销比较大。HPACK数据压缩算法会更新两端的查找表。这样可以让连接有状态,而破坏状态就意味着要重建查找表,另外单连接占用内存较多。
  2. 你可能不需要SSL。如果你的数据不需要保护,或者已经使用DRM或其他编码进行保护了,那么TLS的安全性对你可能无所谓。如果C/S两端都能由你自己控制的话,可以自己实现h2c,然后这个点就不再是问题了
  3. 需要抛弃针对HTTP/1.x的优化。HTTP/1.x优化在支持HTTP/2的浏览器中会影响性能,因此可能需要花时间把它们推倒重来。(比如分域存储)
  4. 对下载大文件不利。如果你的应用主要提供大文件下载或者流媒体播放,那可能不想用TLS,而且在只有一个流的情况下,多路复用也体现不出什么优势。

HTTP/2.0与HTTP/1.x的区别

http2.0和1.x在报文格式上区别很大,但是语义、状态码、请求方法没有什么区别

  • http2.0使用的是二进制格式协议,比起http1.x的明文格式协议健壮性和效率都提升了很多
  • http2.0定义了stream双向帧流,可以在一个tcp连接内混杂发送多个stream的消息,而不必像http1.x中的管道化技术,必须等前一个响应完成后再发送后面的响应(HOLB,Head-Of-Line Blocking)
  • http1.x传的都是明文,安全性很差
  • http1.x每次请求和响应都需要带上完整的header,增加了不少网络开销
  • 使用1.x协议时每个网页可能需要打开多个TCP连接来请求数据,而浏览器对每个域名打开的连接数又有限制;2.0协议可以只打开一个tcp连接,一个连接上能够支持上百个并发的流传输数据。相当于把tcp当成一个平台,在这个平台之上进行设计,实现各种花式特性
  • http2.0可以兼容http1.x,或者说http2.0包含了http1.1
  • 虽然http2.0的协议不强制要求TLS层,但实际上所有浏览器实现时都要求必须有TLS层,所以现有的http2.0基本都依赖https,而http1.x并不强制依赖https

HTTPS

https是在http之下、TCP/IP之上多加了一层安全层,一般使用SSL/TLS作为加密协议(SSL协议所有版本都有漏洞,不建议使用,TLS1.0可以降级到SSL3.0,所以也不安全)
https中的http协议可以是http1.x版本,也可以是http2.0版本

请求过程

https最有意思的地方在于它的请求过程以及安全通信的机制。(理解https安全通信机制需要先理解对称加密、非对称加密、数字证书的概念)
https在发起一个http请求时,需要通过三次握手先建立一个tcp连接,然后通过ssl的握手协议协商密钥、建立安全层连接。

下面是建立https连接的简略通信过程:

Client Server TCP握手阶段 请求建立TCP连接 同意建立TCP连接 收到,准备发送数据 TCP握手阶段结束 SSL握手阶段开始 客户端打招呼:Hello 服务端打招呼:Hello 握手一阶段结束 发送服务器证书 发送服务器公钥(可选,视具体算法而定) 请求客户端发送证书 服务端打招呼结束 握手二阶段结束 发送客户端证书 发送客户端公钥 发送证书验证信息进行自证 握手三阶段结束 发送预置主密钥 发送前面所有发出内容的hash值 通知客户端之后所有信息都是密文 发送前面所有发出内容的hash值 SSL握手第四阶段结束,开始密文通信 Client Server

上面的流程图是一个简略的握手过程示意,每一个阶段客户端和服务端都交换了很多信息。

密钥交换和生成机制

SSL/TLS的安全机制依赖于数字证书和CA机构(申请证书一般都需要花钱),下图是SSL的密钥交换协商过程的简易示意图:

以浏览器为例说明如下整个的校验过程:
在这里插入图片描述
为什么通过上面的过程之后,客户端和服务端就可以进行安全通信?
原因就在于第三方证书机构的引入。
以浏览器访问服务器为例:
在这里插入图片描述
其中最关键的是步骤3和步骤4:

  • 步骤3通过内置的证书信任列表找到给服务端签发证书的CA机构,通过自己持有的CA公钥对服务器发来的证书进行验证;
  • 步骤4利用步骤3获得的服务端公钥加密随机数,公钥加密后的密文只有私钥能够解开,而私钥只有服务端有,这就保证了其他人无法解开密文获得最关键的随机数,也就无法得到对称密钥

需要注意的是,上面两个步骤是通过CA机构公钥解密签名,获得签名中的服务器公钥,然后使用服务器公钥加密随机数的。

下面是步骤3中浏览器的操作:

  1. 首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验
  2. 浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发
  3. 如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。
  4. 如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密
  5. 浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比
  6. 对比结果一致,则证明服务器发来的证书合法,没有被冒充
  7. 此时浏览器就可以读取证书中的公钥,用于后续加密了

HTTP/3

http3是一个正在制定中的协议,其前身是HTTP-over-QUIC协议。
HTTP-over-QUIC的意思是基于QUIC协议实现的HTTP通信协议。
QUIC(Quick UDP Internet Connections),是快速 UDP 互联网连接的缩写,这是一种实验性的传输层协议,由 Google 开发,在 2013 年实现。

所以,可以看出,未来的http3将会抛弃TCP而转向UDP,省去了TCP握手的时间以及其他TCP连接的限制。
但是,UDP本身也有自己的问题,所以Google对UDP进行了改进,提出了新的传输层协议QUIC(Google真是个厉害的公司,HTTP2的前身SPDY协议也是Google提出的)

QUIC

QUIC协议放弃了TCP协议而转用UDP协议,避免了TCP的各种问题和限制,并且设计了一系列的机制来改进优化UDP本身的问题。
TCP协议都是由操作系统内核实现的,想要修改TCP协议几乎不可能,再加上TCP通信时操作系统需要在用户模式和内核模式下切换(这种切换的消耗很可观),改用UDP似乎是个不错的想法。

扩展:TCP的三次握手和四次挥手

三次握手的主要任务是验证双向传输的通路是正常的,并且在验证通路的同时建立连接。

四次挥手的主要任务是在保证数据完整性的情况下断开链接,和三次握手基本一致的思路。前两次挥手对发送端来说是主动停止单方向的链路传输,而对于接收端来说则是个通知。在完成两次挥手后连接已经是单向关闭的了。后两次挥手是接收端完成所有数据接收且已被通知单向链接被关闭的情况下发出的,目的是关闭另一个方向的连接。整个过程和拍电影时的“预备”“Action”很类似。

原本的握手流程也是四次,和挥手流程一致。但后来发现第二次和第三次握手时接收端不需要像挥手时那样等待(挥手时要等待数据传输完成,保证数据完整性),所以就把两次握手合并成了一次。


HTTP协议相关扩展阅读

代理(Proxy)、网关(Gateway)和通道(Tunnel)
HTTP的管线化技术
HTTP的Cookie技术
HTTP协议Content Lenth限制漏洞导致拒绝服务攻击
HTTP慢速攻击
SYN洪水攻击(半连接攻击)
Http指纹识别技术
使用TCP/IP协议栈指纹进行远程操作系统辨识
Banner信息
HTTP/2服务器主动推送详解
SPDY协议 v3

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值