请求方法 | Body | 幂等 | |
---|---|---|---|
GET | 获取资源 | Y | |
POST | 增加或修改资源 | Y | |
PUT | 修改资源 | Y | Y |
DELETE | 删除资源 | Y | |
HEAD | 同 GET;响应报文没有 Body | 响应报文也没有 | Y |
状态码 | 描述 |
---|---|
1xx | 临时消息 |
100 | 继续发送 |
101 | 协议切换 e.g. http1.1 -> http2 |
2xx | 成功 |
3xx | 重定向 |
4xx | 客户端错误 |
5xx | 服务器错误 |
Header: 用于主机确定子主机,不用于 DNS 解析。
Content-Length: Body 长度。Body 可能包含任意数据,包括二进制数据。因此难以设置一个结束标记。所以需要显式指明数据长度。
Content-Type:
text/html: html 文本,用于浏览器页面响应。
application/x-www-form-urlencoded: 普通表单(纯文本表单),URL encoded 格式。
[body]
key1=v1&key2=v2
multipart/form-data: 多部分形式。多用于传输包含二进制项的多项数据。
POST /users HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary777777
----WebKitFormBoundary777777
......
application/json
application/zip, image/jpeg…: 单文件,多用于响应或 POST/PUT 请求。
Location: 重定向目标 URL
Range: 指定 Body 内容范围。用于分段加载/断点续传。服务器用 Accept-Ranges 指明是否支持,以及支持的单位。
Range: bytes=0-1024
Cookie / Set-Cookie
Authorization
Authorization 是一个 HTTP Header,根据具体使用的规范不同,携带不同的数据来认证。
Header 格式:
Authorization: Basic xxxxxx(<username:password> 整体 base64 编码)
缺点
Header 格式:
Authorization: Bearer <token>
此处的 Token 一般来源于:
在场景 「用户使用 Github 登录掘金」 中:
3rd-party Server3rd-party ClientProviderclient_id1authorization_code2authorization_code3authorization_code & client_secret4access_token & refresh_token53rd-party Server3rd-party ClientProvider
① 跳转到 Provider 的网站。client_id 用于 Provider 确认第三方身份。
②: OAuth 不强制使用 https(也无法保证浏览器本身不是恶意软件),故这里只返回 code 而不是 token,防止被窃取。
AuthCode 换取 token 的时候需要 client_secret,所以即使 AuthCode 被窃取也依然安全。
⑤: 第三方得到 token,OAuth2 流程结束。 refresh_token 出于安全目的提供,防止 access_token 泄漏。可以立即刷新 access_token,或在其过期后自助重新获取。
原则上 access_token 不应该发送到客户端,客户端不应该自己去 Provider 取数据。
应用层/Application Layer
传输层/Transport Layer:提高传输稳定性,为应用层提供数据切分分块传输/重传能力。
网络层/Internet Layer:不是所有的场景都需要重传,但它们都需要网络(寻址/路由等),因此抽象出网络层。
数据链路层/Link Layer:不同的物理设备/传输介质需要不同的协议,因此抽象出数据链路层。
TCP 是有状态协议,需要建立连接。为了节省资源,也需要关闭连接。
ClientServerSYN_SENDSYN_RCVDESTABLISHEDESTABLISHEDSYN=11SYN=1, ACK=12SYN=0, ACK=1, DATA3ClientServer
ClientServerFIN_WAIT_1CLOSE_WAIT半关闭:客户端不再发送数据FIN_WAIT_2LAST_ACK服务端不再发送数据CLOSEDTIME_WAIT2MSLCLOSEDFIN=11ACK=12FIN=1, ACK=13ACK=14ClientServer
TCP 连接若长时间空闲,网关或中间的其他网络节点可能会强行关闭来释放资源。
但实际上不发消息不代表打算关闭连接,随时有可能出现新消息。
所以我们要定期发送一点消息来保持活跃,称为「心跳包」。
心跳包的频率等问题,需要在稳定/耗电等诸多方面寻求平衡,是一个专门的话题。
HTTPS 本质是在 HTTP 与 TCP 直接插入一个加密层。它在客户端与服务器之间用非对称加密协商出一个对称加密密钥,用这个密钥加密后续的数据。
HTTPS (TLS) 也是有状态的(比如协商出的对称密钥),同样需要连接。
基本流程
ClientServerClient Hello 0x01 etc..1Server Hello 0x02 etc..2Cert etc..3Pre-master secret (服务器公钥加密)4Finish5Finish6ClientServer
①: 除了握手包,也包括可选的 TLS 版本 / 加密套件 Cipher suites(可选的对称/非对称/hash 算法)/ 一个随机数。
②: 除了服务端握手包,还包括选定的 TLS 版本 / 加密套件 / 一个服务端生成的随机数。
③: 服务器发送:
④: 发送后。双方都可以使用 Pre-master-secret + Client-random + Server-random 计算出 Master-secret。
为什么不直接用 pre-master 作为密钥?
防止重放攻击 (replay attack)
之后,双方也都可以通过 Master-secret 推算出这些数据:
为什么 TLS 中客户端与服务端要使用不同的密钥?
防止黑客把客户端的数据原样发回。此消息密码正确,会被误认为是服务器返回的。
什么是 MAC secret?
HMAC: hash-based message anthenticate code. 在 hash 的过程中添加进去一个密钥,一遍确认执行 hash 的人身份。