最近面试咋常问HTTP

推荐一下极客时间的《透视HTTP协议》,记录专栏中一些比较重要的点。若有侵权,请联系我。javascript

开篇词

To Be a HTTP Hero

破冰篇

时势与英雄:HTTP的前世此生

讲解了HTTP发展的趋势 从HTTP 0.9到HTTP1.0(不做为正式使用)到HTTP1.1 (如今主流)到HTTP2 (2014产生)到HTTP3(QUIC协议推进发展) HTTP2和HTTP3主要是由谷歌需求推进协议发展。css

HTTP0.9

  1. 采用纯文本形式
  2. 只容许使用GET获取资源,得到后就断开链接

HTTP1.0

  1. 增长了 HEAD、POST 等新方法;
  2. 增长了响应状态码,标记可能的错误缘由;
  3. 引入了协议版本号概念;
  4. 引入了 HTTP Header(头部)的概念,让 HTTP 处理请求和响应更加灵活;
  5. 传输的数据再也不仅限于文本。

HTTP1.1

  1. 增长了 PUT、DELETE 等新的方法;
  2. 增长了缓存管理和控制;
  3. 明确了链接管理,容许持久链接;
  4. 容许响应数据分块(chunked),利于传输大文件;
  5. 强制要求 Host 头,让互联网主机托管成为可能。

缓存管理和控制:当浏览器得到资源后,服务器回传资源有效时间,浏览器将参数放在Cache-Control中下次请求时判断缓存是否过时再次请求html

HTTP2

  1. 二进制协议,再也不是纯文本;
  2. 可发起多个请求,废弃了 1.1 里的管道;
  3. 使用专用算法压缩头部,减小数据传输量;
  4. 容许服务器主动向客户端推送数据;
  5. 加强了安全性,“事实上”要求加密通讯。

HTTP3

HTTP是什么?HTTP又不是什么?

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

HTTP世界全览(上):与HTTP相关的各类概念

image-20200424162001087

  1. 互联网上绝大部分资源都使用 HTTP 协议传输;
  2. 浏览器是 HTTP 协议里的请求方,即 User Agent;
  3. 服务器是 HTTP 协议里的应答方,经常使用的有 Apache 和 Nginx;
  4. CDN 位于浏览器和服务器之间,主要起到缓存加速的做用;
  5. 爬虫是另外一类 User Agent,是自动访问网络资源的程序。

HTTP世界全览(下):与HTTP相关的各类协议

image-20200424162946245

代理的做用

  1. 负载均衡:把访问请求均匀分散到多台机器,实现访问集群化;
  2. 内容缓存:暂存上下行的数据,减轻后端的压力;
  3. 安全防御:隐匿 IP, 使用 WAF 等工具抵御网络攻击,保护被代理的机器;
  4. 数据处理:提供压缩、加密等额外的功能。

常说的“四层”和“七层”究竟是什么?“五层”“六层”哪去了?

TCP是有状态的协议,发送数据前双方必须创建链接,由此能够保证传输字节流 是连续的并且没有重复。UDP是没有状态的协议,发送前不须要创建链接。UDP发送的数据包是无序的,且乱序收的。算法

CDN处于应用层 (一开始觉得处于网络层,果真对于请求处理层数越少越好)json

域名里有哪些门道

  1. 域名使用字符串来代替 IP 地址,方便用户记忆,本质上一个名字空间系统;
  2. DNS 就像是咱们现实世界里的电话本、查号台,统管着互联网世界里的全部网站,是一 个“超级大管家”;
  3. DNS 是一个树状的分布式查询系统,但为了提升查询效率,外围有多级的缓存;
  4. 使用 DNS 能够实现基于域名的负载均衡,既能够在内网,也能够在外网。

DNS域名解析的过程能够分别为本地host文件-> 本地域名服务器->根域名服务器->权威域名服务器后端

外围有多级缓存为大公司为了加速域名解析,会建立本身的DNS域名服务器,非权威域名服务器。做为用户DNS查询的代理,代替用户访问核心DNS。如同谷歌建立的8.8.8.8免费公共域名服务器。浏览器

本身动手,搭建HTTP实验环境

配置实验环境 ,同时安装了wireshak以及openresty缓存

基础篇

键入网址再按下回车,后面究竟发生了什么?

再简要叙述一下此次最简单的浏览器 HTTP 请求过程:安全

  1. 浏览器从地址栏的输入中得到服务器的 IP 地址和端口号;
  2. 浏览器用 TCP 的三次握手与服务器创建链接;
  3. 浏览器向服务器发送拼好的报文;
  4. 服务器收到报文后处理请求,一样拼好报文再发给浏览器;
  5. 浏览器解析报文,渲染输出页面。

image-20200424221950118

HTTP报文是什么样子的?

HTTP协议主要由如下三部分构成

  1. 起始行
  2. 头部字段集合
  3. 消息正文

image-20200425092339944

HTTP协议再细分能够分为 请求以及响应

请求行包括

  • 请求方法
  • 请求目标
  • HTTP协议版本号

这三个部分一般用空格来进行隔开,最后用CRLF来表示结束

状态行包括

  • HTTP协议版本
  • 状态码
  • 缘由 (如ok等)

image-20200425092834693

