HTTP协议

计算机网络学习笔记之三

Posted by     "Eric" on Sunday, February 16, 2020

1. Http的初步认识

1.1 Http的诞生

CERN的蒂姆·伯纳斯-李博士提出一种让全球研究者共享知识的设想:借助多文档之间互相关联形成的超文本,连成可相互参阅的WWW(World Wide Web),WWW由HTML作为语言,HTTP作为文档传递协议,以URL标记文档所在地构成。

1.2 各种协议与HTTP协议的关系

3pInVe.png

1.3 URI和URL

统一资源标志符URI就是在某一规则下能把一个资源独一无二地标识出来。当然我们可以通过地址的形式将该资源标识出来,也就是说我们熟知的URL统一资源定位符。因此URL是URI的一个子集。

URI的格式如下

<协议>://<主机>:<端口>/<路径>

其中主机名可以用域名来表示也可以用IPv4地址,端口号若胜率则自动选择默认端口号。

2. HTTP协议结构

2.1 HTTP概述

HTTP协议用于客户端和服务器端之间的通信,通过请求和响应的交换达成通信。HTTP是一种不保存状态,即无状态的协议,也就是说每当有新的请求发送到服务器时,服务器都会有对应的新响应产生,而不受过去状态的影响。这符合HTTP协议设计的初衷——简单。HTTP/1.1虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了Cookie技术。

2.2 HTTP报文结构

HTTP报文大致可分为报文首部和报文主体两块。两块中间由空行(CR+LF)间隔。通常,并不一定要有报文主体。

3pI12t.png

请求报文是由请求方法、 请求 URI、 协议版本、 可选的请求首部字段和内容实体构成的。

3pINVg.png

响应报文基本上由协议版本、 状态码(表示请求成功或失败的数字代码)、 用以解释状态码的原因短语、 可选的响应首部字段以及实体主体构成。

3pIhGR.png

2.3 请求URI定位资源

3pIoM6.png

当客户端请求访问资源而发送请求时,HTTP报文需要将URI包含在内。指定URI的方式有很多,如上图所示。可以在请求行中写明URI,或者可以在Host首部中写明网络域名或者IP地址。在Host首部中写出主机名还可以用来访问放在同一个IP地址的主机上不同的网站。

除此之外,如果不是访问特定资源还是对服务器本身发起请求,可以用一个*来代替请求URI,例如查询HTTP服务器端支持的HTTP方法种类。

OPTIONS * HTTP/1.1

2.4 告知服务器意图的HTTP方法

  • GET:获取资源

    GET 方法用来请求访问已被URI识别的资源 ,

  • POST:传输实体主体

    用来给服务器传输数据,虽然GET方法也可以传输实体的主体,但通常使用POST,并且POST的主要目的不是获取响应的主体内容

  • PUT:传输文件

    PUT 方法用来传输文件。 就像 FTP 协议的文件上传一样, 要求在请求报文的主体中包含文件内容, 然后保存到请求 URI 指定的位置。但是由于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,一般Web网站不适用该方法。

  • HEAD:获得报文首部

    与GET方法一样,只是不返回报文主体部分。用于确认URI的有效性以及资源更新的日期时间等。

  • DELETE:删除文件

    与PUT相反的方法。一般的Web网站同样不使用DELETE方法。

  • OPTIONS:询问支持的方法

    上文已提。

2.5 持久连接节省通信量

在HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接,例如访问一个多图的HTML页面的时候,每加载一张图都要建立TCP连接,然后断开连接,增加了通信量的开销。

为了避免这一情况,在HTTP/1.1中提出了持久连接,只要任意一端没有明确提出断开连接,则保持TCP连接状态。

3pILIH.png

持久连接使得多数请求以管线化方式发送称为可能。也就是不用等待响应就可以发送下一个请求。

3pIxzt.png

2.6 使用Cookie的状态管理

HTTP不保存状态,可以减少服务器的CPU及内存资源的消耗。但是不保存状态又会给用户访问页面带来许多麻烦。Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。

Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的 首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器 发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。

服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一 个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。

3 HTTP报文内的HTTP信息

3.1 请求报文以及响应报文的结构

3poVWn.png

  • 请求行:包含用于请求的方法,请求URI和HTTP版本
  • 状态行:包含表明响应结果的状态码,原因短语和HTTP版本
  • 首部字段:包含表示请求和响应的各种条件和属性的各类首部,一般有4种首部,分别是:通用首部、请求首部、响应首部和实体首部
  • 其他:可能包含HTTP里未定义的首部。

