HTTP详解

Posted by Sutdown on January 20, 2025
HTTP基础
URL标准格式

方案/协议(TCP/IP传输协议) + 因特网地址(IP地址 / 数组形式的IP地址) + 资源路径

HTTP方法

GET从服务器获取一份文档

PUT将请求的主体存储到服务器上

DELETE从服务器中删除命名资源

POST向服务器发送需要处理的数据

HEAD只发送资源相应中的HTTP头部

1.put和post的区别(命名资源和网关应用程序)

HTTP状态码
  • 1xx 信息提示
  • 2xx成功
  • 3xx重定向
  • 4xx客户端错误
  • 5xx服务器错误
HTTP报文结构

起始行,首部字段,主体

请求报文:

  • 方法 路径 版本 ;
  • 首部(Accept首部(比如Accept Encoding,Accept Language等),条件请求首部(比如IF None match等),安全请求首部(Cookie,Authorization),代理请求首部 ;
  • 主体

响应报文:

  • 版本 状态 ;
  • 首部 (协商首部(Accept Range),安全响应首部(set cookie, www Authenticate等),实体首部(Content Type, Content Encoding, Etag, Last Modiied等) );
  • 主体

响应报文中的10个基本字体首部字段:

content type , content lenghth , content language , content encoding , content location , content range , content MD5 , last modified , expires , allow , Etag , cache control(HTTP/1.1)

HTTP特性
  1. 简单灵活,易于扩展。

    基本报文格式header+body,头部信息以key-value的简单文本形式,易于理解。

    HTTP2.0之后提出压缩算法,针对头部信息中的冗余。

    HTTP中的各种请求方法等每个字段都允许开发人员自行定义和补充修改。

  2. 应用广泛,跨平台。

  3. 无状态,明文传输,不安全。

    无状态—>cookie/session

    明文传输—>SSL/TLS,基于UDP的QUIC都能起到加密的作用

HTTP连接
  • 从URL中解析出主机名,通过DNS协议查询主机名对应的IP地址,浏览器同时获得端口号;
  • 浏览器根据相应的IP地址和端口号,建议一条到服务器的TCP连接
  • 浏览器发送请求报文,服务器收到后发回响应报文
  • 浏览器四次挥手关闭连接
TCP的数据通过IP分组的数据块发送

HTTP发送数据时以流的形式通过打开的TCP连接按序传输,TCP收到数据流后,将数据流分为断的数据块,封装在IP分组中,每个IP分组包括一个IP分组首部,一个TCP段首部,一个TCP数据块。(IP分组存在于网络层,TCP段存在于运输层)

TCP连接通过四元组识别<源IP,源端口,目的IP,目的端口>

提高HTTP的连接性能
  1. 并行连接。通过多条TCP连接发送并发的HTTP请求。(视觉上你能看到多个组件同时加载,但实际上还是并发)

  2. 持久连接。重用TCP连接,消除连接,关闭时延。

    HTTP/1.0的“Keep alive” 和 HTTP/1.1的“persistent”。两者的差异在于前者默认关闭,后者默认开启。

  3. 管道化连接。通过共享的TCP连接发起并发的HTTP请求。可以同时发出多个请求,避免了请求时的队头阻塞。

  4. 复用连接。交替传送请求和响应报文。

四次握手的关闭连接

TCP连接是双向的,服务器和客户端都存在输入和输出的信道。关闭连接的输出信道总是很安全的,关闭连接的输入信道存在很大的隐患,如果对方还有数据没有发送完,再次发送时会会送“连接被对端重置”的报文,此时操作系统会将其视为严重的错误,删除对端还未读取的所有缓存数据。

HTTP缓存

缓存是数据传输中不可缺少的一环,优点如下:

  • 减少了冗余的数据传输
  • 缓解了网络瓶颈的问题
  • 降低了对原始服务器的要求
  • 降低了距离时延

对于HTTP中的缓存,一般发生在客户端发起请求,缓存中的内容没有变化时,服务器会以一个304 Not Modified进行相应,这就是缓存命中。当然,如果收到404,说明对象被删除,缓存也会删除;收到200,说明服务器对象和缓存副本不同,服务器会重新发送一条带有内容的HTTP 200 OK相应。

对于缓存的评判标准有两个,文档命中率字节命中率。前者的提升对于降低整体延迟很有好处,后者对于节省带宽很有利。

缓存的处理步骤
  1. 接收—缓存从网络中读取抵达的请求报文
  2. 解析—缓存对报文进行解析,提取出URL和各种首部
  3. 查询—缓存查看是否有本地副本,没有就获取一份副本
  4. 新鲜度检测—缓存查看已缓存的副本是否足够新鲜,如果不是,询问服务器是否有任何更新
  5. 创建响应—缓存会用新的首部和已缓存的主体构建一条响应报文
  6. 发送—缓存通过网络将响应发回客户端
  7. 日志—缓存可选地创建一个日志系统条目来描述这个事务

对于缓存的数据,首先查看文档是否过期

  • cache control(定义了文档的最大使用期,也就是从第一次生成文档到文档不再新鲜无法使用为止)
  • expires(指定一个绝对的过期日期,存在时钟不同步的问题)首部可以查看是否过期。

这里存在一个问题,cache control和expires谁的优先级高。

应当是先看cache control 再看expires ,expires的结论可以覆盖cache control

但是过期了也不能说明该 j 缓存一定无效,此时需要进行服务器再验证 1.如果内容变化,缓存会获取新的副本存储在就文档的位置发送给客户端 2.如果内容不变,缓存会获取新的首部,包括一个新的过期日期,更新首部。

  • if modified since <last modified date>如指定日期之后文档被修改,它的条件就为真,新文档会返回缓存,同时返回新的指定日期,返回200;如果为假,返回304,同时返回需要修改的部分值,比如指定日期。

  • if none match <tags>(上一种方法的缺陷很明显,那就是date,世界各地都存在时区,数据的传世也存在时延,那么这就是不准确的,因此HTTP重新提出了一种称为“版本标识符”的实体标签–ETag)。这里存的是已经存在的内容版本,可以看这个例子就明了了

    1
    2
    3
    
    if none match : "v2.6" "v2.4"
    ETag : "v2.6" // 304
    ETag : "v3.0" // 200
    

至于常说的强缓存和协商缓存,前者指的是判断缓存是否过期,后者用于服务器再次验证。

HTTP版本
HTTP/0.9

只有GET方法,没有请求头,服务器只返回HTML

HTTP/1.0

引入请求头和响应头,支持多种请求方法和状态码,依然是短连接

HTTP/1.1

开始支持长连接;

容易引申问题:HTTP的Keep alive和TCP的keep alive,前者指支持长连接,后者为保活机制

管道网络传输:客户端可以同时发送多个请求,解决了请求的队头阻塞,但是服务端依然只能按顺序接收,依旧存在阻塞。

队头阻塞:顺序发送的请求序列中的某个请求阻塞后,后面的请求也会一并被阻塞。

HTTP/2.0
  • stream并发:引出stream概念,多个stream复用一条TCP连接,针对不同HTTP用独一无二的id区分,不同的stream可以乱序发送,因此可以并行交错的发送请求和响应。解决了请求和响应的队头阻塞。

但是存在传输层的队头阻塞,传输时要保证内核中的数据是顺序的,只有前1个数据到达,后面的才会到达缓冲区,因此也会阻塞。

  • 增加HPack对头部压缩。(静态字典,动态字典,Huffman编码)

  • 增加TLS 1.2+。

缺点:

队头阻塞 TCP和TLS握手时的延迟 网络迁移需要重新连接

HTTP/3.0

HTTP/3 把 HTTP 下层的 TCP 协议改成了基于 QUIC 的 UDP

特点:

  • 零RTT连接建立
  • 无队头阻塞
  • 连接迁移
  • 向前纠错机制
用户识别机制
承载用户信息HTTP首部
  • From 用户的Email地址
  • User Agent 用户的浏览器软件
  • Referer 用户来源页面的URL

然而这三者都不能建立可靠的的识别。

客户端IP地址
  • ip地址只能区分机器,不能区分不同用户
  • 用户每次登录时,ip地址会发生变化
  • Web服务可能只会看见共享的(NAT)防火墙地址或者代理服务器的ip地址,并不能看见真正的地址
用户登录

HTTP中的www-Authenticate首部和Authorization首部向Web站点传送用户的相关信息。

用户输入用户名和密码时,浏览器会重复原来的请求,添加Authorization作为身份的标识,在之后的每次请求,浏览器都会自动发起相应的用户名和密码,这样就可以在整个会话期间维持用户的身份。

胖URL

在URL中添加了一些信息,将Web服务器上若干个HTTP事务捆绑成一个会话或者访问,首次访问时生成唯一ID,此后每次浏览该站点时都会采用胖URL进行识别。

cookie的基本思想在于让浏览器积累一组服务器特有的信息,每次访问服务器时提供这些信息。cookie规范的正式名称为HTTP状态管理机制。下面这两种唯一的区别在于他们的过期时间。

  • 会话cookie。只会持续到用户退出浏览器为止自动被破坏。
  • 持久cookie。有过期日期,会在硬盘上存储到哪个日期为止。

用户首次访问Web站点时,服务器发出中的相应中带有set cookie,这也是对用户独有的标识码,浏览器也会记住这个cookie存储在浏览器的cookie数据库中,当用户返回同一站点时能够自动识别。

cookie版本0

主要由set cookie响应首部,cookie请求头部以及用于控制cookie的字段构成。

1
2
3
4
set cookie:
NAME=VALUE(强制) Expires(可选) Domain(可选) Path(可选) Secure(可选,SSL)
Cookie: 
session-id=0021145271-8271212; session-id-time=2881222899
cookie版本1 RFC 2965
  • 能够与版本0相互操作
  • 增加解释性文本,对目的进行解释
  • 浏览器退出时可以将cookie强制销毁
  • 用相对时间而不是绝对时间标识cookie的过期日期
  • 控制cookie除了域和路径增加了URL端口号
  • 增加了版本号

cookie:在客户端记录信息确定用户身份,是服务端发送存储在本地用户浏览器的小型文本文件。

session:在服务端记录信息确定用户身份。用于维护用户登录状态,存储用户临时数据,上下文信息等。会话标识符,记录当时的会话活动,时间等。

认证

基本认证只会对用户名和密码进行一层的Base64编码,但是这个时很容易解码 的,所以基本也可以等同于明文运输,安全性极低。

HTTPS

HTTPS = HTTP + SSL/TLS(位于HTTP层和TCP层之间)

  • 对称加密:每对发送者和接收者之间存在共享的保密密钥。
  • 非对称加密:每个发送者或者接收者都存在公钥和私钥,公钥加密,私钥解密

一般会采用非对称的公开密钥加密技术建立安全通信,再利用这条安全的通道发送临时的随机对称密钥对其余的数据进行加密。

另外:

数字签名用于判定谁编写的报文,同时证明报文未被篡改。(原理依旧是非对称加密)

数字证书,由官方的“证书颁发机构”以数字方式签发的。

HTTPS连接
  1. 客户端建立到服务器端口443的TCP连接
  2. SSL安全参数握手(交换协议版本号,选择密码,身份认证(CA签发的证书),生成临时的会话密钥加密信道)
  3. 客户端SSL上发送HTTP请求/TCP上发送已加密的请求
  4. 服务端SSL上发送HTTP响应/TCP上发送已加密的响应
  5. SSL关闭通知
  6. TCP关闭通知
参考资料

很高兴你能看完我的文章,因为近期在找实习,所以重新看起了曾经学过的知识,沟通了很多,简历也投出去了一部分,但是杳无音讯,多少有点落寞了。

重点回归,看八股的话,计网最为出名的就是小林coding的图解网络,写的确实好,但总感觉少了什么,这几天看了书之后明悟了很多,八股只能作为最后突击的材料,终究比不上自己去看经典书籍效果要好。我写的笔记也终究只是我个人总结的想法。

推荐可以看看这本书《HTTP权威指南》,写的很好,提前也可以看看小林的图解网络,带着面试可能会问的问题读,效果会更好。

缺点在于比较新版本的HTTP没有讲清楚,比如HTTP2.0,3.0几乎没怎么提到,或者跟RPC相关的之类的。以后再补充。

1.图解网络 - 小林coding

2.书籍《HTTP权威指南》