头部字段主要分为四大类

  1. 通用字段:在请求头和响应头里均可以出现;
  2. 请求字段:仅能出如今请求头里,进一步说明请求信息或者额外的附加条件;
  3. 响应字段:仅能出如今响应头里,补充说明响应报文的信息;
  4. 实体字段:它实际上属于通用字段,但专门描述 body 的额外信息。

请求字段:

Host字段:告诉服务器这个请求应该由哪一个主机来处理

User-Agent字段:告诉服务器请求的客户端信息

通用字段:

Data字段:客户端可使用这个时间再搭配其余字段决定缓存策略

响应字段:

Server字段:告诉客户端 响应服务器信息(也有部分网站不用透露信息)

实体字段:

content-length:表示响应体中报文body的长度

总结

  1. HTTP 报文结构就像是“大头儿子”,由“起始行 + 头部 + 空行 + 实体”组成,简单地说就是“header+body”;
  2. HTTP 报文能够没有 body,但必需要有 header,并且 header 后也必需要有空行,形象地说就是“大头”必需要带着“脖子”;
  3. 请求头由“请求行 + 头部字段”构成,响应头由“状态行 + 头部字段”构成;
  4. 请求行有三部分:请求方法,请求目标和版本号;
  5. 状态行也有三部分:版本号,状态码和缘由字符串;
  6. 头部字段是 key-value 的形式,用“:”分隔,不区分大小写,顺序任意,除了规定的标准头,也能够任意添加自定义字段,实现功能扩展;
  7. HTTP/1.1 里惟一要求必须提供的头字段是 Host,它必须出如今请求头里,标记虚拟主机名。

应该如何理解请求方法?

HTTP/1.1 规定了八种方法

  1. GET:获取资源,能够理解为读取或者下载数据;
  2. HEAD:获取资源的元信息;
  3. POST:向资源提交数据,至关于写入或上传数据;
  4. PUT:相似 POST;
  5. DELETE:删除资源;
  6. CONNECT:创建特殊的链接隧道;
  7. OPTIONS:列出可对资源实行的方法;
  8. TRACE:追踪请求 - 响应的传输路径。

GET POST DELETE PUT 不用过多介绍

HEAD

HEAD方法与 GET 方法相似,也是请求从服务器获取资源,服务器的处理机制也是同样的,但服务器不会返回请求的实体数据,只会传回响应头,也就是资源的“元信息”。

HEAD 方法能够看作是 GET 方法的一个“简化版”或者“轻量版”。由于它的响应头与 GET 彻底相同,因此能够用在不少并不真正须要资源的场合,避免传输 body 数据的浪费。

安全与幂等

对于安全性来讲GET和HEAD是安全的,不会修改计算机的资源。剩下三种会修改或者删除计算机的资源因此不是安全的。

对于幂等性来讲GET和HEAD是幂等的。同时PUT DELETE方法也是幂等的,屡次修改一条记录最后的结果也是一条,而POST则会修改数据的个数 不是幂等的。

总结:

  1. 请求方法是客户端发出的、要求服务器执行的、对资源的一种操做;
  2. 请求方法是对服务器的“指示”,真正应如何处理由服务器来决定;
  3. 最经常使用的请求方法是 GET 和 POST,分别是获取数据和发送数据;
  4. HEAD 方法是轻量级的 GET,用来获取资源的元信息;
  5. PUT 基本上是 POST 的同义词,多用于更新数据;
  6. “安全”与“幂等”是描述请求方法的两个重要属性,具备理论指导意义,能够帮助咱们设计系统。

你能写出正确的网址吗?

URI,也就是统一资源标识符Uniform Resource Identifier)

URL——统一资源定位符Uniform Resource Locator)

URL 实在是太普及了,因此经常把这二者简单地视为相等。

URL组成的基本格式

image-20200425141632553

浏览器会根据cheme使用默认的端口号 (HTTP 80 端口,HTTPS 443端口)

总结

  1. URI 是用来惟一标记服务器上资源的一个字符串,一般也称为 URL;
  2. URI 一般由 scheme、host:port、path 和 query 四个部分组成,有的能够省略;
  3. scheme 叫“方案名”或者“协议名”,表示资源应该使用哪一种协议来访问;
  4. “host:port”表示资源所在的主机名和端口号;
  5. path 标记资源所在的位置;
  6. query 表示对资源附加的额外要求;
  7. 在 URI 里对“@&/”等特殊字符和汉字必需要作编码,不然服务器收到 HTTP 报文后会没法正确处理。

响应状态码该怎么用?

状态码的分类为

  • 1××:提示信息,表示目前是协议处理的中间状态,还须要后续的操做;
  • 2××:成功,报文已经收到并被正确处理;
  • 3××:重定向,资源位置发生变更,须要客户端从新发送请求;
  • 4××:客户端错误,请求报文有误,服务器没法处理;
  • 5××:服务器错误,服务器在处理请求时内部发生了错误。

1××

1××类状态码属于提示信息,是协议处理的中间状态,实际可以用到的时候不多。

2××

2××类状态码表示服务器收到并成功处理了客户端的请求,这也是客户端最愿意看到的状态码。