3.2 编码提升传输速率

HTTP在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码提升传输速率。但是,编码的操作需要计算机来完成,因此会消耗更多的CPU资源。

3.2.1 压缩传输的内容编码

HTTP协议中有一种被称为内容编码的功能对数据进行压缩,然后传输。内容编码后的实体由客户端接收并负责解码。

3.2.2 分割发送的分块传输编码

在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。这种把实体主体分块的功能称为分块传输编码。使用分块传输编码的实体会由接收的客户端负责解码,恢复到编码前的实体主体。

3.4 发送多种数据的多部分对象集合

在HTTP协议中也采纳了多部分对象集合,发送的一份报文主题内可含有多类型实体。通常是在图片或文本文件等上传时使用。

3.5 获取部分内容的范围请求

如果下载过程中遇到网络中断情况,HTTP可以提供一种恢复机制。要实现该功能需要制定下载的实体范围。像这样,制定范围发送的请求叫做范围请求。针对范围请求,响应会返回状态码为206 Partial Content的响应报文。如果服务器端无法响应范围请求,则返回状态码200 OK和完整的实体内容。

3.6 内容协商返回最合适的内容

内容协商机制是指客户端和服务器端就响应的资源内容进行交涉,然后提供给客户端最为适合的资源。内容协商会以响应资源的语言、字符集、编码方式等作为判断的基础。

由服务器端进行内容协商,在服务器端自动处理,并不一定能筛选出最优内容。由客户端进行内容协商的方式,用户从浏览器显示的可选列表中手动选择。

4. HTTP状态码

响应类别有以下5种。

类别 原因短语
1XX 信息性状态码 接收的请求正在处理
2XX 成功状态码 请求正常处理完毕
3XX 重定向状态码 需要进行附加操作以完成请求
4XX 客户端错误状态码 服务器无法处理请求
5XX 服务器错误状态码 服务器处理请求出错

4.1 2XX成功

  • 200 OK

    表示从客户端发来的请求在服务器端被正常处理了。在响应报文内,随状态码一起返回的信息因方法的不同而发生改变。

  • 204 No Content

    服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。

  • 206 Partial Content

    客户端进行了范围请求,而服务器成功执行了这部分的GET请求。

4.2 3XX重定向

  • 301 Moved Permanently

    永久性重定向,表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI

  • 302 Found

    临时性重定向,该状态码表示请求的资源已被分配新的URI,希望用户能使用新的URI访问。

  • 303 See Other

    该状态码表示由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。

当301、302、303响应状态码返回时,几乎所有的浏览器都会将POST改成GET,并删除请求报文内的主体,之后请求会自动再次发送。301、302标准是禁止POST方法改变成GET方法的,但实际使用时大家都会这么做。

  • 304 Not Modified

    当客户端缓存了目标资源但不确定该缓存资源是否是最新版本的时候, 就会发送一个条件请求。在进行条件请求时,客户端会提供给服务器一个If-Modified-Since请求头,其值为服务器上次返回响应头中Last-Modified值,还会提供一个If-None-Match请求头,值为服务器上次返回的ETag响应头的值。

    服务器会读取到这两个请求头中的值,判断出客户端缓存的资源是否是最新的,如果是的话,服务器就会返回HTTP/304 Not Modified响应头, 但没有响应体.客户端收到304响应后,就会从本地缓存中读取对应的资源。

    如果服务器认为客户端缓存的资源已经过期了,那么服务器就会返回HTTP/200 OK响应,响应体就是该资源当前最新的内容。

  • 307 Temporary Redirect

    类似于302 Found。

4.3 4XX客户端错误

4XX的响应结果表明客户端是发生错误的原因所在。

  • 400 Bad Request

    该状态码表示请求报文中存在语法错误,需要修改请求的内容后再次发送请求。

  • 401 Unauthorized

    该状态码表示发送的请求需要通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。

  • 403 Forbidden

    请求资源的访问被服务器拒绝,服务器没有必要给出详细理由。

  • 404 Not Found

    服务器无法找到请求的资源。

  • 405 Method Not Allowed

    服务器不支持请求的HTTP方法

4.4 5XX服务器错误

