计算机网络⑤应用层:HTTP协议(todo)


HTTP 协议

超文本传输协议(Hyper Text Transfer Protocol),是 TCP/IP 协议族的一个子集。

1、基础知识

1.1、网络和 TCP/IP

回顾一下基础知识:

  • 网络发展阶段
  • 协议:分组交换、标准化
  • TCP/IP 协议分层
    • 应用层
    • 传输层:TCP、UDP
    • 网络层:IP
    • 数据链路层、物理层
  • 其它知识点:网络组成、地址、首部等

1.2、URI 和 URL

URI URL
全称 统一资源标识符,Uniform Resource Identifier 统一资源定位符,Uniform Resource Locater
含义 唯一标识资源 互联网中资源的位置
说明 只对资源进行标识,而不进行定位 不仅对资源进行标识,还具体到资源位置
实例 http://www.abc.com
唯一标识资源,但没有定位资源位置
http://www.abc.com/image/1.png
唯一标识资源,也定位资源位置

结论URI 和 URL 是包含关系,而不是并列关系。

  • URI 是一个抽象概念,可以有不同实现形式。但只要能唯一标识资源的就可以称作 URI。
  • URL 是 URI 的实现,在 URI 的基础上定位了资源位置。
  • 只要是 URL,就一定是 URI。

1.3、HTTP 版本

时间 标准 连接方式
HTTP/0.9 1990 年问世 未成为标准 -
HTTP/1.0 RFC1945:1996 年 5 月 初期标准 每次 HTTP 通信(一次请求和响应)使用新的 TCP 连接
HTTP/1.1 RFC2068:1997 年 1 月
RFC2616:修订版
目前主流标准 持久连接:在一个 TCP 连接上发送多个请求和响应

1.4、HTTP 相关协议

  1. DNS:负责域名解析

  2. :面向连接的、可靠的流协议

  3. :实现端到端通信

    image-20220303114357553

2、HTTP

HTTP 协议 是 TCP/IP 协议族的一个子集。

  • 用于 C/S 通信,通过请求和响应的交换达成通信。

  • 客户端发出请求,服务器端响应请求并返回。

    image-20220303164433839

2.1、无状态协议

HTTP 不保存通信状态,对于发送过的请求或响应都不做持久化处理。

  • 每当有新的请求发出,都会有新的响应。
  • 目的:减少服务器 CPU 和内存消耗,更快地处理大量事务,确保协议的可伸缩性,
  • HTTP/1.1 中引入 Cookie 技术,实现保持状态功能。

假设一个场景

Web 页面使用无状态的 HTTP 协议,登录状态不会被保存。

导致每次跳转页面都需要再次登录,或者每次都在请求报文中附加参数来管理登录状态。

引入 Cookie 技术

在保留 HTTP 无状态协议特性的同时,实现了保持状态功能。

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

  • 服务器端:在响应报文中添加 Set-Cookie 首部字段,通知客户端保存 Cookie。
  • 客户端:将 Cookie 信息保存在本地,在请求报文中添加 Cookie 值。

Cookie 交互

image-20220303180154142

报文信息(有关报文的详解,见下一节)

  1. 请求报文:无 Cookie 信息

    image-20220303180320369

  2. 响应报文:生成 Cookie 信息

    image-20220303180351595

  3. 请求报文:有 Cookie 信息

    image-20220303180428710

2.2、持久连接

持久连接(HTTP keep-alive),HTTP/1.1 的默认连接

  • HTTP/1.0:每进行一次 HTTP 通信,就要建立和断开一次 TCP 连接。
  • HTTP/1.1持久连接。只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
    • 减少了 TCP 连接的重复建立和断开所造成的开销。
    • 减轻服务器端的负载。

管线化(流水线式)

管线化:无需等待响应,即可直接发送下一个请求。(并行发送)

没有使用管线化技术的情况下,需要等待上一个响应,才能发送新的请求。

2.3、范围请求

在下载大文件时如果遇到网络中断,就必须重头开始。

因此需要一种恢复机制,而实现恢复机制的前提是范围请求。

  • 恢复:能在下载中断处恢复下载。
  • 范围请求(Range Request):指定资源的下载范围。
    • 请求:使用 Range 首部字段,指定资源的 byte 范围;
    • 响应:状态码 206(Partial Content)

2.4、内容协商

内容协商(Content-Negotiation):当浏览器的默认语言不同,访问相同 URI 的页面时,会显示对应语言的 Web 页面。

内容协商机制:就响应的资源内容进行交涉,提供给客户端最为合适的资源。

  • 判断基准:响应资源的语言、字符集、编码方式等;
    • Accept
    • Accept-Charset
    • Accpet-Encoding
    • Accpet-Language
    • Content-Language
  • 类型
    • 服务器驱动类型:服务器端进行,以请求报文的首部字段未参考;
    • 客户端驱动协商:客户端进行,从浏览器的可选项列表中选择。
    • 透明协商:服务器驱动和客户端驱动的结合。