200 OK”是最多见的成功状态码,表示一切正常,服务器如客户端所指望的那样返回了处理结果,若是是非 HEAD 请求,一般在响应头后都会有 body 数据。

204 No Content”是另外一个很常见的成功状态码,它的含义与“200 OK”基本相同,但响应头后没有 body 数据。因此对于 Web 服务器来讲,正确地区分 200 和 204 是很必要的。

206 Partial Content”是 HTTP 分块下载或断点续传的基础,在客户端发送“范围请求”、要求获取资源的部分数据时出现,它与 200 同样,也是服务器成功处理了请求,但 body 里的数据不是资源的所有,而是其中的一部分。

3××

3××类状态码表示客户端请求的资源发生了变更,客户端必须用新的 URI 从新发送请求获取资源,也就是一般所说的“重定向”,包括著名的 30一、302 跳转。

301 Moved Permanently”俗称“永久重定向”,含义是这次请求的资源已经不存在了,须要改用改用新的 URI 再次访问。

与它相似的是“302 Found”,曾经的描述短语是“Moved Temporarily”,俗称“临时重定向”,意思是请求的资源还在,但须要暂时用另外一个 URI 来访问。

4××

4××类状态码表示客户端发送的请求报文有误,服务器没法处理,它就是真正的“错误码”含义了。

400 Bad Request”是一个通用的错误码,表示请求报文有错误,但具体是数据格式错误、缺乏请求头仍是 URI 超长它没有明确说,只是一个笼统的错误,

403 Forbidden”实际上不是客户端的请求出错,而是表示服务器禁止访问资源。缘由可能多种多样,例如信息敏感、法律禁止等,若是服务器友好一点

404 Not Found”多是咱们最常看见也是最不肯意看到的一个状态码,它的原意是资源在本服务器上未找到

5××

5××类状态码表示客户端请求报文正确,但服务器在处理时内部发生了错误,没法返回应有的响应数据,是服务器端的“错误码”。

500 Internal Server Error”与 400 相似,也是一个通用的错误码

501 Not Implemented”表示客户端请求的功能还不支持

502 Bad Gateway”一般是服务器做为网关或者代理时返回的错误码

503 Service Unavailable”表示服务器当前很忙,暂时没法响应服务,咱们上网时有时候遇到的“网络服务正忙,请稍后重试”的提示信息就是状态码 503

总结

  1. 状态码在响应报文里表示了服务器对请求的处理结果;
  2. 状态码后的缘由短语是简单的文字描述,能够自定义;
  3. 状态码是十进制的三位数,分为五类,从 100 到 599;
  4. 2××类状态码表示成功,经常使用的有 200、20四、206;
  5. 3××类状态码表示重定向,经常使用的有 30一、30二、304;
  6. 4××类状态码表示客户端错误,经常使用的有 400、40三、404;
  7. 5××类状态码表示服务器错误,经常使用的有 500、50一、50二、503。

HTTP有哪些特色?

总结

  1. HTTP 是灵活可扩展的,能够任意添加头字段实现任意功能;
  2. HTTP 是可靠传输协议,基于 TCP/IP 协议“尽可能”保证数据的送达;
  3. HTTP 是应用层协议,比 FTP、SSH 等更通用功能更多,可以传输任意数据;
  4. HTTP 使用了请求 - 应答模式,客户端主动发起请求,服务器被动回复请求;
  5. HTTP 本质上是无状态的,每一个请求都是互相独立、毫无关联的,协议不要求客户端或服务器记录请求相关的信息。

HTTP虽然是可靠的传输协议但不保证传输的时候是彻底有效的,想要彻底可靠,须要使用中间件消息队列等。

HTTP有哪些优势?又有哪些缺点?

总结

  1. HTTP 最大的优势是简单、灵活和易于扩展;
  2. HTTP 拥有成熟的软硬件环境,应用的很是普遍,是互联网的基础设施;
  3. HTTP 是无状态的,能够轻松实现集群化,扩展性能,但有时也须要用 Cookie 技术来实现“有状态”;
  4. HTTP 是明文传输,数据彻底肉眼可见,可以方便地研究分析,但也容易被窃听;
  5. HTTP 是不安全的,没法验证通讯双方的身份,也不能判断报文是否被窜改;
  6. HTTP 的性能不算差,但不彻底适应如今的互联网,还有很大的提高空间。

进阶篇

海纳百川:HTTP的实体数据(干货)

数据类型和压缩

当请求返回的时候,TCP和IP任务已经完成可是HTTP须要解析出响应文件的类型。同时HTTP文件内容在传输时候常常会有压缩。所以产生数据类型和压缩类型的需求。

HTTP支持压缩类型有:

  1. gzip:GNU zip 压缩格式,也是互联网上最流行的压缩格式;
  2. deflate:zlib(deflate)压缩格式,流行程度仅次于 gzip;
  3. br:一种专门为 HTTP 优化的新压缩算法(Brotli)。

HTTP常见数据类型有:

  1. text:即文本格式的可读数据,咱们最熟悉的应该就是 text/html 了,表示超文本文档,此外还有纯文本 text/plain、样式表 text/css 等。
  2. image:即图像文件,有 image/gif、image/jpeg、image/png 等。
  3. audio/video:音频和视频数据,例如 audio/mpeg、video/mp4 等。
  4. application:数据格式不固定,多是文本也多是二进制,必须由上层应用程序来解释。常见的有 application/json,application/javascript、application/pdf 等,另外,若是实在是不知道数据是什么类型,像刚才说的“黑盒”,就会是 application/octet-stream,即不透明的二进制数据。