5XX的响应结果表明服务器本身发生错误。

  • 500 Internal Server Error

    服务器端在执行请求时发生了错误。

  • 503 Service Unavailable

    服务器暂时处于超负荷或正在进行停机维护。

5 与HTTP协作的Web服务器

一台Web服务器可搭建多个独立域名的Web网站,也可作为通信路径上的中转服务器提升传输速率。

5.1 用单台虚拟主机实现多个域名

一个web服务器上可以托管多个网站,HTTP如何区分请求访问的哪个网站?可以在服务器的网卡上绑定多个IP地址,然后给每个网站分配不同的ip。也可以都用同一个ip但是不同的端口号,访问的时候必须指明端口号。或者使用域名,给每个网站绑定一个域名,客户端访问的时候只能使用域名进行访问,绑定的域名我们称之为主机头(host)。

在互联网上,域名通过DNS服务映射到IP地址之后访问目标网络,可见,当请求发送到服务器时,已经是以IP地址形式访问了。因此在相同IP地址下,在发送HTTP请求时,必须在Host首部内完整指定主机名或域名的URI。

5.2 代理

代理是一种有转发功能的应用程序,代理服务器基本行为就是接受客户端发送的请求后转发给其他服务器,代理不改变请求URI,会直接发送给原服务器。从源服务器返回的响应经过代理服务器后再转给客户端。

使用代理服务器可以利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制等。

代理可以根据两个基准进行分类,一种是是否使用缓存,另一种是是否会修改报文。

缓存代理会预先将资源的副本保存在代理服务器上,当代理再次接收到相同资源的请求时,可以将之前的缓存作为相应返回。

转发请求或响应时,不对报文做任何加工的代理类型称为透明代理

5.3 网关

网关能使通信线路上的服务器提供非HTTP协议服务。

3powwD.png

5.4 隧道

隧道可按要求建立起一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全通信。

5.5 缓存

缓存是指代理服务器或客户端本地磁盘内保存的资源副本。 利用缓存可减少对源服务器的访问, 因此也就节省了通信流量和通信时间。

5.5.1 缓存的有效期限

当服务器上资源更新时,代理服务器上缓存的资源就变成了“旧”资源,因此即使存在缓存,也会因为客户端的要求、 缓存的有效期等因素, 向源服务器确认资源的有效性。 若判断缓存失效, 缓存服务器将会再次从源服务器上获取“新”资源。

3poDFH.png

5.5.2 客户端的缓存

缓存不仅可以存在缓存服务器内,也可以存在客户端浏览器中。与缓存服务器相同,当判定缓存过期后,会向源服务器确认资源的有效性。 若判断浏览器缓存失效, 浏览器会再次请求新资源。

6. HTTP首部(略)

6.1 通用首部字段

3po2Of.png

Cache-Control

通过制定首部字段Cache-Control的指令,就能操作缓存的工作机制,该指令的参数是多选的,多个指令之间通过“,”分割。相同的参数在请求和响应两种状态下有不同的含义。如下图所示

image-20200909211915182

6.2 请求首部字段

3pohTg.png

Host

虚拟主机运行在同一个IP上,使用首部字段Host加以区分

image-20200909214620699

If-Match

后面跟实体标记(ETag),实体标记是与特定的资源相关联的,它是资源以字符串形式的唯一标识,只有If-Match后面所跟的实体标记与所请求的资源相一致时,服务器才会返回结果。

6.3 响应首部字段

3pxvWT.png

实体首部字段

3pzPm9.png

为Cookie服务的首部字段

管理服务器与客户端之间状态的Cookie,虽然没有编入标准化HTTP/1.1中,但在Web网站方面得到了广泛的应用。

Cookie的工作机制是用户识别及状态管理。Web网站为了管理用户的状态会通过Web浏览器,把一些数据临时写入用户的计算机内,接着当用户访问该Web网站时,可通过通信方式取回之前发放的Cookie。

属性 说明
NAME=VALUE 赋予Cookie的名称和其值
expires=DATE Cookie的有效期,如果省略,其有效期仅限于维持浏览器会话时间段内
path=PATH 将服务器上的文件目录作为Cookie的使用对象
domain=域名 作为Cookie使用对象的域名
Secure 仅在HTTPS安全通信时才会发送Cookie
HttpOnly 加以限制,使Cookie不能被JavaScript脚本访问