3、HTTP 报文

HTTP 报文:用于 HTTP 协议交互的信息。

  • 报文:由多行数据构成的字符串文本(用 CR+LF 作换行符)
  • 结构
    • 报文首部:请求或响应的内容及属性。
    • 空行:CR+LF
    • 报文主体:可选,表示应被发送的数据(实体主体)

请求报文

首部由请求行和首部字段组成。

image-20220305140546310

响应报文

首部由响应行和首部字段组成。

image-20220305140638020

实例

image-20220303185232593

3.1、报文首部

3.1.1、请求行:方法

请求报文首部——请求行

方法:使指定请求 URI 的资源,按期望产生某种行为。

  • 即:客户端使用不同的方法,向指定 URI 发出请求报文,服务器会采取不同的行为。
  • 方法名区分大小写,要用大写字母。

HTTP 1.0 和 HTTP/1.1 支持的方法

共有的方法:GET、POST、PUT、HEAD、DELETE

  • HTTP/1.0:LINK 和 UNLINK,在 1.1 已被废弃

  • HTTP/1.1:OPTION、TRACE、CONNECT

    image-20220303171854893

HTTP/1.1

下面详细介绍 HTTP/1.1 中的方法。

意图 含义 注意
GET 获取资源
已被 URI 识别的资源,经服务器端解析后返回响应内容。 请求的资源是文本则直接返回,是 CGI 等程序则返回执行结果。
POST 传输实体主体
PUT 传输文件 在请求报文中包含文件内容,将文件保存到指定 URI 不带验证机制,存在安全性问题
HEAD 获取报文首部 类似 GET,但只获取报文首部 不获取报文主体部分,通常用于确认 URI 有效性、资源更新的日期时间等
DELETE 删除文件 与 PUT 相反,删除指定 URI 的资源 不带验证机制,存在安全性问题
OPTIONS 询问支持的方法 查询指定 URI 支持的请求方法 即向服务器询问,某个 URI 支持使用哪些方法对其请求
TRACE 追踪路径 让服务器将请求通信环回给客户端 不常用,而且容易引发 XST(Cross-Site Tracing,跨站追踪)
CONNECT 使用隧道协议连接代理 在与代理服务器时建立隧道,用隧道协议进行 TCP 通信 主要使用 SSL 和 TLS 协议,将通信内容加密后经网络隧道传输

3.1.2、响应行:状态码

响应报文首部——响应行

状态码:表示请求的返回结果(服务器正常处理请求 / 出现错误)

image-20220303204823685

2XX:成功

表明请求被正常处理。

  • 200 OK
  • 204 No Content:不含报文主体
  • 206 Partial Content:范围请求

3XX:重定向

浏览器需要执行某些特殊的处理以正确处理请求。

  • 301 Moved Permanently:永久性重定向
  • 302 Found:临时性重定向
  • 303 See Other:资源存在另一个 URI,且需要按 GET 方式访问
  • 304 Not Modified:请求未满足条件(权限)
  • 307 Temporary Redirect:不会从 POST 变成 GET 请求

说明

  • 在 301 和 302 标准中,禁止将 POST 方法改成 GET。

  • 在 303 标准中,应当用 GET 方式访问资源的另一个 URI,而不是 POST。

  • 但是,几乎所有的浏览器都没有遵守标准,在收到 301、302、303 状态码时,将 POST 改成 GET 并重新发送请求。

  • 307 会按照浏览器标准,不会从 POST 变成 GET。

4XX:客户端错误

客户端发生错误

  • 400 Bad Request:请求报文中存在语法错误
  • 401 Unauthorized:请求未通过 HTTP 认证
  • 403 Forbidden:服务器拒绝访问(未获得授权、访问权限不足)
  • 404 Not Found:无法找到请求的资源

5XX 服务器错误

服务器发生错误

  • 500 Internal Server Error:服务器端在执行请求时发生错误
  • 503 Service Unavailable:服务器处于超负载或停机维护

3.1.3、首部字段

请求报文或响应报文——首部字段

请求和响应报文都会使用首部字段,用于传递额外的重要信息。

  • 通用首部
  • 请求首部、响应报文
  • 实体首部
  • 其它
// 结构
首部字段名: 字段值
// 例如
Content-Type: text/html
// 可以有多个字段值
Keep-Alive: timeout=15, max=100

种类

HTTP/1.1 规范定义的47 种首部字段

  • 通用首部

    image-20220305143423874
  • 请求首部

    image-20220305143501526
  • 响应报文

    image-20220305143625649
  • 实体首部

    image-20220305143639585

