HTTP相关

  • 2021 年 5 月 22 日
  • 笔记

HTTP

什么是HTTP?

HTTP 是超文本传输协议,也就是HyperText Transfer Protocol。

详细解释

HTTP 是一个在计算机世界里专门在“两点”之间“传输”文字、图片、音频、视频等“超文本”数据的“约定和规范”。

什么是socket

套接字,TCP/IP网络的API。Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.

Socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。

HTTP和Socket的关系

客户端的套接字接口是客户进程与TCP连接之间的门,在服务器端的套接字接口则是服务器进程与TCP连接之间的门.

客户端向他的套接字接口发送HTTP请求报文并从它的套接字接口接收HTTP响应报文,类似的,服务器从它的套接字接口接收HTTP请求报文和向它的套接字接口发送HTTP响应报文.一旦客户向它的套接字接口发送了一个请求报文,该报文就脱离了客户控制并进入TCP的控制.

image-20210327224007162

HTTP的特点

  • HTTP是一个无状态协议.即服务器向客户发送被请求的文件,而不存储任何关于该客户的状态信息.

无状态的好处与坏处

  • 无状态的好处,因为服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。

  • 无状态的坏处,既然服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦。

例如登录->添加购物车->下单->结算->支付,这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的,每次都要问一遍身份信息。

Cookie进行状态管理

对于无状态的问题,解法方案有很多种,其中比较简单的方式用 Cookie 技术。

Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。

  • 没有Cookie信息状态下的请求

    image-20210328000031493

  • 第2次以后(存有Cookie信息状态)的请求

    image-20210328000114568

发生Cookie交互的情景中,HTTP请求报文和响应报文的内容如下.

  1. 请求报文(没有Cookie信息的状态)

    image-20210328000317071

  2. 响应报文(服务器端生成Cookie信息)

    image-20210328000342442

  3. 请求报文(自动发送保存着的Cookie信息)

    image-20210328000409752

HTTP报文格式

  • HTTP请求报文

    如下是一个HTTP请求报文

    image-20210327225622321

    请求报文的第一行叫做请求行,其后继的行叫做首部行,请求行有3个字段:方法字段,URL字段和HTTP版本字段,方法字段可以取不同的值,包括GET,POST,HEAD,PUT和DELETE.

    在本例中,该浏览器正在向 /chapter17/user.html 提交表单,实现的是HTTP/1.1协议

    User-Agent:向服务器发送请求的浏览器类型

    Connection: Keep-Alive: 使用持续连接

    Host:指明对象所在的主机

    Cookie:类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息

    一个HTTP请求报文的通用格式如下

  • HTTP响应报文

    如下是一个HTTP响应报文

    image-20210327230733385

    它有三个部分:响应行,首部行,实体体(entity body)

    实体体部分是报文的主要部分,包含了所请求的对象本身.

    响应行有3个字段:协议版本字段,状态码和相应状态信息.

    在这个例子中,状态行指示服务器正在使用HTTP/1.1,并且一切正常

    Date:服务器产生并发送该响应报文的日期和时间.(不是指对象创建或者最后修改的时间,而是服务器从它的文件系统中检索到该对象,将该对象插入响应报文,并发送该响应报文的时间)

    Server:指示该报文是由一台Apache-Coyote/1.1服务器产生的

    Content-Type:指示了实体体中的对象是json文本

    一个HTTP响应报文的通用格式如下

    image-20210327231724589

HTTP的请求方法

image-20210327232940936

常见的状态码

200 OK:请求成功,信息在返回的响应报文中

301 Moved Permanently:请求的对象已经被永久转移,新的URL定义在响应报文的Location:首部行中.客户软件将自动获取新的URL.

例如,当lldexample更名为example时,他们将URL从lldexample.com更改为example.com,每个lldexample.com页面都通过永久的301重定向重定向到相应的example.com页面。

302 Found:临时重定向,表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问.