首部字段Cookie会告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。

通用首部字段中Connection的作用

Connection首部字段具有两个作用:

  1. 控制不再转发给代理的首部字段
  2. 管理持久化连接

image-20200615144630505

HTTP/1.1版本的默认连接就是持久连接,客户端会在持久连接上连续发送请求,当服务器端明确断开连接时,则指定Connection首部字段的值为close

7 确保Web安全的HTTPS

7.1 HTTP的缺点

  • 通信使用明文(不加密),内容会被窃听
  • 不验证通信方的身份,因此有可能遭遇伪装
  • 无法证明报文的完整性,所以有可能已遭篡改

7.2 HTTP+加密+认证+完整性保护=HTTPS

HTTPS不是应用层的一种新协议,只是HTTP的通信接口部分使用SSL和TLS协议代替。

3pzFT1.png

SSL使用的是一种混合加密技术,处理方式详见该博文

7.3 HTTPS的安全通信机制

3pzEY6.png

步骤 1: 客户端通过发送 Client Hello 报文开始 SSL通信。 报文中包含客户端支持的 SSL的指定版本、 加密组件(Cipher Suite) 列表(所使用的加密算法及密钥长度等) 。
步骤 2: 服务器可进行 SSL通信时, 会以 Server Hello 报文作为应答。和客户端一样, 在报文中包含 SSL版本以及加密组件。 服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。

步骤 3: 之后服务器发送 Certificate 报文。 报文中包含公开密钥证书。

步骤 4: 最后服务器发送 Server Hello Done 报文通知客户端, 最初阶段的 SSL握手协商部分结束。

步骤 5: SSL第一次握手结束之后, 客户端以 Client Key Exchange 报文作为回应。 报文中包含通信加密中使用的一种被称为 Pre-master secret 的随机密码串。 该报文已用步骤 3 中的公开密钥进行加密。

步骤 6: 接着客户端继续发送 Change Cipher Spec 报文。 该报文会提示服务器, 在此报文之后的通信会采用 Pre-master secret密钥加密(可以理解为混合加密中已经被公钥加密的共享密钥)。

步骤 7: 客户端发送 Finished 报文。 该报文包含连接至今全部报文的整体校验值。 这次握手协商是否能够成功, 要以服务器是否能够正确解密该报文作为判定标准。

步骤 8: 服务器同样发送 Change Cipher Spec 报文。

步骤 9: 服务器同样发送 Finished 报文。

步骤 10: 服务器和客户端的 Finished 报文交换完毕之后, SSL连接就算建立完成。 当然, 通信会受到 SSL的保护。 从此处开始进行应用层协议的通信, 即发送 HTTP 请求。

步骤 11: 应用层协议通信, 即发送 HTTP 响应。

步骤 12: 最后由客户端断开连接。 断开连接时, 发送 close_notify 报文。 上图做了一些省略, 这步之后再发送 TCP FIN 报文来关闭与 TCP的通信。

简化的讲,SSL建立的过程就是服务器向客户端发送带有ca认证的公钥,客户端使用公钥加密一个共享公钥然后传递给服务器,服务器使用自己的私钥解密的过程。在后续发送http请求的时候都是用该共享公钥进行加密解密,同时应用层发送数据时会附加MAC(消息认证),查知报文是否遭到篡改。

3pzmlD.png

7.4 HTTPS的缺点

当使用SSL时,它的处理速度会变慢,其原因有二,一是通信慢,在正常的http基础上要进行SSL通信;二是处理速度慢,在服务器和客户端都需要进行加密和解密的运算处理。HTTPS要比HTTP慢2到100倍。

8 确认访问用户身份的认证

8.1 BASIC认证

3pzuOH.png

客户端将用户名和密码中间用冒号连接,然后经过Base64编码处理,发送给服务器。Base64编码不是加密处理,不需要任何附加信息就可以对其解码,除此之外想再进行一次 BASIC 认证时,一般的浏览器却无法实现认证注销操作,且达不到多数Web网站期望的安全性登记,因此并不常用。

8.2 基于表单认证

基于表单的认证方法并不是在HTTP协议中定义的,而是由Web应用程序各自实现的。通过服务器端的 Web 应用, 将客户端发送过来的用户ID和密码与之前登录过的信息做匹配来进行认证的。

基于表单认证一般会使用Cookie来管理Session。

3pzdmj.png