非 HTTP/1.1 首部字段

在 HTTP 通信中,不限于使用 RFC2616 中定义的 47 中首部字段。

还有 Cookie、Set-Cookie、Content-Disposition 等非正式的首部字段。

类型

HTTP 首部字段分为 2 种类型,依据是使用缓存代理和非缓存代理。

  • 端到端首部(End-to-end):会转发给最终接收目标,且必须保存在由缓存生成的响应中。
  • 逐跳首部(Hop-by-hop):单次转发有效,因经过缓存或代理后不再转发。

3.2、报文主体

HTTP 的报文主体,用于传输实体主体。

  • 报文(message):HTTP 通信的基本单位
  • 实体(entity):作为请求和响应的有效载荷数据,由实体首部和实体主体组成。

通常,报文实体就是实体主体。

3.2.1、编码

如果在传输中对实体主体进行编码操作时,以上二者就不是同一个概念。

  • 内容编码:用于压缩传输
    • 指明应用在实体内容上的编码格式,保持实体信息原样发送;
    • 客户端接收并负责解码。
  • 分块传输编码:用于分割发送
    • 将实体主体分成多个块;
    • 客户端接收并负责解码。

3.2.2、多部份集合对象

类似邮件中的 MIME 机制,HTTP 协议也采纳了多部份集合对象。

通常在图片或文本文件上传时使用。

添加 Content-type 首部字段,使用 boundary 字符串划分每个实体。

  • multipart/form-data:Web 表单文件上传

    image-20220303203332834
  • multipart/byteranges:多范围内容

    image-20220303203456236

4、Web 服务器

HTTP/1.1 允许一台 HTTP 服务器搭建多个 Web 站点,利用了虚拟主机的功能。

  • 虚拟主机(Virtual Host):又称虚拟服务器。
  • 即使物理层面只有一台服务器,可以“变成”多台服务器。
  • 部署在同一个服务器上的站点,具有相同的 IP 地址。
  • HTTP 请求报文必须在 Host 首部内完整指定主机名或域名的 URI。

通信数据转发程序

个人理解:代理模式的不同应用场景

  • 代理:转发请求和响应

    • 透明代理:不对报文作任何加工。反之则称为非透明代理。
    • 缓存代理:将资源的副本保存在代理服务器上。
    image-20220303231400375
  • 网关:转发服务器通信数据,就像自己拥有资源的源服务器

    • 能使通信线路上的服务器提供非 HTTP 服务;
    • 能在客户端和网关之间的通信线路上加密,提高通信安全性。
    image-20220303231522012
  • 隧道:在客户端和服务器之间进行中转

    • 确保客户端和服务器能进行安全通信。
    • 隧道本身不会解析 HTTP 请求。
    image-20220303231557998

5、HTTP 缓存

5.1、Cache-Control

通常,客户端不会直接对源服务器发起请求。

在客户端和源服务器之间,使用一个缓存服务器。

  1. 客户端向缓存服务器发出请求。

  2. 缓存服务器将请求转发给源服务器,将源服务器的响应内容转发给客户端,并在本地作缓存。

  3. 下次客户端对相同的资源发起请求时,缓存服务器可以将缓存资源直接返回给客户端,无需再访问源服务器。

    image-20220305152158172

通用首部字段:Cache-Control

  • 功能:控制缓存的行为。
  • 指令参数:参数是可选的,多个参数之间用分隔。
  • 请求报文和响应报文都可以使用 Cache-Control,具体的指令和用途可能有所不同。

共有的指令

在客户端的请求报文中使用,或在源服务器的响应报文中使用。

功能可能有所不同。

  1. no-cache:防止使用过期的缓存(而不是不缓存)
    • 请求中使用:客户端不接收缓存过的响应,缓存服务器必须把请求转发给源服务器;
    • 响应中使用:源服务器要求缓存服务器不对资源进行缓存。
  2. no-store:不缓存
  3. max-age
    • 请求中使用
      • 客户端只接收缓存时间比 max-age 数值小的缓存资源。
      • 如果指定 max-age 为 0,则缓存服务器需要将请求转发给源服务器
    • 响应中使用
      • 缓存服务器不对资源有效性再作确认。
      • max-age 数值为缓存资源的最长保存时间
  4. no-transform:缓存不能改变实体主体的媒体类型,防止压缩图片等操作
  5. cache-extension:扩展 Cache-Control 的首部字段内的指令。

缓存请求指令

image-20220305145912796
  • max-stale:即使缓存资源过期,也照常接收。
  • min-fresh:客户端要求缓存服务器,返回指定时间以内的缓存资源。
  • only-if-cached:请求的资源在缓存服务器的本地缓存时,客户端才要求其返回。
    (即如果缓存服务器中没有请求资源的缓存,则不会转发请求给源服务器)

