图解 HTTP 摘要
参考 [日] 上野宣 HTTPの教科書
Web Basis
Web and Networking Fundamentals
Web 是建立在 HTTP HyperText Transfer Protocol 上通信的。
通常所使用的网络是在 TCP/IP 协议族的基础上运作的。HTTP 属于它的子集。
TCP/IP 协议族按层次可分为:应用层、传输层、网络层和链路层。
OSI 模型是国际化组织 ISO 提出的世界范围计算机互联框架。
OSI 七层模型各自实现功能与协议,并能与相邻层的接口进行通信。
应用层 => 表示层 => 会话层 => 传输层 => 网络层 => 数据链路层 => 物理层
HTTP/1.1 规范允许一台 HTTP 服务器搭建多个 Web 站点。
IP & TCP 和 URI & URL
负责传输的 IP 协议:
- IP Internet Protocol 网际协议位于网络层
- 此 IP 作为一种协议的名称,非 IP 地址的 IP
- IP 协议的作用是将各种数据包进行传送
- 确保传递的条件:IP 地址和 MAC 地址 Media Access Control Address
- IP 地址指明节点被分配到的地址
- MAC 地址是网卡所属的固定地址
确保可靠性的 TCP 协议:
字节流服务 Byte Stream Service 是指为了方便传输,将大块数据分割成以报文段 segment 为单位的数据包进行管理。
- TCP 位于传输层,提供可靠的字节流服务
- TCP 协议能够确认数据最终是否送达到指定方(三次握手)
- 握手过程使用 TCP 的标志 flag => SYN synchronize & ACK acknowledgement
发送端先发送带 SYN 标志的数据包;接收端收到后回传带有 SYN/ACK 标志的数据包以示传达确认信息。最后发送端再回传一个带 ACK 标志的数据包,代表握手的结束。若握手过程中的某个阶段被莫名中断,TCP 协议会再次以相同的顺序发送相同的数据包。
URI 用字符串标识某一互联网资源,而 URL 表示资源的地点:
- URL 是访问页面时需要输入的地址
- URI 是由某个协议方案所表示的统一资源标识符
- URL 是 URI 的子集
协议方案是指访问资源时所使用的协议类型名称。常见有 http、ftp、telnet 等。
HTTP response status codes
状态码的职责是描述客户端向服务器发送请求的结果。借助状态码,开发者可以知道服务器端是正常处理了请求,还是出现了错误。
2XX Success
200 OK: The request has succeeded. A 200 response is cacheable by default.
204 No Content: A request has succeeded, but that the client doesn't need to navigate away from its current page.
206 Partial Content: The request has succeeded and the body contains the requested ranges of data, as described in the Range header of the request.
3XX Redirection
301 Moved Permanently: The requested resource has been definitively moved to the URL given by the Location headers.
302 Found: The requested resource was temporarily moved to the URL specified by the Location header.
The Common Gateway Interface (CGI) provides the middleware between WWW servers and external databases and information sources.
303 See Other: This response code is often sent back as a result of PUT or POST. The method used to display this redirected page is always GET.
304 Not Modified:The resource on the server side has not changed, and the unexpired cached content on the client side can be used directly. Although it is classified in the 3XX category, it has nothing to do with redirection.
307 Temporary Redirect: The target resource resides temporarily under a different URI and the user agent MUST NOT change the request method if it performs an automatic redirection to that URI.
4XX Client Error
400 Bad Request: There is a syntax error in the request message.
401 Unauthorized: The client request has not been completed because it lacks valid authentication credentials for the requested resource.
403 Forbidden: The server understands the request but refuses to authorize it.
404 Not Found: The server cannot find the requested resource.
5XX Server Error
500 Internal Server Error: The server encountered an unexpected condition that prevented it from fulfilling the request.
503 Service Unavailable: the server is not ready to handle the request.
503 状态码表明服务器暂时处于超负载状态或正在进行停机维护,现在无法处理请求。条件允许时,可以将确定的恢复时间写入响应的首部字段 Retry-After。
504 Gateway Timeout: The server, while acting as a gateway or proxy, did not get a response in time from the upstream server that it needed in order to complete the request.
HTTP header & Message
请求/响应报文由以下内容组成:请求行、HTTP 头字段、空行、可选的 HTTP 报文主体数据
message 是 HTTP 通信中的基本单位(即站点一次性要发送的数据块)。
实体作为请求或响应的有效载荷数据(补充项)被传输,由实体首部和实体主体组成。内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。常用的内容编码有 gzip、compress 等。
在请求的编码实体资源尚未传输完成前,浏览器无法显示请求的页面。当传输大容量的数据时,可以通过将数据分割成多块的方式让浏览器逐步的显示页面。
这种把实体主体分块的功能称为分块传输编码 Chunked Transfer Coding。
使用分块传输编码的实体主体会由接收的客户端负责解码,恢复到编码前的实体主体。
HTTP 协议的请求和响应报文中必定包含 HTTP 首部。
首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。客户端用户无须亲自查看。
HTTP 首部字段由字段名和字段值构成,中间用冒号 :
分隔。
// 首部字段名: 字段值
Content-Type: text/html // 报文主体的对象类型
Keep-Alive: timeout=15, max=100...
HTTP 首部字段根据实际的用途可分为四种类型:
- 通用首部字段 General Header Fields => 请求和响应报文都会使用到
- 请求首部字段 Request Header Fields => 请求报文使用的首部
- 响应首部字段 Response Header Fields => 响应报文使用的首部
- 实体首部字段 Entity Header Fields => 请求和响应报文的实体使用的首部
首部字段不限于 RFC2616 中定义的 47 种首部字段,还有 Cookie、Set-Cookie 和 Content-Disposition 等在其他 RFC 中定义的首部字段。这些非正式的首部字段统一归纳在 RFC4229 HTTP Header Field Registrations 中。
使用 Cookie 的状态管理
无状态协议的优点:减少服务器 CPU 以及内存资源的消耗。
Cookie 技术是通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。
根据响应报文内的 Set-Cookie
字段通知客户端保存 Cookie。后续客户端再往该服务器发送请求时,会自动的在请求报文中加入 Cookie 值。
服务器端获取客户端所发送的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录得到之前的状态信息。
强缓存与协商缓存
缓存能减少不必要的数据传输,在减轻服务器负担的同时,可以提升网站的响应速度。Cache 访问的优先级:memory cache -> disk cache -> HTTP Request。
强缓存:浏览器不向服务器发送请求,直接从本地读取缓存的文件并返回成功状态码 200 ok。
强缓存的主要依托:
- HTTP/1.0 中的 Expires 标头 => 明确的时间
- HTTP/1.1 中的 Cache-Control: max-age => 指定经过的时间
If a response includes both an Expires header and a max-age directive, the max-age directive overrides the Expires header, even if the Expires header is more restrictive. RFC2616
协商缓存:浏览器向服务端发送请求,服务端根据请求的参数来判断是否命中协商缓存。若命中协商缓存,那么通知浏览器从缓存中读取资源并返回状态码 304 Not Modified,未命中则返回最新资源并附带成功状态码 200 ok。
协商缓存的主要依托:
- response header 的 etag 与 last-modified
- request header 的 if-none-matched 与 if-modified-since
HTTPS for web security
HTTP 缺陷:通信明文且不加密;通信方身份不验证;报文无法证明完整性。
通信的加密:
- HTTP 协议可以通过 SSL Secure Socket Layer 安全套接层加密通信内容
- 与 SSL 组合使用的 HTTP 称为 HTTPS HTTP Secure 超文本传输安全协议
内容的加密:最好要求客户端与服务器同时具备加密和解密的机制。
请求和响应不对通信方进行确认:各种隐患以及隐藏在海量请求下的 DDoS。
SSL 使用证书确定通信方:证书由可信任的第三方颁发,证明双边的实际存在。
无法证明通信报文的完整性:当请求或响应送出后,即使内容遭到篡改,也没有办法获悉。
请求或响应传输途中所遭到的攻击拦截与内容篡改称为中间人攻击 MITM Man-in-the-Middle attack。可使用 MD5 或 SHA-1 散列值来校验文件的数字签名。
SSL 独立于 HTTP,也能和其他应用层的协议(如 SMTP、Telnet)配合使用。
常规情况是 HTTP 和 TCP 直接通信,但使用了 SSL 后,HTTP 会先和 SSL 通信,再由 SSL 和 TCP 通信。
HTTPS 采用共享密钥加密和公开密钥加密两者的混合加密机制。
Identifying HTTP users
HTTP Basic Authentication
basic 认证即基本认证,是 HTTP/1.0 时定义的服务器与客户端之间的认证。
服务器响应返回 401 Authorization Required,且带回 WWW-Authenticate 首部字段。该字段内包含认证方式 BASIC 以及 Request-URI 安全域字符串 realm。
客户端将 ID 与密码发送给服务器,两者间以冒号连接,再经 Base64 编码处理。
接收到包含首部字段 Authorization 请求的服务器,会对认证信息进行验证。验证通过后会返回一条包含 Request-URI 资源的响应。
basic authentication 虽采用 Base64 编码,但这并不是加密处理(不安全)。
Digest Access Authentication
HTTP/1.1 出现的 Digest 认证采取质询/响应 challenge/response 的方式。
SSL Client Certificate Authentication
仅根据 ID 和密码的正确无法排除可能是他人冒充的情况。
SSL 客户端认证:借助 HTTPS 客户端证书来完成认证。
凭借证书,服务器可以确定来访的客户端。这种认证方式需要事先分发证书,且客户端必须安装此证书。
多数情况下,这种认证方式还会和表单认证组合成一种双因素的认证来使用。
Form-based Authentication
基于表单的认证并不是在 HTTP 协议中所定义的。
客户端向服务器应用发送登录信息,根据认证的结果来决定认证是否成功。
客户端将登录信息放入报文的实体部分并发送给服务器。服务器会发放识别用户的 sessionid。用户的认证状态与 sessionid 绑定后会被记录在服务器。sessionid 通常会放在响应首部字段的 Set-Cookie 中。
为减少跨站脚本攻击 XSS,建议事先在 Cookie 内加上 httponly 属性。
客户端将 sessionid 作为 Cookie 保存在本地。后续的请求会自动携带 Cookie。
服务器会通过客户端请求中所携带的 sessionid 来验证用户的状态。
HTTP-based Protocols
SPDY
SPDY 发音如英语 speedy,是一种由 Google 开发的开放网络传输协议,基于传输控制协议 TCP 的应用层协议。SPDY 也是 HTTP/2 的前身。
异步 JavaScript 与 XML 和以前的同步通信相比,只需要更新一部分的内容,这可以有效减少响应中所需要传输的数据量。
SPDY 以会话层形式加入,控制数据的流动,但还是采用 HTTP 所建立的连接。
使用 SPDY 以获得的功能:多路复用流、赋予请求优先顺序、压缩 HTTP 首部、推播通知和服务器提示。
全双工通信 WebSocket
服务器与客户端所建立的 WebSocket 通信连接,任意方都可直接发送报文。
WebSocket 的首部信息较 HTTP 更小;WebSocket 通信需要在 HTTP 连接建立后完成一次握手。
实现 WebSocket 通信需要用到 HTTP 的 Upgrade 首部字段:告知服务器通信协议所发生的改变。
WebSocket 通信不使用 HTTP 数据帧,而采用 WebSocket 独立的数据帧。
结束
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议,转载请注明出处!