例如,可以在登陆用户访问用户中心的时候重定向到登录页面。接着,搜索引擎就会获取新内容,并保留旧的URL。由于服务器返回的是302代码,搜索引擎会认为新的网址只是暂时的。

400 Bad Request:表示请求报文中存在语法错误.当错误发生时,需修改请求的内容后再次发送请求.

403 Forbidden:表示对请求资源的访问被服务器拒绝了.

404 Not Found:表示服务器上无法找到请求的资源

什么情况下会出现404?

> 第一种:
		用户输入的地址链接有误,导致IIS提示404 not found。

> 第二种:
		服务器上本该有的页面已经被删除了,这种情况多发于BBS论坛,N年前的帖子如今被你通过搜索引擎搜索出来了,但实际上BBS论坛为了保障服务器的资源合理运用,都会将过期或非常久远的信息页面删除,导致404 not found。

> 第三种:
		DNS设置阻止,就中文环境而言,国外有一些被禁网站在中国浏览同样会出现404 not found的现象,这需要使用代理服务器才可以正常浏览。

500 Internal Server Error:表示服务器在执行请求时发生了错误,也可能是web应用存在bug或临时故障

503 Service Unavaliable:表示服务器暂时处于超负载或正在进行停机维护,现在无法处理请求

505 HTTP Version Not Supported:服务器不支持请求报文使用的HTTP协议版本

HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/3 演变

  • HTTP/1.0:1996年5月,HTTP/1.0 版本发布,内容大大增加。

    首先,任何格式的内容都可以发送。这使得互联网不仅可以传输文字,还能传输图像、视频、二进制文件(超文本)。这为互联网的大发展奠定了基础。

    其次,除了GET命令,还引入了POST命令和HEAD命令,丰富了浏览器与服务器的互动手段。

    再次,HTTP请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。

    其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

    痛点:每个TCP连接只能发送一个请求,发送数据完毕,链接就关闭,如果还要请求其他资源,就必须再新建一个连接。

    TCP连接的新建成本很高,因为需要客户端和服务器三次握手,并且开始时发送速率较慢(slow start)。所以,HTTP 1.0版本的性能比较差。随着网页加载的外部资源越来越多,这个问题就愈发突出了。

  • HTTP/1.1:1997年1月,HTTP/1.1 版本发布,只比 1.0 版本晚了半年。它进一步完善了 HTTP 协议,一直用到了20年后的今天,直到现在还是最流行的版本。

    为了解决HTTP 1.0的这个痛点,HTTP/1.1支持持续连接(HTTP/1.1的默认模式使用带流水线[1]的持久连接),在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍然需要使用各自的连接。

    管道机制:HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间。

    痛点:

    1. 虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。也就是如果一个响应返回延迟了,那么其后续的响应都会被延迟,直到队头的响应送达。
    2. 单向请求,只能由客户端发起。
    3. 请求报文与响应报文首部信息冗余量大。
    4. 数据未压缩,导致数据的传输量大
  • HTTP/2:2015年,HTTP/2 发布。它不叫 HTTP/2.0,是因为标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3。

    二进制分帧

    HTTP/1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为”帧”(frame):头信息帧和数据帧。

    image-20210329000430088

    多路复用

    下面是几个概念:

    • 流(stream):已建立连接上的双向字节流。
    • 消息:与逻辑消息对应的完整的一系列数据帧。
    • 帧(frame):HTTP/2通信的最小单位,每个帧包含帧头部,至少也会标识出当前帧所属的流(stream id)。

    image-20210329001715976

    从图中可见,所有的HTTP/2通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流。

    每个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(stream id)重新组装。

    另外,多路复用(连接共享)可能会导致关键请求被阻塞。HTTP/2里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回给客户端,数据流还可以依赖其他的子数据流。

    可见,HTTP/2实现了真正的并行传输,它能够在一个TCP上进行任意数量HTTP请求。而这个强大的功能则是基于“二进制分帧”的特性。

    头部信息压缩

    HTTP 协议不带有状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如CookieUser Agent,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。

    HTTP/2 对这一点做了优化,引入了头信息压缩机制(header compression)。一方面,头信息使用gzipcompress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

    服务器推送

    HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)。

    常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。

    痛点:

    • 建立连接时间长(本质上是TCP的问题)队头阻塞问题移动互联网领域表现不佳(弱网环境)
    • 移动互联网领域表现不佳
    • TCP队头阻塞问题
  • HTTP/3:在我们眼里,TCP是面向连接、可靠的传输层协议,当前几乎所有重要的协议和应用都是基于TCP来实现的。

    网络环境的改变速度很快,但是TCP协议相对缓慢,正是这种矛盾促使谷歌做出了一个看似出乎意料的决定-基于UDP来开发新一代HTTP协议。

    image-20210329235319849

    谷歌决定在UDP基础上改造一个具备TCP协议优点的新协议也就顺理成章了,这个新协议就是QUIC[2]协议。

    在设计之初,Google就希望使用这个协议来取代HTTPS/HTTP协议,使网页传输速度加快。2015年6月,QUIC的网络草案被正式提交至互联网工程任务组。2018 年 10 月,互联网工程任务组 HTTP 及 QUIC 工作小组正式将基于 QUIC 协议的 HTTP(英语:HTTP over QUIC)重命名为HTTP/3。

    所以,我们现在所提到的HTTP/3,其实就是HTTP over QUIC,即基于QUIC协议实现的HTTP。

    image-20210330001224491

    QUIC协议必须要实现HTTP2.0在TCP协议上的重要功能,同时解决遗留问题,我们来看看QUIC是如何实现的。

    队头阻塞问题

    回顾:所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。也就是如果一个响应返回延迟了,那么其后续的响应都会被延迟,直到队头的响应送达。

    HTTP/2协议中的多路复用机制解决了HTTP层的队头阻塞问题,但是在TCP层仍然存在队头阻塞问题.

    TCP协议在收到数据包之后,这部分数据可能是乱序到达的,但是TCP必须将所有数据收集排序整合后给上层使用,如果其中某个包丢失了,就必须等待重传,从而出现某个丢包数据阻塞整个连接的数据使用。

    但是,QUIC协议是基于UDP协议实现的,在一条链接上可以有多个流,流与流之间是互不影响的,当一个流出现丢包影响范围非常小,从而解决队头阻塞问题。

    建链时间长问题

    衡量网络建链的常用指标是RTT Round-Trip Time,也就是数据包一来一回的时间消耗。

    image-20210330002018005

    一般来说HTTPS协议要建立完整链接包括:TCP握手和TLS握手,总计需要至少2-3个RTT,普通的HTTP协议也需要至少1个RTT才可以完成握手。

    然而,QUIC协议可以实现在第一个包就可以包含有效的应用数据,从而实现0RTT

    这在连接时延上有很大优势,可以节约数百毫秒的时间

    但是对于双方完全陌生的情况下,为了保证传输的安全,我们需要进行一次连接

    使用QUIC协议的客户端和服务端要使用1RTT进行密钥协商,使用的密钥协商算法是DH(Diffie-Hellman)迪菲-赫尔曼算法

    当密钥协商完之后,客户端会存储服务端发送来的config包,后续再连接时可以直接使用,从而跳过这个1RTT,实现0RTT的业务数据交互.

    但是客户端保存config是有时间期限的,在config失效之后仍然需要进行首次连接时的密钥交换。

    移动互联网领域表现不佳问题

    网络切换几乎无时无刻不在发生。

    TCP协议使用五元组来表示一条唯一的连接,当我们从4G环境切换到wifi环境时,手机的IP地址就会发生变化,这时必须创建新的TCP连接才能继续传输数据。

    QUIC协议基于UDP实现摒弃了五元组的概念,使用64位的随机数作为连接的ID,并使用该ID表示连接。

    基于QUIC协议之下,我们在日常wifi和4G切换时,或者不同基站之间切换都不会重连,从而提高业务层的体验。

    image-20210330004242118

    UDP链接的安全问题

    通俗来说,前向安全指的是密钥泄漏也不会让之前加密的数据被泄漏,影响的只有当前,对之前的数据无影响。

    前面提到QUIC协议首次连接时先后生成了两个加密密钥,由于config被客户端存储了,如果期间服务端私钥泄漏,那么可以根据K = mod p计算出密钥K。

    如果一直使用这个密钥进行加解密,那么就可以用K解密所有历史消息,因此后续又生成了新密钥,使用其进行加解密,当时完成交互时则销毁,从而实现了前向安全。

    image-20210330235340173

    丢包处理

    FEC前向纠错
    QUIC协议的每个数据包除了本身的数据以外,会带有其他数据包的部分数据,在少量丢包的情况下,可以使用其他数据包的冗余数据完成数据组装而无需重传,从而提高数据的传输速度。具体实现类似于RAID5,将N个包的校验和(异或)建立一个单独的数据包发送,这样如果在这N个包中丢了一个包可以直接恢复出来。除此之外还可以用来校验包的正确性(已废弃)

    关键包发送多次

    同时,对于一些非常重要的包,QUIC在发送后的短时间内如果没收到回包,便会重发请求,以确保重要的节点不被Delay