HTTP 协议为此定义了两个 Accept 请求头字段和两个 Content 实体头字段,用于客户端和服务器进行“内容协商”。也就是说,客户端用 Accept 头告诉服务器但愿接收什么样的数据,而服务器用 Content 头告诉客户端实际发送了什么样的数据。

image-20200425160429455

语言类型与编码

为了解决浏览器可以解析出正确的语言。为此引入了语言类型和编码。

Accept-language:指定了用户使用想要使用的语言类型 (可有多个参数)

Accept-Language: zh-CN, zh, en

Content-Language:返回浏览器的语言类型

Content-Language: zh-CN

字符集在 HTTP 里使用的请求头字段是Accept-Charset,但响应头里却没有对应的 Content-Charset,而是在Content-Type字段的数据类型后面用“charset=xxx”来表示,这点须要特别注意。

image-20200425161104951

总结

image-20200425161221854

  1. 数据类型表示实体数据的内容是什么,使用的是 MIME type,相关的头字段是 Accept 和 Content-Type;
  2. 数据编码表示实体数据的压缩方式,相关的头字段是 Accept-Encoding 和 Content-Encoding;
  3. 语言类型表示实体数据的天然语言,相关的头字段是 Accept-Language 和 Content-Language;
  4. 字符集表示实体数据的编码方式,相关的头字段是 Accept-Charset 和 Content-Type;
  5. 客户端须要在请求头里使用 Accept 等头字段与服务器进行“内容协商”,要求服务器返回最合适的数据;
  6. Accept 等头字段能够用“,”顺序列出多个可能的选项,还能够用“;q=”参数来精确指定权重。

HTTP传输大文件的方法

主要方法有两种,压缩以及分块传输

压缩的三种算法中gzip压缩率能够达到百分之60,而br算法对于HTML文件压缩效率在gzip基础上还能够提高百分之20。

分块传输(重点)

若使用分块传输那么响应报文会添加Transfer-Encoding以及Content-length。“Transfer-Encoding: chunked”和“Content-Length”这两个字段是互斥的,也就是说响应报文里这两个字段不能同时出现,一个响应报文的传输要么是长度已知,要么是长度未知(chunked)。

范围请求

HTTP 协议为了知足视频跳点观看的需求,提出了“范围请求”(range requests)的概念,范围请求不是 Web 服务器必备的功能,能够实现也能够不实现,因此服务器必须在响应头里使用字段“Accept-Ranges: bytes”明确告知客户端:“我是支持范围请求的”。

排队也要讲效率:HTTP的链接管理

主要内容短链接 长链接 队头阻塞

短链接

短链接对应版本为HTTP0.9 指使用HTTP进行通讯时,二者每次传送数据都要创建TCP链接,短链接的缺点严重制约了服务器的服务能力。

长链接

对于短链接的缺陷,HTTP1.1提出屡次请求只需创建一次TCP链接,减小服务器的消耗。使用的字段是Connection,值是“keep-alive”。长时间的空闲链接也会占据服务器的资源,因此长链接也须要在适当的时间关闭。一般有两种方式来在适当时间关闭请求,在必定请求后关闭链接 在设定空闲时间内无请求关闭链接

队头阻塞

队头阻塞主要是由于网络模型为“请求-应答”模型。前面的未响应请求对阻塞后方请求。对于HTTP来讲可使用 并发链接来解决,对于同一个域名创建多个链接。(多个链接会加重服务器资源消耗被服务器当成攻击拒绝链接)

总结

  1. 早期的 HTTP 协议使用短链接,收到响应后就当即关闭链接,效率很低;
  2. HTTP/1.1 默认启用长链接,在一个链接上收发多个请求响应,提升了传输效率;
  3. 服务器会发送“Connection: keep-alive”字段表示启用了长链接;
  4. 报文头里若是有“Connection: close”就意味着长链接即将关闭;
  5. 过多的长链接会占用服务器资源,因此服务器会用一些策略有选择地关闭长链接;
  6. “队头阻塞”问题会致使性能降低,能够用“并发链接”和“域名分片”技术缓解。

HTTP的重定向和跳转(干货)

在网页中由用户主动发起请求的跳转称为 主动跳转,用户没法控制的称为 被动跳转 ,同时也被称为 重定向

image-20200425212750598

这里出现了一个新的头字段“Location: /index.html”,它就是 301/302 重定向跳转的秘密所在。

Location”字段属于响应字段,必须出如今响应报文里。但只有配合 301/302 状态码才有意义,它标记了服务器要求重定向的 URI

对于站内的连接可使用 相对URl 站外的连接必须使用 绝对URI

301 以及 302

在重定向状态码中重用的分别为301以及302。 301称为“永久重定向” 302称为“临时重定向” 。

永久重定向指当运行服务器进行更新以及修改,资源位置彻底改变时使用

临时重定向指当系统进行维修或者在服务降级时进行调用

