推荐一下极客时间的《透视HTTP协议》,记录专栏中一些比较重要的点。若有侵权,请联系我。javascript
讲解了HTTP发展的趋势 从HTTP 0.9到HTTP1.0(不做为正式使用)到HTTP1.1 (如今主流)到HTTP2 (2014产生)到HTTP3(QUIC协议推进发展) HTTP2和HTTP3主要是由谷歌需求推进协议发展。css
缓存管理和控制:当浏览器得到资源后,服务器回传资源有效时间,浏览器将参数放在Cache-Control中下次请求时判断缓存是否过时再次请求html
HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。java
TCP是有状态的协议,发送数据前双方必须创建链接,由此能够保证传输字节流 是连续的并且没有重复。UDP是没有状态的协议,发送前不须要创建链接。UDP发送的数据包是无序的,且乱序收的。算法
CDN处于应用层 (一开始觉得处于网络层,果真对于请求处理层数越少越好)json
DNS域名解析的过程能够分别为本地host文件-> 本地域名服务器->根域名服务器->权威域名服务器后端
外围有多级缓存为大公司为了加速域名解析,会建立本身的DNS域名服务器,非权威域名服务器。做为用户DNS查询的代理,代替用户访问核心DNS。如同谷歌建立的8.8.8.8免费公共域名服务器。浏览器
配置实验环境 ,同时安装了wireshak以及openresty缓存
再简要叙述一下此次最简单的浏览器 HTTP 请求过程:安全
HTTP协议主要由如下三部分构成
HTTP协议再细分能够分为 请求以及响应
请求行包括
这三个部分一般用空格来进行隔开,最后用CRLF来表示结束
状态行包括
头部字段主要分为四大类
请求字段:
Host字段:告诉服务器这个请求应该由哪一个主机来处理
User-Agent字段:告诉服务器请求的客户端信息
通用字段:
Data字段:客户端可使用这个时间再搭配其余字段决定缓存策略
响应字段:
Server字段:告诉客户端 响应服务器信息(也有部分网站不用透露信息)
实体字段:
content-length:表示响应体中报文body的长度
总结
HTTP/1.1 规定了八种方法
GET POST DELETE PUT 不用过多介绍
HEAD
HEAD方法与 GET 方法相似,也是请求从服务器获取资源,服务器的处理机制也是同样的,但服务器不会返回请求的实体数据,只会传回响应头,也就是资源的“元信息”。
HEAD 方法能够看作是 GET 方法的一个“简化版”或者“轻量版”。由于它的响应头与 GET 彻底相同,因此能够用在不少并不真正须要资源的场合,避免传输 body 数据的浪费。
安全与幂等
对于安全性来讲GET和HEAD是安全的,不会修改计算机的资源。剩下三种会修改或者删除计算机的资源因此不是安全的。
对于幂等性来讲GET和HEAD是幂等的。同时PUT DELETE方法也是幂等的,屡次修改一条记录最后的结果也是一条,而POST则会修改数据的个数 不是幂等的。
总结:
URI,也就是统一资源标识符(Uniform Resource Identifier)
URL——统一资源定位符(Uniform Resource Locator)
URL 实在是太普及了,因此经常把这二者简单地视为相等。
URL组成的基本格式
浏览器会根据cheme使用默认的端口号 (HTTP 80 端口,HTTPS 443端口)
总结
状态码的分类为
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
总结
总结
HTTP虽然是可靠的传输协议但不保证传输的时候是彻底有效的,想要彻底可靠,须要使用中间件消息队列等。
总结
数据类型和压缩
当请求返回的时候,TCP和IP任务已经完成可是HTTP须要解析出响应文件的类型。同时HTTP文件内容在传输时候常常会有压缩。所以产生数据类型和压缩类型的需求。
HTTP支持压缩类型有:
HTTP常见数据类型有:
HTTP 协议为此定义了两个 Accept 请求头字段和两个 Content 实体头字段,用于客户端和服务器进行“内容协商”。也就是说,客户端用 Accept 头告诉服务器但愿接收什么样的数据,而服务器用 Content 头告诉客户端实际发送了什么样的数据。
为了解决浏览器可以解析出正确的语言。为此引入了语言类型和编码。
Accept-language:指定了用户使用想要使用的语言类型 (可有多个参数)
Accept-Language: zh-CN, zh, en
Content-Language:返回浏览器的语言类型
Content-Language: zh-CN
字符集在 HTTP 里使用的请求头字段是Accept-Charset,但响应头里却没有对应的 Content-Charset,而是在Content-Type字段的数据类型后面用“charset=xxx”来表示,这点须要特别注意。
总结
主要方法有两种,压缩以及分块传输
压缩的三种算法中gzip压缩率能够达到百分之60,而br算法对于HTML文件压缩效率在gzip基础上还能够提高百分之20。
分块传输(重点)
若使用分块传输那么响应报文会添加Transfer-Encoding以及Content-length。“Transfer-Encoding: chunked”和“Content-Length”这两个字段是互斥的,也就是说响应报文里这两个字段不能同时出现,一个响应报文的传输要么是长度已知,要么是长度未知(chunked)。
范围请求
HTTP 协议为了知足视频跳点观看的需求,提出了“范围请求”(range requests)的概念,范围请求不是 Web 服务器必备的功能,能够实现也能够不实现,因此服务器必须在响应头里使用字段“Accept-Ranges: bytes”明确告知客户端:“我是支持范围请求的”。
主要内容短链接 长链接 队头阻塞
短链接
短链接对应版本为HTTP0.9 指使用HTTP进行通讯时,二者每次传送数据都要创建TCP链接,短链接的缺点严重制约了服务器的服务能力。
长链接
对于短链接的缺陷,HTTP1.1提出屡次请求只需创建一次TCP链接,减小服务器的消耗。使用的字段是Connection,值是“keep-alive”。长时间的空闲链接也会占据服务器的资源,因此长链接也须要在适当的时间关闭。一般有两种方式来在适当时间关闭请求,在必定请求后关闭链接 在设定空闲时间内无请求关闭链接
队头阻塞
队头阻塞主要是由于网络模型为“请求-应答”模型。前面的未响应请求对阻塞后方请求。对于HTTP来讲可使用 并发链接来解决,对于同一个域名创建多个链接。(多个链接会加重服务器资源消耗被服务器当成攻击拒绝链接)
总结
在网页中由用户主动发起请求的跳转称为 主动跳转,用户没法控制的称为 被动跳转 ,同时也被称为 重定向
这里出现了一个新的头字段“Location: /index.html”,它就是 301/302 重定向跳转的秘密所在。
“Location”字段属于响应字段,必须出如今响应报文里。但只有配合 301/302 状态码才有意义,它标记了服务器要求重定向的 URI。
对于站内的连接可使用 相对URl 站外的连接必须使用 绝对URI
301 以及 302
在重定向状态码中重用的分别为301以及302。 301称为“永久重定向” 302称为“临时重定向” 。
永久重定向指当运行服务器进行更新以及修改,资源位置彻底改变时使用
临时重定向指当系统进行维修或者在服务降级时进行调用
对于浏览器来讲 永久和临时的区别在于对于永久性的重定向,浏览器下次该地址时会进行优化。对于临时,浏览器在下次访问的时候只会认为该地址暂时没法使用,下次请求时仍会使用原来URL。
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 协议传输,禁止其余方式访问。
总结
这篇文章感受比较干货,建议看原文
服务器有缓存,浏览器也有缓存。缓存有什么做用,又是经过哪几个字段来保证有效,就是这篇文章的全部内容。
当使用浏览器的前进或者后退的时候,这时使用了缓存。在缓存期内浏览器有时仍会请求服务器获取资源,由于缓存的使用是服务器和浏览器协商的结果。
缓存的字段有以下几个
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”,而后第二次请求时就能够带上缓存里的原值,验证资源是不是最新的。(看原文)
总结
代理的主要做用:
代理相关头字段:
Via:标明代理的身份,追加代理用户的主机名或者域名。
X-Forwarded-For:每通过一个代理节点就会在字段里追加一个信息。追加的是代理主机的IP。
X-Real-IP:记录客户端 IP 地址,没有中间的代理信息,至关因而“X-Forwarded-For”的简化版。
从抓包里就能够清晰地看出代理与客户端、源服务器的通讯过程:
总结:
这篇我的认为是涨知识的一篇文章
总结
由于 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来确保安全性。
安全性主要包括如下四个方面
SSL最初在1994年由网景公司提出,后在1999年更名为TSL。目前普遍使用的协议是TSL1.2。
TLS 由记录协议、握手协议、警告协议、变动密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术。
TLS 的密码套件命名很是规范,格式很固定。基本的形式是“密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法”
“握手时使用 ECDHE 算法进行密钥交换,用 RSA 签名和身份认证,握手后的通讯使用 AES 对称算法,密钥长度 256 位,分组模式是 GCM,摘要算法 SHA384 用于消息认证和产生随机数。”
总结
实现机密性最经常使用的手段是“加密”(encrypt),就是把消息用某种方式转换成谁也看不懂的乱码,只有掌握特殊“钥匙”的人才能再转换出原始文本。
这里的“钥匙”就叫作“密钥”(key),加密前的消息叫“明文”(plain text/clear text),加密后的乱码叫“密文”(cipher text),使用密钥还原明文的过程叫“解密”(decrypt),是加密的反操做,加密解密的操做过程就是“加密算法”。
加密能够分为两大类:对称加密和非对称加密。
对称加密
“对称加密”很好理解,就是指加密和解密时使用的密钥都是同一个,是“对称”的。只要保证了密钥的安全,那整个通讯过程就能够说具备了机密性。
对称加密的算法主要由AES以及ChaCha20 。
加密分组模式
对称算法还有一个“分组模式”的概念,它可让算法用固定长度的密钥加密任意长度的明文,把小秘密(即密钥)转化为大秘密(即密文)。
非对称加密
对称加密看上去好像完美地实现了机密性,但其中有一个很大的问题:如何把密钥安全地传递给对方,术语叫“密钥交换”。
非对称加密的算法主要有RSA和ECC。
混合加密
因为非对称加密常用数学方法进行加密解密,因此计算时间较长。对称加密时间则比非对称加密速度快好几个量级。因此TSL使用混合加密。
在通讯刚开始的时候使用非对称算法,好比 RSA、ECDHE,首先解决密钥交换的问题。
而后用随机数产生对称算法使用的“会话密钥”(session key),再用公钥加密。由于会话密钥很短,一般只有 16 字节或 32 字节,因此慢一点也无所谓。
对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换,后续就再也不使用非对称加密,全都使用对称加密。
总结
实现完整性的手段主要是摘要算法(Digest Algorithm),也就是常说的散列函数、哈希函数(Hash Function)。
摘要算法使得丝绝不同的内容产生的结果也是彻底不一样,TLS推荐使用的摘要算法主要是 SHA-2 , MD5以及SHA-1因为算法的安全性不足 ,在TLS中被禁用。
真正的完整性必需要创建在机密性之上,在混合加密系统里用会话密钥加密消息和摘要,这样黑客没法得知明文,也就没有办法动手脚了。
数字签名
非对称加密里的“私钥”,使用私钥再加上摘要算法,就可以实现“数字签名”,同时实现“身份认证”和“不能否认”。
数字签名的原理其实很简单,就是把公钥私钥的用法反过来,以前是公钥加密、私钥解密,如今是私钥加密、公钥解密。
但又由于非对称加密效率过低,因此私钥只加密原文的摘要,这样运算量就小的多,并且获得的数字签名也很小,方便保管和传输。
签名和公钥同样彻底公开,任何人均可以获取。但这个签名只有用私钥对应的公钥才能解开,拿到摘要后,再比对原文验证完整性,就能够像签署文件同样证实消息确实是你发的。
数字证书和 CA
咱们常说的CA(Certificate Authority,证书认证机构)。它就像网络世界里的公安局、教育部、公证中心,具备极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥没法伪造,是可信的。
CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证实公钥关联的各类信息,造成“数字证书”(Certificate)。
总结
头部压缩
因为报文请求头通常都会携带许多固定的头字段,而请求体的内容每每只有不多同时屡次重复的请求使得重复的头部字段被屡次发送,因此HTTP2开发出专门的压缩算法进行头部压缩,因为gzip算法会被”crime“攻击因此HTTP2开发了专门的“HPACK”算法,在客户端和服务器两端创建“字典”,用索引号表示重复的字符串,还釆用哈夫曼编码来压缩整数和字符串,能够达到 50%~90% 的高压缩率。
二进制格式
因为传统的纯文本形式会使用复杂的状态机,致使文本解析效率低。HTTP2采用二进制来优化,将原来的的“Header+Body”的消息“打散”为数个小片的二进制“帧”(Frame),用“HEADERS”帧存放头数据、“DATA”帧存放实体数据。
虚拟的“流”
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”。
协议栈
小结:
链接前言
TLS 握手成功以后,客户端必需要发送一个“链接前言”(connection preface),用来确认创建 HTTP/2 链接。
HTTP2的链接前言使用的是“Magic”确保使用的HTTP2
头部压缩 :smiling_imp:
头部压缩算法使用的是HPACK算法。它是一个“有状态”的算法,须要客户端和服务器各自维护一份“索引表”,也能够说是“字典”(这有点相似 brotli),压缩和解压缩就是查表和更新表的操做。 具体的实现为将原先头部的字段改成伪头部形式为“:authority”,":method"等来跟原先头部进行区分。HTTP/2 就为一些最经常使用的头字段定义了一个只读的“静态表”(Static Table)。经过key——value的形式如 ":method":2来表示GET请求,在发送时候只要一个字节发送对应的索引2就能够。
同时为了解决自定义字段找不到的问题,使用了动态表,跟在静态表的后面,在编码解码的时候随时更新。
二进制帧
格式
二进制帧头部占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。
流的特色:
流状态转换
状态转换相似tcp的状态转换
总结:
总结篇 探索篇 安全篇的部份内容没有记录 本身感受在实践中没有太多用到,或者是自身储备不足。下次再作记录。