超文本传输协议(HyperText Transfer Protocol), 是一种用于分布式、协做式和超媒体信息系统的应用层协议, 是万维网的数据通讯的基础(维基百科)。这里咱们主要关注一下什么是应用层,以及网络是如何分层的.html
网络为何要分层[1]?web
开放式系统互联通讯参考模型,由国际标准化组织提出。
OSI
将网络分为七层: 应用层、表示层、会话层、传输层、网络层、链路层、物理层。算法
TCP/IP
是实际的标准, 分为五层: 应用层、传输层、网络层、链路层、物理层。浏览器
TCP/IP
与OSI
的分层的对应关系, 以下图所示:
缓存
TCP/IP
也能够说是四层, 若是是四层的话就是把链路层与物理层统称为网络接口层。安全
让咱们从一次请求过程来了解HTTP
。bash
URL
以后,首先须要DNS
来将域名解析为IP
地址。TCP
链接(三次握手),创建链接的时候是须要发送IP
包的。HTTPS
会进行TLS/SSL
的握手。链接创建之后,就是要向服务器发送请求,那么请求格式是怎么样的呢? HTTP1.1为明文传输,因此咱们很容易可以在Chrome
的Network
中看到,请求的格式以下图所示:
服务器
从上图能够看出,请求分为了三部分:请求行,首部,实体。websocket
首部与实体之间使用空行分隔。网络
请求行由三部分构成:方法,URL
,HTTP
版本号,以空格隔开。
主要的方法有:GET
POST
OPTIONS
HEAD
等
GET
若是有参数,会将其放在URL
中: 优势:
URL
能够被缓存TCP
第三次握手时将报文随握手包发送)。 缺点:URL
的长度)GET
请求的过程[2]:
TCP
链接(第一次握手)TCP
链接(第二次握手)GET
请求头和数据200 OK
响应POST
参数存在于实体中: 优势:
GET
,抓包除外)。 缺点:GET
多了几个用于协商的首部,且须要待第三次握手后再发送报文)。POST
请求的过程[2]:
TCP
链接(第一次握手)TCP
链接(第二次握手)POST
请求头(第三次握手)100 Continue
响应200 OK
响应OPTIONS
HEAD
请求资源的首部信息, 而且这些首部与GET
方法请求时返回的一致。响应不该包含响应实体,即便包含了实体也必须忽略掉。
URL
(Uniform Resource Locator), 统一资源定位符, 是因特网上标准的资源的地址。
完整格式:协议类型:[//[访问资源须要的凭证信息@]服务器地址[:端口号]][/资源层级UNIX文件路径]文件名[?查询][#片断ID]
另外,与URL
相关的定义还有URI
和URN
。 URI
(Uniform Resource Identifier),统一资源标识符,用于标识某一互联网资源名称的字符串。 URN
(Uniform Resource Name),统一资源名称,一种为资源提供持久的、位置无关的标识方式。
URL
与URN
是URI
的子集,三者关系,以下图所示:
举个栗子:
urn:isbn:0-486-27557-4
这是一个资源,它是URN
,也是URI
,但不是URL
。
HTTP
版本主要版本:0.九、1.0、1.1、2
首部是key: value
形式,经过冒号空格分隔,为客户端和服务器分别处理请求和相应提供所须要的信息。 首部分为四类:请求首部,响应首部,通用首部,实体首部。
顾名思义,只会在请求报文中存在。
Accept-Charset
:客户端支持的字符集,例:utf-8
。Accept-Encoding
:客户端能够接受的内容编码形式,例:gzip
。Referer
:对请求中URL
的原始获取方。Host
:请求资源所在服务器。Accept-Language
:提示用户指望得到的天然语言的优先顺序。User-Agent
:用来识别发送请求的浏览器。Cache-Control
:缓存控制。Content-Encoding
:实体的编码方式。Content-Language
:实体的天然语言。Content-Type
:实体的媒体类型。Location
:令客户端重定向至指定URL
。Retry-After
:对再次发起请求的时机要求。Server
:HTTP
服务器的安装信息。ETag
:资源匹配信息(缓存相关)。一切准备完成后就是发送请求。
请求发送接收的过程以下图所示:
HTTP
构建完成后,经过网络线程将请求报文交给TCP
。TCP
将请求的报文进行分割,并将各个报文包入TCP
的头部,交给IP
。IP
将TCP
报文包入IP
的头部,交个链路层。MAC
地址是否为本身的MAC
地址,若是是会把以太网头部去除,交个上层协议。IP
收到链路层发送的数据后,会检查目标IP
是否为本身的IP
,若是是把IP
头部去除,交给上层协议。TCP
收到数据后,去掉TCP
头部,交给浏览器。响应与请求除了状态行外结构基本相同,一样分为 3 部分:状态行,首部,实体。
状态行分为 3 部分:HTTP版本,状态码,短语,以空格分隔,其中短语为对状态码的解释。
PUT
请求中进行资源更新,可是不须要改变当前展现给用户的页面,那么返回204 No Content
。例如:提交表单后,不进行页面跳转)。GET
请求。响应报文中包含由Content-Range
指定范围的的实体内容。URL
,之后请使用资源如今所指的URL
。搜索引擎会根据该响应修正。URL
,但愿用户(本次)能使用新的URL
访问。已改变,且未来还有可能发生改变。URL
,应使用GET
方法定向获取请求的资源。(301
、302
、303
响应状态码返回时几乎全部的浏览器都会把POST
改为 GET
,并删除请求报文的主体,以后请求会自动再次发送。)。302
之间的惟一区别在于,当发送重定向请求的时候,307
状态码能够确保请求方法和消息主体不会发生变化。200 OK
同样对待该状态码。WWW-Authenticate
首部一块儿发送,其中包含有如何进行验证的信息。Retry-After
首部字段再返回给客户端。在完成了响应的构建以后,会按照与发送相同的方式将响应发送给客户端。最后TCP
四次回收断开链接。
整个请求过程以下图所示:
HTTP/0.9很是简单,请求仅由单行构成,以惟一可用方法GET
开头,其后跟目标资源的路径。
GET /index.html
响应也很是简单仅包含响应文档自己,若是出现错误会将错误信息以文档形式返回。
主要引入了头部,及状态码,并支持多种文件格式。
HTTP/1.1 相对 1.0 的不一样:
Keep-Alive
,全部链接都被保持,除非在请求头或响应头中指明要关闭:Connection: Close
。Keep-Alive
不会永久保持链接,它有一个保持时间,能够在不一样的服务器软件中设定这个时间(实际是在1.0
版本引入,但并不会默认开启)。Cache-Control
等。TCP
端口号。与 HTTP/1.1
的区别:
TCP
链接中能够同时发送多个请求。浏览器在首次对资源进行请求时,会记录缓存相关的首部,在后续请求中根据记录的首部进行相应的资源读取操做,如读取缓存,资源验证等。 缓存的做用:减小请求次数,减小带宽;增长加载速度,减小白屏时间。
在说明缓存控制原理以前,先了解下缓存相关的首部。
控制缓存的有效时间,及缓存行为。
主要值:
对于 Cache-Control: no-cache, max-age=900 这种状况,no-cache 与 max-age 的优先级与前后顺序有关。
为HTTP/1.0
提出,表示缓存过时时间,超过这个时间即缓存过时。若是响应中有max-age
或s-maxage
会被覆盖。
expires: Sun, 02 Sep 2018 14:36:18 GMT
资源的最后修改时间,主要用于在服务器验证缓存是否被修改时使用。
last-modified: Fri, 18 May 2018 01:10:24 GMT
资源实体标识,由服务器分配,资源更新时ETge
随之改变,分为强ETag
与弱ETag
。 **弱ETag
**很容易生成,但不利于比较。**强ETag
**是比较的理想选择,但很难有效地生成。
ETag: W/"5a323f72-152"(弱) ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"(强)
200 (from memory/disk cache)
。ETag
及Last-Modified
,若是存在,则在请求首部中发送对应的首部If-None-Match
及If-Modified-Since
,若是没有则不发送这两个首部。If-None-Match
及If-Modified-Since
来比较资源的ETag
若是改变了比较Last-Modified
,若是匹配则返回304
,若是不匹配,将资源随实体返回,状态码200
。from memory cache 与 from disk cache 为 Chrome 的缓存优化机制,但对于该采用什么方式,并无找到明确答案。
强缓存:不会向服务器发送请求,直接读取缓存的方式,在上述过程当中直接返回状态码200 (from memory/disk cache)
。 协商缓存:请求资源时会向服务器发送If-None-Match
及If-Modified-Since
(若是存在ETag
及Last-Modified
),服务器验证后,返回304
或200
。
在学习HTTPS
以前,咱们了解下HTTP
的缺点:
而HTTPS
解决了上述缺点(HTTPS
并不是新协议,而是HTTP
+ TLS
)
发送端和接收端使用相同的密钥。发送端使用密钥加密明文,接收端接收后使用密钥解析加密信息,获得明文。
对称加密最大的问题就是在一对多的时候的密钥传输问题,因此为了保证安全对称加密的密钥是绝对不能公开的。
非对称加密有两个密钥,一个是公钥,一个是私钥,公钥加密后的密文只能使用私钥解密,私钥加密后的密文只能使用公钥解密。那么只须要对外展现公钥就能够了。
可是,非对称加密的解密过程速度较慢(对称加密主要是位运算,而非对称加密包含了不少乘法或大数模)。
充分利用对称及非对称加密的优点,使用非对称加密的方式传输对称加密的密钥,即有非对称加密的安全又有对称加密的速度。 HTTPS
(或者说TLS
)就是采用了这种方式。
CA
在拿到公钥后,能不能就直接肯定这个公钥是值得信任的?答案是确定不能,若是公钥是某个黑客伪造的,他就能够修改从发送端接到的请求,在发给服务器了。因此,在拿到公钥后,首先要验证公钥是否是能够信任的,那么谁能保证公钥是能够信任的,那就必需要是一个你信任的机构,这个机构就是CA
,而每一个站点的公钥实际都是由CA
签发的。因此CA
能够验证公钥是否属于这个站点的。
CA
CA
使用本身的私钥向服务器的公钥部署数字签名,并颁发公钥证书CA
的公钥(存在于客户端证书信任列表中)去验证签名是否与公钥匹配。TCP
三次握手后,客户端发送请求安全链接(Client Hello),报文中包含一个随机字符串,并列出客户端支持的加密套件,用于协商对称加密的加密方式。CA
,使用该CA
的公钥解密证书,来验证公钥是否安全,若是CA
的证书由上级CA
提供且不在信任列表内,则须要一直向上找到客户端信任的CA
为止。Pre-master secret
的随机字符串,客户端及服务器端使用上面提到的三个随机字符串,并使用协商好的加密算法计算出对称加密的密钥。Change Cipher Spec
报文,以提示服务器后续通讯将采用计算好的对称加密密钥进行通讯Finished
报文,报文中包含链接至今所有报文的总体校验值,若是服务器端可以正确解密该报文,则握手成功Change Cipher Spec
报文Finished
报文,链接创建。WebSocket
是能够实现客户端与服务器端双向通讯的新协议,除了借助HTTP
完成一次握手外,与HTTP
没有关系。
TCP
三次握手。Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
复制代码
上述首部中主要是用到了Upgrade
首部,用于通知服务器切换协议到WebSocket
。 3. 服务器端接收到升级协议的请求后,若是支持WebSocket
会响应该请求。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
复制代码
响应状态码:101,表示服务器端应客户端升级协议的请求正在升级协议。 4. WebSocket
握手完成,后续通讯将使用WebSocket
协议。
参考:
[1]《计算机网络(第五版)》(谢希仁)
[2] http GET 和 POST 请求的优缺点、区别以及误区
[3] TLS 握手优化详解