对于浏览器来讲 永久和临时的区别在于对于永久性的重定向,浏览器下次该地址时会进行优化。对于临时,浏览器在下次访问的时候只会认为该地址暂时没法使用,下次请求时仍会使用原来URL。

HTTP的Cookie机制(干货)

HTTP增长Cookie是为了解决HTTP是无状态链接的问题。为此HTTP中增长响应头字段Set-Cookie和请求头字段Cookie。Cookie是存储在客户端也就是浏览器中,只在本浏览器内生效。

在Cookie中也能够设置其余cookie属性如cookie过时时间,可使用 Expires 和 Max-Age 两个属性来设置。

Expires为绝对过时时间,为某个绝对时间点。 Max-Age为相对过时时间在某个时间点上延长必定时间。浏览器会优先使用 Max-Age做为过时的时间。

对于cookie的安全性,可使用另外一个属性“SameSite”防范“跨站请求伪造”(XSRF)攻击。属性“HttpOnly”会告诉浏览器,此 Cookie 只能经过浏览器 HTTP 协议传输,禁止其余方式访问。

总结

  1. Cookie 是服务器委托浏览器存储的一些数据,让服务器有了“记忆能力”;
  2. 响应报文使用 Set-Cookie 字段发送“key=value”形式的 Cookie 值;
  3. 请求报文里用 Cookie 字段发送多个 Cookie 值;
  4. 为了保护 Cookie,还要给它设置有效期、做用域等属性,经常使用的有 Max-Age、Expires、Domain、HttpOnly 等;
  5. Cookie 最基本的用途是身份识别,实现有状态的会话事务。

生鲜速递:HTTP的缓存控制(干货)

这篇文章感受比较干货,建议看原文

服务器有缓存,浏览器也有缓存。缓存有什么做用,又是经过哪几个字段来保证有效,就是这篇文章的全部内容。

当使用浏览器的前进或者后退的时候,这时使用了缓存。在缓存期内浏览器有时仍会请求服务器获取资源,由于缓存的使用是服务器和浏览器协商的结果。

image-20200426101004521

缓存的字段有以下几个

  • max-age:缓存使用的最大有效时间,注意max-age为ttl(time to live)当服务器响应时开始计时;

  • no_store:不容许缓存,用于某些变化很是频繁的数据,例如秒杀页面;

  • no_cache:它的字面含义容易与 no_store 搞混,实际的意思并非不容许缓存,而是能够缓存,但在使用以前必需要去服务器验证是否过时,是否有最新的版本;

  • must-revalidate:又是一个和 no_cache 类似的词,它的意思是若是缓存不过时就能够继续使用,但过时了若是还想用就必须去服务器验证。

对于后两种验证缓存的类型,HTTP采用条件请求字段,将缓存的判断放在服务端进行处理,由此来避免两次请求占用网络带宽。

条件请求一共有 5 个头字段,咱们最经常使用的是“if-Modified-Since”和“If-None-Match”这两个。须要第一次的响应报文预先提供“Last-modified”和“ETag”,而后第二次请求时就能够带上缓存里的原值,验证资源是不是最新的。(看原文)

总结

  1. 缓存是优化系统性能的重要手段,HTTP 传输的每个环节中均可以有缓存;
  2. 服务器使用“Cache-Control”设置缓存策略,经常使用的是“max-age”,表示资源的有效期;
  3. 浏览器收到数据就会存入缓存,若是没过时就能够直接使用,过时就要去服务器验证是否仍然可用;
  4. 验证资源是否失效须要使用“条件请求”,经常使用的是“if-Modified-Since”和“If-None-Match”,收到 304 就能够复用缓存里的资源;
  5. 验证资源是否被修改的条件有两个:“Last-modified”和“ETag”,须要服务器预先在响应报文里设置,搭配条件请求使用;
  6. 浏览器也能够发送“Cache-Control”字段,使用“max-age=0”或“no_cache”刷新数据。

良心中间商:HTTP的代理服务

代理的主要做用:

  1. 负载均衡:将请求分发都不一样后端服务机器。
  2. 健康检查:使用“心跳”等机制监控后端服务器,发现有故障就及时“踢出”集群,保证服务高可用;
  3. 安全防御:保护被代理的后端服务器,限制 IP 地址或流量,抵御网络攻击和过载;
  4. 加密卸载:对外网使用 SSL/TLS 加密通讯认证,而在安全的内网不加密,消除加解密成本;
  5. 数据过滤:拦截上下行的数据,任意指定策略修改请求或者响应;
  6. 内容缓存:暂存、复用服务器响应。

代理相关头字段:

Via:标明代理的身份,追加代理用户的主机名或者域名。

image-20200426140852819

X-Forwarded-For:每通过一个代理节点就会在字段里追加一个信息。追加的是代理主机的IP。

X-Real-IP:记录客户端 IP 地址,没有中间的代理信息,至关因而“X-Forwarded-For”的简化版。

image-20200426141100741

