HTTP
超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使开发和部署非常地直截了当。
报文结构
HTTP有两类报文:
- 请求报文——从客户向服务器发送请求报文
GET /xxx/index.html HTTP/1.1 Host: www.xxx.com Connection: keep-alive User-Agent: Mozilla/5.0 Accept_language: cn {请求报文的最后还有一个空行} - 响应报文——从服务器到客户的回答
HTTP/1.1 200 OK Host: www.xxx.com Connection: keep-alive Set-Cookie: xxxxx {响应报文的最后还有一个空行}
HTTP是面向文本的,每个字段的长度都是不确定的。请求报文和响应报文都是由三个部分组成。
- 开始行:用于区分请求报文还是响应报文。在请求报文中的开始行叫做
请求行(Request-Line),而在响应报文中的开始行叫做状态行(Status-Line)。CR:回车,LF:换行
- 首部行:用来说明浏览器、服务器或报文主题的一些信息。
- 实体主体:body
Content-Length
使用十进制的数字表示了消息的长度,服务端/客户端通过它来得知后续要读取消息的长度。记录的长度应该与Body保持一致否则会导致异常。
-
Content-Length > 实际长度
curl --location --request GET '0.0.0.0:8080/ping' \ --header 'Content-Length: 5' \ --header 'Content-Type: text/plain' \ --data-raw '123'服务端/客户端读取到消息结尾后, 会等待下一个字节, 会无响应直到超时
-
Content-Length < 实际长度
curl --location --request GET '0.0.0.0:8080/ping' \ --header 'Content-Length: 1' \ --header 'Content-Type: text/plain' \ --data-raw '123'如果这个长度小于实际长度,首次请求的消息会被截取,所以只能读取到
1。
如果我们在这条连接的基础上再次请求,报文解析会产生解析(如将上一次剩下的消息拼接到后续的请求消息中).
请求过程
域名解析
为什么要进行DNS域名解析
网络通信都是基于tcp/ip的,tcp/ip是基于ip协议的。而ip协议只能识别ip地址。所以需要将指定的域名通过DNS解析为ip地址。
DNS域名解析的工作过程
通过udp查询
客户机本地缓存--->本地DNS服务器--->根域名服务器--->顶级域名服务器--->域名提供商
TCP三次握手
SSL/TLS
SSL/TLS 协议位于网络 OSI 七层模型的会话层,用来加密通信。SSL(Secure Sockets Layer,安全套接字层)是一种标准安全协议,用于在在线通信中建立Web服务器和浏览器之间的加密链接。SSL 通过互相认证、使用数字签名确保完整性、使用加密确保私密性,以实现客户端和服务器之间的安全通讯。
TLS(Transport Layer Security,传输层安全)是 IETF 在 SSL 3.0 的基础上设计的协议,它是 SSL 协议的升级版。两者差别极小,可以理解为 TLS 是 SSL 3.1。
客户端请求1
客户端(通常是浏览器)先向服务器发出加密通信的请求,这被叫做ClientHello请求。在这一步,客户端主要向服务器提供以下信息:
- 支持的协议版本,比如TLS 1.0版。
- 一个客户端生成的随机数,稍后用于生成"对话密钥"。
- 支持的加密方法,比如RSA公钥加密。
- 支持的压缩方法。
服务器回应1
服务器收到客户端请求后,向客户端发出回应,这叫做SeverHello。服务器的回应包含以下内容。
- 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
- 一个服务器生成的随机数,稍后用于生成"对话密钥"。
- 确认使用的加密方法,比如RSA公钥加密。
服务器回应2
服务器会把自己的公钥注册到CA(第三方证书机构),然后CA拿自己的私钥对服务器的公钥进行处理并颁发数字证书。服务器再向客户端发送数字证书。
CA
现实中,通过CA来保证公钥的真实性。CA也是基于非对称加密算法来工作。有了CA,服务端会先把自己的公钥和一些其他信息交给CA。CA用自己的私钥加密这些数据,加密完的数据称为服务器的数字证书。
现在服务器要向客户端传递公钥,服务器传递的是CA加密之后的数字证书。客户端收到以后,会通过CA发布的CA证书(包含了CA的public key),来解密服务器的数字证书,从而获得的公钥。
CA证书集成在了浏览器和操作系统里面,保证不被劫持。客户端和服务器的公钥的真实性得到了保证,可以通过网络交换公钥。
除非有种情况,客户端内置的CA证书被篡改了,例如使用了盗版的系统,或者被病毒攻击了,那这个时候,客户端会认可非CA认证的数字证书。
客户端请求2
客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息。
- 一个随机数。该随机数用服务器公钥加密,防止被窃听。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。
服务端回应3
服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的"会话密钥"。然后,向客户端最后发送下面信息。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的 hash值,用来供客户端校验。 至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用"会话密钥"加密内容。