DNS协议

DNS(Domain Name System)服务是和HTTP协议一样位于应用层的协议.它提供域名到IP地址之间的解析服务

计算机既可以被赋予IP地址,也可以被赋予主机名和域名.比如 www.baidu.com.

用户通常使用主机名或域名来访问对方的计算机,而不是直接通过IP地址访问.因为与IP地址的一组纯数字相比,用字母配合数字的表示形式来指定计算机名更符合人类的记忆习惯

DNS协议提供通过域名查找IP地址,或逆向从IP地址反向查域名的服务

image-20210328002230119

获得www.baidu.com的IP地址的做法如下:

  1. 同一台用户主机上运行着DNS应用的客户端
  2. 浏览器从URL中抽取出主机名www.baidu.com,并将这台主机名传给DNS应用的客户端
  3. DNS客户向DNS服务器发送一个包含主机名的请求
  4. DNS客户最后会收到一份回答报文,其中含有对应于该主机名的IP地址.
  5. 一旦浏览器接收到来自DNS的该IP地址,它能够向位于该IP地址80端口的HTTP服务器进程发起一个TCP连接

通过DNS服务器查询IP地址的过程如下:

  • 根DNS服务器:有400多个根名字服务器遍及全世界.这些根名字服务器由13个不同组织管理

  • 顶级域服务器:对于每个顶级域(如com,org,net,edu和gov)和所有的国家的顶级域(如uk,fr,ca和jp),都有TLD服务器(或服务器集群

  • 本地服务器:严格来说,一个本地DNS服务器并不属于该服务器的层次结构,但它对DNS层次结构是至关重要的.每个ISP都有一台本地DNS服务器(也叫默认名字服务器).当主机与某个ISP连接时,该ISP提供一台主机的IP地址,该主机具有一台或多台其本地DNS服务器的IP地址(通常通过DHCP)

  • DNS缓存:为了改善时延性能并减少在因特网上到处传输的DNS报文数量,DNS广泛运用了缓存技术.

    原理是,在一个请求链中,当某DNS服务器接受一个DNS回答时,它能将映射缓存在本地存储器中.


HTTPS

HTTP与HTTPS的区别

  1. HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全 的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
  2. HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
  3. HTTP 的端口号是 80,HTTPS 的端口号是 443。
  4. HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

HTTP的痛点

  • 窃听风险,比如通信链路上可以获取通信内容,用户号容易没。
  • 篡改风险,比如强制植入垃圾广告,视觉污染,用户眼容易瞎。
  • 冒充风险,比如冒充淘宝网站,用户钱容易没。

HTTPS如何解决这些问题?

HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议,可以很好的解决了上述的风险:

  • 信息加密:交互信息无法被窃取,但你的号会因为“自身忘记”账号而没。
  • 校验机制:无法篡改通信内容,篡改了就不能正常显示,但百度“竞价排名”依然可以搜索垃圾 广告。
  • 身份证书:证明淘宝是真的淘宝网,但你的钱还是会因为“剁手”而没。

信息加密的三种方式

  • 对称加密:加密和解密同用一个密钥的方式称为共享密钥加密,也被叫做对称密钥加密.

    常用的对称加密算法有DES,AES加密

    问题是如何安全的转交密钥到对方手中呢?

    image-20210513000820727

  • 非对称加密:非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

    常用的对称加密算法有RSA加密.

    值得注意的是,RSA所要求的指数运算相当耗费时间,形成对比的是,DES用软件实现要比RSA快100倍,所以,在实际应用中,RSA通常与对称密钥密码结合起来使用

  • Hash: hash 是把任意长度数据经过处理变成一个长度固定唯一的字符串,但任何人拿到这个字符串无法反向解密成原始数据(解开你就是密码学专家了),Hash 常用来验证数据的完整性。常见 Hash 算法有 MD5(已经不安全了)、SHA1、SHA256


结合上述对称加密和非对称加密的特点,HTTPS采用混合加密机制

具体过程为:

  1. 服务器把 公钥发给客户端 去加密 稍后共享密钥加密 中要使用的密钥
  2. 客户端把 共享密钥 用服务器刚发来的公钥加密,并发给服务器,服务器拿到后用私钥解开,就得到了共享密钥
  3. 然后就可以快乐的用共享密钥来进行通信

image-20210513003638711

可是问题又来了,

我如何证明我收到的公钥就是货真价实服务器发来的公钥,而不是坏人发来的钓鱼公钥呢?

数字证书认证机构(CA)

数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上.

数字证书认证的业务流程:

首先,服务器 的运营人员向数字证书认证机构提出公开密钥的申请。

数字证书认证 机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。

服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行公开密钥加密方式通信。

公钥证书也可叫做数字证书或直接称为证书。

接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书 上的数字签名进行验证,一旦验证通过,客户端便可明确两件事: 一,认证服务器的公开密钥的是真实有效的数字证书认证机构。二, 服务器的公开密钥是值得信赖的。

此处认证机关的公开密钥必须安全地转交给客户端。

使用通信方式时,如何安全转交是一件很困难的事,因此,多数浏览器开发商发布版本时,会事先在内部植入常用认证机关的公开密钥。

image-20210513004358362

CA认证要花钱么?

CA证书的价格主要受到两个方面的因素影响,即:品牌和类型。

品牌方面,高端的像SymantecGlobalSign等,价格基本都在千元到万元不等,平价的像GeoTrustComodoRapidSSL等,几百元到几千元不等。

类型方面,基础型的DV证书就比较便宜,最低百元左右就能申请。企业型的OV证书和EV证书价格就贵一些,几百几千甚至上万元都有。

总的来说,价格从百元到千元甚至万元的都有。当然,不同类型的CA证书适用于不同类型的网站。

参考:

//segmentfault.com/a/1190000013028798

//www.ruanyifeng.com/blog/2016/08/http.html

//baijiahao.baidu.com/s?id=1686728003170581869&wfr=spider&for=pc

//baijiahao.baidu.com/s?id=1677802258258817086&wfr=spider&for=pc

《图解HTTP》

《计算机网络 自顶向下方法》


  1. 对对象的这些请求可以一个接一个地发送,而不必等待对未决请求的回答 ↩︎

  2. Quick UDP Internet Connections ↩︎