从抓包里就能够清晰地看出代理与客户端、源服务器的通讯过程:

  1. 客户端 55061 先用三次握手链接到代理的 80 端口,而后发送 GET 请求;
  2. 代理不直接生产内容,因此就表明客户端,用 55063 端口链接到源服务器,也是三次握手;
  3. 代理成功链接源服务器后,发出了一个 HTTP/1.0 的 GET 请求;
  4. 由于 HTTP/1.0 默认是短链接,因此源服务器发送响应报文后当即用四次挥手关闭链接;
  5. 代理拿到响应报文后再发回给客户端,完成了一次代理服务。

总结:

  1. HTTP 代理就是客户端和服务器通讯链路中的一个中间环节,为两端提供“代理服务”;
  2. 代理处于中间层,为 HTTP 处理增长了更多的灵活性,能够实现负载均衡、安全防御、数据过滤等功能;
  3. 代理服务器须要使用字段“Via”标记本身的身份,多个代理会造成一个列表;
  4. 若是想要知道客户端的真实 IP 地址,可使用字段“X-Forwarded-For”和“X-Real-IP”;
  5. 专门的“代理协议”能够在不改动原始报文的状况下传递客户端的真实 IP。

HTTP的缓存代理

这篇我的认为是涨知识的一篇文章

总结

  1. 计算机领域里最经常使用的性能优化手段是“时空转换”,也就是“时间换空间”或者“空间换时间”,HTTP 缓存属于后者;
  2. 缓存代理是增长了缓存功能的代理服务,缓存源服务器的数据,分发给下游的客户端;
  3. “Cache-Control”字段也能够控制缓存代理,经常使用的有“private”“s-maxage”“no-transform”等,一样必须配合“Last-modified”“ETag”等字段才能使用;
  4. 缓存代理有时候也会带来负面影响,缓存不良数据,须要及时刷新或删除。

安全篇

HTTPS是什么?SSL/TLS又是什么?

由于 HTTPS 至关于“HTTP+SSL/TLS+TCP/IP”,其中的“HTTP”和“TCP/IP”咱们都已经明白了,只要再了解一下 SSL/TLS,HTTPS 也就可以轻松掌握。

SSL 的全称是“Secure Socket Layer”,由网景公司发明,当发展到 3.0 时被标准化,更名为 TLS,即“Transport Layer Security”,但因为历史的缘由仍是有不少人称之为 SSL/TLS,或者直接简称为 SSL。

SSL 使用了许多密码学最早进的研究成果,综合了对称加密、非对称加密、摘要算法、数字签名、数字证书等技术,可以在不安全的环境中为通讯的双方建立出一个秘密的、安全的传输通道,为 HTTP 套上一副坚固的盔甲。

由于HTTP明文传输的不安全因此在原先HTTP运行的TCP/IP层上面添加了一层TLS/SSL来确保安全性。

安全性主要包括如下四个方面

  • 机密性
  • 完整性
  • 身份认证
  • 不能否认

image-20200427140857905

SSL最初在1994年由网景公司提出,后在1999年更名为TSL。目前普遍使用的协议是TSL1.2。

TLS 由记录协议、握手协议、警告协议、变动密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术。

TLS 的密码套件命名很是规范,格式很固定。基本的形式是“密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法”

image-20200427141242196

“握手时使用 ECDHE 算法进行密钥交换,用 RSA 签名和身份认证,握手后的通讯使用 AES 对称算法,密钥长度 256 位,分组模式是 GCM,摘要算法 SHA384 用于消息认证和产生随机数。”

总结

  1. 由于 HTTP 是明文传输,因此不安全,容易被黑客窃听或窜改;
  2. 通讯安全必须同时具有机密性、完整性,身份认证和不能否认这四个特性;
  3. HTTPS 的语法、语义仍然是 HTTP,但把下层的协议由 TCP/IP 换成了 SSL/TLS;
  4. SSL/TLS 是信息安全领域中的权威标准,采用多种先进的加密技术保证通讯安全;
  5. OpenSSL 是著名的开源密码学工具包,是 SSL/TLS 的具体实现。

固若金汤的根本(上):对称加密与非对称加密

实现机密性最经常使用的手段是“加密”(encrypt),就是把消息用某种方式转换成谁也看不懂的乱码,只有掌握特殊“钥匙”的人才能再转换出原始文本。

这里的“钥匙”就叫作“密钥”(key),加密前的消息叫“明文”(plain text/clear text),加密后的乱码叫“密文”(cipher text),使用密钥还原明文的过程叫“解密”(decrypt),是加密的反操做,加密解密的操做过程就是“加密算法”。

加密能够分为两大类:对称加密和非对称加密

对称加密

“对称加密”很好理解,就是指加密和解密时使用的密钥都是同一个,是“对称”的。只要保证了密钥的安全,那整个通讯过程就能够说具备了机密性。

对称加密的算法主要由AES以及ChaCha20 。

加密分组模式

对称算法还有一个“分组模式”的概念,它可让算法用固定长度的密钥加密任意长度的明文,把小秘密(即密钥)转化为大秘密(即密文)。

非对称加密

对称加密看上去好像完美地实现了机密性,但其中有一个很大的问题:如何把密钥安全地传递给对方,术语叫“密钥交换”。

非对称加密的算法主要有RSA和ECC。

混合加密

因为非对称加密常用数学方法进行加密解密,因此计算时间较长。对称加密时间则比非对称加密速度快好几个量级。因此TSL使用混合加密。

