超文本传输协议(Hyper Text Transport Protocol, HTTP)建立在传输层协议(TCP/UDP)之上
HTTP基础
HTTP 请求消息格式
Request = Request-Line
*(( general-header
| request-header
| entity-header ) CRLF)
CRLF
[ message-body ]
示例:
GET /index.html HTTP/1.1 // request line
Host: www.example.com // header fields
<CR><LF> // empty line, <CR><LF> only
// optional message body
HTTP 方法
GET 请求资源
HEAD 请求资源,仅返回响应头部信息
POST 创建资源
PUT 指定资源存在则对其进行修改,不存在则创建
DELETE 删除指定资源
TRACE 追踪中间服务器对请求的修改, Cross-site Tracing
OPTIONS 查询服务器对指定资源支持哪些HTTP请求方法
CONNECT SSL
PATCH 对资源进行部分修改
根据规范,HTTP服务器必须支持 GET 和 HEAD 方法
GET HEAD TRACE OPTIONS 都是安全方法因为它们不修改资源
PUT DELETE 是幂等的(同样的输入永远得到同样的输出)
HTTP 部分头部字段
使用场景分类
- 通用字段
- 请求字段
- 响应字段
- 实体字段
代理服务器处理方式分类
- 端到端字段
- 逐跳字段
用途分类
认证(Authentication)
- WWW-Authenticate
- Authorization
- Proxy-Authenticate
- Proxy-Authorization
缓存(Caching)
- Age
- Cache-Control
- Clear-Site-Data
- Expires
- Pragma
- Warning
客户端提示(Client Hints)
- Accept-CH
- Accept-CH-Lifetime
- Early-Data
- Content-DPR
- DPR
- Save-Data
- Viewport-Width
- Width
条件(Conditionals)
- Last-Modified
- ETag
- If-Match
- If-None-Match
- If-Modified-Since
- If-Unmodified-Since
- Vary
连接管理(Connection management)
- Connection
- Keep-Alive
内容协商(Content-negotiation)
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
控制(Controls)
- Expect
Cookies
- Cookie
- Set-Cookie
CORS
- Access-Control-Allow-Origin
- Access-Control-Allow-Credentials
- Access-Control-Allow-Headers
- Access-Control-Allow-Methods
- Access-Control-Expose-Headers
- Access-Control-Max-Age
- Access-Control-Request-Headers
- Access-Control-Request-Method
- Origin
- Timing-Allow-Origin
Do Not Track
- DNT
- Tk
Downloads
- Content-Disposition
Message body
- Content-Length
- Content-Type
- Content-Encoding
- Content-Language
- Content-Location
Proxies
- Forwarded
- Via
Redirects
- Location
Request context
- From
- Host
- Referer
- Rferrer-Policy
- User-Agent
Response context
- Allow
- Server
Range requests
- Accept-Ranges
- Range
- If-Range
- Content-Range
Security
- Content-Security-Policy
- Feature-Policy
- Strict-Transport-Security
- X-Content-Type-Options
- X-Frame-Options
- X-XSS-Protection
Other
- Alt-Svc
- Date
- Large-Allocation
- Link // Link: https://example.com; rel="preload”
- Retry-After
- Server-Timing
- SourceMap // link to source map file
- X-DNS-Prefetch-Control
### HTTP 部分状态码
- 1xx (Informational): The request was received, continuing process
- 2xx (Successful): The request was successfully received, understood and accepted
- 3xx (Redirection): Further action needs to be taken in order to complete the request
- 4xx (Client Error): The request contains bad syntax or cannot be fulfilled
- 5xx (Server Error): The server failed to fulfill an apparently valid request
一些常见状态码:
- 100 Continue
- 101 Switching Protocols(如从HTTP切换到HTTPS)
- 200 OK
- 201 Created(new resource)
- 202 Accepted(processing not completed)
- 203 Non-Authoritative Information(origin response modified)
- 204 No Content
- 206 Partial Content(byte serving)
- 300 Multiple Choices(agent-driven content negotiation)
- 301 Moved Permanently(always redirect to new URL)
- 302 Found/Moved temporarily
- 303 See Other (HTTP/1.1)
- 304 Not Modified(If-Modified-Since or If-None-Match)
- 307 Temporary Redirect(HTTP/1.1)
- 308 Permanent Redirect(307 and 308 parallel the behaviors of 302 and 301, but do not allow the HTTP method to change. )
- 400 Bad Request(malformed request syntax, size too large, etc.)
- 401 Unauthorized
- 402 Payment Required
- 403 Forbidden(server refusing)
- 404 Not Found
- 405 Method Not Allowed(wrong http method used, such as a PUT request on a read-only resource)
- 406 Not Acceptable(Content negotiation)
- 408 Request Timeout
- 409 Conflict(resource state in conflict, such as multiple simultaneous updates)
- 410 Gone(a resource has been intentionally removed and the resource should be purged.Clients such as search engines should remove the resource from their indices)
- 411 Length Required
- 412 Precondition Failed
- 413 Payload Too Large
- 414 URI Too Long
- 415 Unsupported Media Type
- 418 I’m a teapot
- 426 Upgrade Required(switch protocol such as TLS/1.0)
- 429 Too Many Requests
- 431 Request Header Fields Too Large
- 500 Internal Server Error
- 501 Not Implemented(HTTP method not supported)
- 502 Bad Gateway(invalid upstream response received by server)
- 503 Service Unavailable(server overloaded or down for maintenance)
- 504 Gateway Timeout
some codes by nginx:
- 495 SSL Certificate Error
- 496 SSL Certificate Required
- 499 Client Closed Request
内容协商(Content Negotiation)
请求的资源可能以多种格式存在,比如视频 音频 图片
- server-driven(主动) 客户端指定能处理的媒介类型和相应的处理能力,由服务器端算法决定返回内容格式
Accept Accept-CH Accept-Charset Accept-Encoding Accept-Language User-Agent Vary
- agent-driven(被动) 300 (Multiple Choices) or 406 (Not Acceptable)
Accept-Language: de; q=1.0, en; q=0.5
Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1
Content negotiation What Are Client Hints and Are They Worth Implementing
缓存机制(Cache)
HTTP/1.x
HTTP/1.0 连接在响应后断开
HTTP/1.1 重要特性
Connection reuse
Pipelining(superseded by multiplexing)
Chunked responses
Content negotiation
Host header(one IP for multiple domain)
Server-sent Events
WebSocket
keep-alive
pipelining
chunked transfer encoding
byte serving
TCP 慢启动 拥塞窗口机制
HTTP pipelining默认关闭。单个请求处理耗时较长时阻塞后续请求,存在线头阻塞(head-of-line blocking)问题。
HTTP/1.1 头部字段除host外都是可选的
降低延迟的一些手段
Spriting,多张小图片合并成一张大图 缺点是当某些页面只需要显示其中一两张小图时,这种缓存整张大图的方案就显得过于臃肿。同时,当缓存被清除时,会导致所有小图片被同时删除,而不能选择保留其中最常用的几个
图片内联(inlining),使用data URI指定图片路径
文件拼接(concatenation)
分片(Sharding),把服务分散在尽可能多的主机上,然后建立多个TCP连接。比如单独的不需要cookie的图片服务器
TCP Fast Open(支持不理想) TCP Slow start
HTTP/2
HTTP/1.1 过于庞大,细枝末节过多,可选配置和为扩展预留的选项很多。
从HTTP/2开始不再使用小版本号(HTTP/2.x)。服务器和客户端都必须确定自己是否完整兼容http2或者彻底不兼容。
HTTPS(HTTP over TLS) Next Protocol Negotiation (NPN) ALPN(Application Layer Protocol Negotiation) ALPN和NPN的主要区别在于:谁来决定通信协议。在ALPN的描述中,是让客户端先发送一个协议优先级列表给服务器,由服务器最终选择一个合适的。而NPN则正好相反,客户端有着最终的决定权。
HTTP/1.1是文本协议,HTTP2是二进制协议 基于文本的协议更容易产生错误 HTTP/2 通常运行在TLS之上的事实又再次降低了基于纯文本实现的价值,反正也没办法直接从数据流上看到文本
二进制帧公共字段:
- Type
- Length
- Flags
- Stream Identifier
- Frame payload
HTTP/2特性
- 多路复用(multiplexing)
头部压缩(HPACK)
请求重置(RST_STREAM)
服务器推送(主动推送关联资源)
流量控制(双方协商数据发送量,仅对数据帧有效)
备选服务(TCP连接复用导致服务器负载增加),使用 ALTSVC 帧指定
Client Hints
It is a binary protocol rather than text.
It is a multiplexed protocol. Parallel requests can be handled over the same connection, removing the order and blocking constraints of the HTTP/1.x protocol.
It compresses headers.
It allows a server to populate data in a client cache, in advance of it being required, through a mechanism called the server push.
HTTP/3(HTTP-over-QUIC)
HTTP/3采用QUIC协议(基于UDP协议),QUICK协议介于HTTP/3与UDP之间 QUIC在UDP之上增加了带来可靠性的层。它提供了数据包重传、拥塞控制、调整 传输节奏(pacing)以及其他一些TCP中存在的特性 IETF版QUIC是一个传输层协议 目前已知的所有QUIC实现都位于用户空间,这使它能得到更快速的迭代(相较于内核空间中的实现)。 QUIC连接基于UDP端口和IP地址建立,而一旦建立,连接通过 其“连接ID”(connection ID)关联,连接ID的基本功能是确保底层协议(UDP、IP及其底层协议)的寻址变更不会使QUIC连接传输数据到错误的端点 有一些网络上的中间设备会拦截端口53(用于DNS)以外的UDP流量。还有一些网络会节流(throttle)UDP流量,使得QUIC的表现慢于基于TCP的协议
当TCP连接阻塞丢包率增加时,HTTP/2多路复用表现会受到显著影响
所以QUIC引入了独立数据流
HTTP/3并没有发明新的通信协议,因为在用户与服务器之间要经过许多防火墙、NAT(地址转换)、路由器和其他中间设备(middle-box),这些设备有很多只认TCP和UDP。
A Comparison between SCTP and QUIC
协议僵化(Ossification)问题 网络的核心部分(中间设备)与边缘部分(客户端、服务器)相比,更新很慢。在这些设备部署之后的一段时间里,协议有了新的特征。 而在这些设备引入(了解)这些新特性之前,它们会认为这种特征的数据包是非法的、恶意的,于是会将这种流量直接扔 掉,或是拖延到用户不再想使用这些新特征的程度。
尽可能将通信加密是对抗僵化的唯一有效手段,加密可以防止中间设备看到协议传输的绝大部分内容。 所以QUIC连接是加密的(TLS 1.3+)。QUIC只在加密协议协商时会发送几个明文传送的初始握手报文
QUIC特性
- 用户空间实现,方便部署易于演进,但同样带来了实现版本众多的问题
- 0-RTT 1-RTT握手
- early data(QUIC允许客户端在0-RTT的情况下直接捎带数据)
- QPACK 头部压缩(HPACK算法依赖于数据流的有序交付)
QUIC缺点 Linux内核的UDP部分没有得到像TCP堆栈那样的优化,因为传统上没有使用UDP进行如此高速的信息传输。 TCP和TLS有硬件加速(负载卸载到硬件,offload),而这对于UDP很罕见,对于QUIC则基本不存在。
QUIC流程
- 建立连接(加密算法的版本协商与传输层握手合并完成)
- 连接ID
- 端口
- 协议版本协商
- 协商安全的TLS连接
- 使用数据流
- 流控(Flow Control)
- 流ID
- 优先级(1-256)
- 旋转比特
QUIC数据帧
- HEADERS
- DATA
- GOAWAY
- PUSH_PROMISE
- CANCEL_PUSH