缓存响应指令

image-20220305145906270
  • public:任何用户都可以使用响应的缓存
  • private:指定用户才能使用响应的缓存
    • 缓存服务器对特定用户提供资源缓存的服务
    • 对其它用户发送的请求,不会返回缓存
  • s-maxage:与 max-age 相同,但是 s-maxage 仅用于多用户使用的公共缓存服务器。
  • must-revalidate:要求代理在返回缓存资源之前,向源服务器再次验证缓存是否仍有效
  • proxy-revalidate:类似 must-revalidate,但只适用于共享缓存,不影响私有缓存。

5.2、todo

6、HTTPS

HTTP Secure,超文本传输安全协议

HTTP 的缺点

  • 不无加密:通信使用明文,可能被窃听。
  • 无认证:不验证通信方的身份,可能被伪装。
  • 无完整性保护:无法证明报文完整性,可能被篡改。

HTTPS

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

HTTPS = HTTP + SSL

HTTPS 不是新技术,而是指与 SSL 组合使用的 HTTP。

  • 通常,HTTP 与 TCP 直接通信。

  • 使用 SSL:HTTP 先与 SSL 通信,再由 SSL 与 TCP 通信。

    image-20220306181255676

加密

  • 加密的前提:客户端和服务器都具有加密和解密的机制。
  • 客户端或服务器,需要将自己的加密方式(即密钥)交给对方。

共享密钥加密(Common crypto system)

在了解公开密钥加密之前,先了解一下共享密钥加密。

共享密钥加密,是指加密和解密使用同一把密钥(对称密钥)。

因此,在将密钥转发给对方时,可能遭遇窃听。

image-20220306181745960

公开密钥加密(Public-key cryptography)

加密方式复杂,更安全,但效率低

公开密钥加密,使用一对密钥:私有密钥和公开密钥(非对称密钥)。

  • 私有密钥:不能让其他人获取,用于解密。
  • 公开密钥:可以随意发布,用于加密。

密文的发送方,使用对方的公开密钥进行加密处理,接收方使用自己的私有密钥进行解密。

由于

image-20220306182626494

混合加密机制

HTTPS 将两种加密方式并用

  1. 使用公开密钥加密方式交换密钥

  2. 使用共享密钥加密方式进行通信。

    image-20220306183038369

公开密钥证书

公开密钥加密存在的问题:无法证明公开密钥本身就是真实的,可能被攻击者替换了。

为解决该问题,使用数字证书认证机构(Certificate Authority)及相关机构颁发的公开密钥证书。

认证

认证:为了确认使用者是本人。

HTTP/1.1 的认证方式

  • BASIC 认证(基本)
  • DIGEST 认证(摘要)
  • SSL 客户端认证
  • FormBase 认证(基于表单)
  • * 还有 Windows 统一认证

BASIC 认证

(Base64 编码)

灵活性、安全性低

  • Base64 编码属于明文,没有加密。

  • 无法注销认证。

    image-20220306184746126

DIGEST 认证

(质询/响应)

相比 BASIC 认证,密码泄露的可能性降低。

image-20220306184819209

SSL 客户端认证

(客户端证书)

防止由于用户 ID 和密码被盗,导致的第三者冒充。

  • 客户端需安装证书,发送请求时将客户端证书的信息发送给服务器。
  • 服务器进行验证。

FormBase 认证

大部分的认证都是 FormBase 认证。

  • 用户在表单中填写登录信息,发送给服务器。
  • 服务器进行验证。

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

HTTP 本身是无状态协议,通过 Cookie 来实现状态管理。

HTTPS 安全通信机制

下图是 HTTPS 的通信步骤。

除标黄部分,其它都是 HTTPS 的安全机制。

  1. C:开始 SSL 通信
  2. S:服务器可进行 SSL 通信时的应答
  3. S:发送公开密钥证书
  4. S:SSL 第一次握手结束
  5. C:应答,发送 Pre-master secret 随机密码串(相当于公开密钥)
  6. C:ChangeCipherSpec 提示服务器,使用 Pre-master secret 随机密码串加密
  7. C:表示握手结束
  8. S:ChangeCipherSpec
  9. S:表示握手结束,SSL 连接建立完成
  10. C:发送 HTTP 请求(省略了 TCP 连接建立)
  11. S:发送 HTTP 响应
  12. C:断开连接
  13. (省略了 TCP 连接关闭)
image-20220306185715434

为什么不一直使用 HTTPS

加密通信会消耗更多的 CPU 及内存资源

如果每次通信都加密,会消耗相当多的资源,能够处理的请求数量会随之减少。

购买证书的开销大

证书对于 HTTPS 通信来说是必不可少的,而使用证书必须每年向 CA 交授权费用。

因此非敏感信息使用 HTTP,敏感数据使用 HTTPS