在通讯刚开始的时候使用非对称算法,好比 RSA、ECDHE,首先解决密钥交换的问题。

而后用随机数产生对称算法使用的“会话密钥”(session key),再用公钥加密。由于会话密钥很短,一般只有 16 字节或 32 字节,因此慢一点也无所谓。

对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换,后续就再也不使用非对称加密,全都使用对称加密。

image-20200427143640443

总结

  1. 加密算法的核心思想是“把一个小秘密(密钥)转化为一个大秘密(密文消息)”,守住了小秘密,也就守住了大秘密;
  2. 对称加密只使用一个密钥,运算速度快,密钥必须保密,没法作到安全的密钥交换,经常使用的有 AES 和 ChaCha20;
  3. 非对称加密使用两个密钥:公钥和私钥,公钥能够任意分发而私钥保密,解决了密钥交换问题但速度慢,经常使用的有 RSA 和 ECC;
  4. 把对称加密和非对称加密结合起来就获得了“又好又快”的混合加密,也就是 TLS 里使用的加密方式。

固若金汤的根本(下):数字签名与证书

实现完整性的手段主要是摘要算法(Digest Algorithm),也就是常说的散列函数、哈希函数(Hash Function)。

摘要算法使得丝绝不同的内容产生的结果也是彻底不一样,TLS推荐使用的摘要算法主要是 SHA-2MD5以及SHA-1因为算法的安全性不足 ,在TLS中被禁用。

真正的完整性必需要创建在机密性之上,在混合加密系统里用会话密钥加密消息和摘要,这样黑客没法得知明文,也就没有办法动手脚了。

image-20200427145952129

数字签名

image-20200427175035683

非对称加密里的“私钥”,使用私钥再加上摘要算法,就可以实现“数字签名”,同时实现“身份认证”和“不能否认”。

数字签名的原理其实很简单,就是把公钥私钥的用法反过来,以前是公钥加密、私钥解密,如今是私钥加密、公钥解密。

但又由于非对称加密效率过低,因此私钥只加密原文的摘要,这样运算量就小的多,并且获得的数字签名也很小,方便保管和传输。

签名和公钥同样彻底公开,任何人均可以获取。但这个签名只有用私钥对应的公钥才能解开,拿到摘要后,再比对原文验证完整性,就能够像签署文件同样证实消息确实是你发的。

数字证书和 CA

咱们常说的CA(Certificate Authority,证书认证机构)。它就像网络世界里的公安局、教育部、公证中心,具备极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥没法伪造,是可信的。

CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证实公钥关联的各类信息,造成“数字证书”(Certificate)。

总结

  1. 摘要算法用来实现完整性,可以为数据生成独一无二的“指纹”,经常使用的算法是 SHA-2;
  2. 数字签名是私钥对摘要的加密,能够由公钥解密后验证,实现身份认证和不能否认;
  3. 公钥的分发须要使用数字证书,必须由 CA 的信任链来验证,不然就是不可信的;
  4. 做为信任链的源头 CA 有时也会不可信,解决办法有 CRL、OCSP,还有终止信任。

飞翔篇

时代之风(上):HTTP/2特性概览

头部压缩

因为报文请求头通常都会携带许多固定的头字段,而请求体的内容每每只有不多同时屡次重复的请求使得重复的头部字段被屡次发送,因此HTTP2开发出专门的压缩算法进行头部压缩,因为gzip算法会被”crime“攻击因此HTTP2开发了专门的“HPACK”算法,在客户端和服务器两端创建“字典”,用索引号表示重复的字符串,还釆用哈夫曼编码来压缩整数和字符串,能够达到 50%~90% 的高压缩率。

二进制格式

因为传统的纯文本形式会使用复杂的状态机,致使文本解析效率低。HTTP2采用二进制来优化,将原来的的“Header+Body”的消息“打散”为数个小片的二进制“帧”(Frame),用“HEADERS”帧存放头数据、“DATA”帧存放实体数据。

image-20200427181222491

虚拟的“流”

HTTP/2 为此定义了一个“”(Stream)的概念,它是二进制帧的双向传输序列,同一个消息往返的帧会分配一个惟一的流 ID。经过流ID来组装分散的二进制帧,由于“流”是虚拟的,实际上并不存在,因此 HTTP/2 就能够在一个 TCP 链接上用“”同时发送多个“碎片化”的消息,这就是常说的“多路复用”( Multiplexing)——多个往返通讯都复用一个链接来处理。

推送模式

HTTP/2 还在必定程度上改变了传统的“请求 - 应答”工做模式,服务器再也不是彻底被动地响应请求,也能够新建“流”主动向客户端发送消息。好比,在浏览器刚请求 HTML 的时候就提早把可能会用到的 JS、CSS 文件发给客户端,减小等待的延迟,这被称为“服务器推送”(Server Push,也叫 Cache Push)。

强化安全

互联网上一般所能见到的 HTTP/2 都是使用“https”协议名,跑在 TLS 上面。

为了区分“加密”和“明文”这两个不一样的版本,HTTP/2 协议定义了两个字符串标识符:“h2”表示加密的HTTP/2,“h2c”表示明文的 HTTP/2,多出的那个字母“c”的意思是“clear text”。

协议栈

image-20200427182025345

小结:

  1. HTTP 协议取消了小版本号,因此 HTTP/2 的正式名字不是 2.0;
  2. HTTP/2 在“语义”上兼容 HTTP/1,保留了请求方法、URI 等传统概念;
  3. HTTP/2 使用“HPACK”算法压缩头部信息,消除冗余数据节约带宽;
  4. HTTP/2 的消息再也不是“Header+Body”的形式,而是分散为多个二进制“帧”;
  5. HTTP/2 使用虚拟的“流”传输消息,解决了困扰多年的“队头阻塞”问题,同时实现了“多路复用”,提升链接的利用率;
  6. HTTP/2 也加强了安全性,要求至少是 TLS1.2,并且禁用了不少不安全的密码套件。

时代之风(下):HTTP/2内核剖析(干货)

链接前言

TLS 握手成功以后,客户端必需要发送一个“链接前言”(connection preface),用来确认创建 HTTP/2 链接。

HTTP2的链接前言使用的是“Magic”确保使用的HTTP2

头部压缩 :smiling_imp:

头部压缩算法使用的是HPACK算法。它是一个“有状态”的算法,须要客户端和服务器各自维护一份“索引表”,也能够说是“字典”(这有点相似 brotli),压缩和解压缩就是查表和更新表的操做。 具体的实现为将原先头部的字段改成伪头部形式为“:authority”,":method"等来跟原先头部进行区分。HTTP/2 就为一些最经常使用的头字段定义了一个只读的“静态表”(Static Table)。经过key——value的形式如 ":method":2来表示GET请求,在发送时候只要一个字节发送对应的索引2就能够。

image-20200428135524654

同时为了解决自定义字段找不到的问题,使用了动态表,跟在静态表的后面,在编码解码的时候随时更新。

image-20200428135614596

二进制帧

格式

image-20200428140249095

二进制帧头部占9个字节。 帧长度3个字节表示最大传输的大小为2^24 为16M,通常默认上限为2^14 为16Kb 帧类型,大体能够分红数据帧控制帧两类,HEADERS 帧和 DATA 帧属于数据帧,存放的是 HTTP 报文,而 SETTINGS、PING、PRIORITY 等则是用来管理流的控制帧。

标志位:能够保存 8 个标志,携带简单的控制信息。经常使用的标志位有END_HEADERS表示头数据结束,至关于 HTTP/1 里头后的空行(“\r\n”),END_STREAM表示单方向数据发送结束(即 EOS,End of Stream),至关于 HTTP/1 里 Chunked 分块结束标志(“0\r\n\r\n”)。

流标识符:是用来确保多个复用的一个重要标志,接收方使用它就能够从乱序的帧里识别出具备相同流 ID 的帧序列,按顺序组装起来就实现了虚拟的“流”。拥有32位,最多能够表示21亿个标志,不过通常发送端使用的单数,服务端使用双数。单边流标志在10亿个左右。

流与多路复用

流是二进制帧的双向传输序列 **在 HTTP/2 链接上,虽然帧是乱序收发的,但只要它们都拥有相同的流 ID,就都属于一个流,并且在这个流里帧不是无序的,而是有着严格的前后顺序。**http2解决了原先请求响应的队头阻塞问题,须要明白的是并无解决流内部的队头阻塞问题,由于HTTP2使用的还是TCP协议,HTTP3改变使用UDP。

流的特色:

  1. 流是可并发的,一个 HTTP/2 链接上能够同时发出多个流传输数据,也就是并发多请求,实现“多路复用”;
  2. 客户端和服务器均可以建立流,双方互不干扰;
  3. 流是双向的,一个流里面客户端和服务器均可以发送或接收数据帧,也就是一个“请求 - 应答”来回;
  4. 流之间没有固定关系,彼此独立,但流内部的帧是有严格顺序的;
  5. 流能够设置优先级,让服务器优先处理,好比先传 HTML/CSS,后传图片,优化用户体验;
  6. 流 ID 不能重用,只能顺序递增,客户端发起的 ID 是奇数,服务器端发起的 ID 是偶数;
  7. 在流上发送“RST_STREAM”帧能够随时终止流,取消接收或发送;
  8. 第 0 号流比较特殊,不能关闭,也不能发送数据帧,只能发送控制帧,用于流量控制。

image-20200428142358384

流状态转换

状态转换相似tcp的状态转换

image-20200428142827628

总结:

  1. HTTP/2 必须先发送一个“链接前言”字符串,而后才能创建正式链接;
  2. HTTP/2 废除了起始行,统一使用头字段,在两端维护字段“Key-Value”的索引表,使用“HPACK”算法压缩头部;
  3. HTTP/2 把报文切分为多种类型的二进制帧,报头里最重要的字段是流标识符,标记帧属于哪一个流;
  4. 流是 HTTP/2 虚拟的概念,是帧的双向传输序列,至关于 HTTP/1 里的一次“请求 - 应答”;
  5. 在一个 HTTP/2 链接上能够并发多个流,也就是多个“请求 - 响应”报文,这就是“多路复用”。

总结篇 探索篇 安全篇的部份内容没有记录 本身感受在实践中没有太多用到,或者是自身储备不足。下次再作记录。

相关文章
相关标签/搜索