HTTP/HTTPS/HTTP2/HTTP3/QUIC/WebSocket协议详解

发布于 2019-12-24  约 36 分钟

名词解释

URI结构如下,URL是URI中Web Resource的子集,例如http/ftp协议。
image.png

HTTP

HTTP全称Hypertext Transfer Protocol超文本传输协议,主要基于TCP实现的应用层协议,特点有:

  • 支持客户端向服务器请求URL资源。
  • HTTP是无状态协议。服务器不需要强制保存HTTP session任何信息。
  • HTTP authentication特性支持账号密码的传输。

版本变化:

  • HTTP/1.0最初实现了可用性。对每个请求都需要TCP三次握手建立单独链路。
  • HTTP/1.1优化了传输效率。新增keep-alive特性使多个请求可以复用同一条TCP链路(TCP keep-alive是传输层特性,防止NAT路由断开连接);新增chunked transfer encoding允许流式传输而不是一次性buffered传输;新增HTTP pipelining可并行请求-响应,避免串行请求-响应的阻塞耗时;新增byte serving只请求部分资源。

TCP握手流程:
WX20191130-132741@2x.png

三次握手原因。为了避免因传输异常导致包时序问题,一端在发消息时必须要接收到对方的回包确认。例如客户端因网络延迟发了两个SYN,如果没有第三次握手ACK,则服务端会二次建立连接。

WX20191130-132809@2x1.png
四次挥手原因。一端发送FIN是表示自己不发数据,但是还可以接收另一端发送的数据。所以要结束TCP连接,需要双方都FIN+ACK两次RTT。根据wiki也有可以通过三次挥手结束连接,但是需要同时关闭双端。
结束TIME_WAIT需要等待2MSL(最大报文段生存时间)才能到CLOSED状态。一是避免最后的ACK丢白需要重发,二是要确保此次连接的数据包在网络中消失,避免跟下次连接混淆。

请求与响应包:
Http_request_telnet_ubuntu.png
响应状态码分为1xx临时响应、2xx成功、3xx重定向、4xx请求错误、5xx服务器错误。常见状态码见附录。

WebSocket

WebSocket是基于TCP的全双工通信协议。背景是web app网络通信是基于HTTP协议,每次服务端跟客户端通信都需要建立一次HTTP连接,WebSocket在应用层重新设计,提供机制可以让web网络通信在一个TCP连接中实现多次数据传输。
WebSocket与HTTP的联系
为了兼容HTTP服务,WebSocket握手协议是在HTTP基础上进行扩展。但是WebSocket其他部分与HTTP无关,完全是在TCP之上封装的应用与web的协议,其中包括以下内容:
o 为浏览器添加基于Web Origin标准的安全模型
o 添加了一种寻址和协议命名机制,以支持一个端口上的多种服务和一个IP地址上的多个主机名
o 在TCP之上分层成帧机制,以回到建立TCP的IP数据包机制,但没有长度限制
o 在代理和其他中间人的情况下额外设计一套关闭握手协议

WebSocket URI格式:
ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]

WebSocket握手头部:
WX20191224-212945@2x.png

RFC: https://tools.ietf.org/html/rfc6455

HTTPS

HTTPS全称Hypertext Transfer Protocol Secure,是在HTTP协议中添加TLS/SSL扩展,支持加密数据传输。
为了确保数据在传输过程中不被读取(加密算法)、篡改(数字签名)、调包(数字证书),以下对相关术语进行解释。
加密算法
1.对称加密
对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。不足之处是,交易双方都使用同样钥匙,安全性得不到保证。常见的对称加密有 DES、AES 等。
2.非对称加密
非对称加密使用一对“私钥-公钥”,用私钥加密的内容只有对应公钥才能解开,反之亦然。非对称加密有以下特性:

  • 对于一个公钥,有且只有一个对应的私钥。
  • 公钥是公开的,并且不能通过公钥反推出私钥。
  • 通过私钥加密的密文只能通过公钥能解密,通过公钥加密的密文也只能通过私钥能解密。

非对称加密不需要共享同一份秘钥,安全性要比对称加密高,但由于算法强度比对称加密复杂,加解密的速度比对称加解密的速度要慢。常见的非对称加密有 RSA、ESA、ECC 等。

数字签名
数字签名就是用摘要算法提取出源文件的摘要并用私钥进行加密后的内容。摘要一致则说明文件没有被篡改过,即使摘要被解密也无法还原数据内容。
摘要算法有以下特性:

  • 只要源文本不同,计算得到的结果,必然不同(或者说机会很少)。
  • 无法从结果反推出源数据。

一般使用摘要算法来校验原始内容是否被篡改。常见的摘要算法有 MD5、SHA 等。

数字证书
数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件,用于认证密匙的有效性。一般会包含公钥、公钥拥有者名称、CA 的数字签名、有效期、授权中心名称、证书序列号等信息。

数字证书如何确保列出的用户就是公钥的拥有者呢?关键点是 CA 的数字签名,CA会用自己的私钥将证书内容的摘要进行加密。因为 CA 的公钥是公开的,任何人都可以用公钥解密出 CA 的数字签名的摘要,再用同样的摘要算法提取出证书的摘要和解密 CA 数字签名后的摘要比对,一致则说明这个证书没有被篡改过,可以信任。

参考:https://www.jianshu.com/p/ffe8c203a471

TLS握手过程:
TLS握手协议分为基础握手协议(Basic TLS handshake)与双向认证协议(Client-authenticated TLS handshake)。双向认证协议是在Basic基础上增加了客户端发送证书的步骤。

  1. 客户端发送「_ClientHello_」,内容包括:支持的协议版本,比如TLS1.0版,一个客户端生成的随机数Random1(稍后用于生成“会话密钥”),支持的加密算法(如RSA公钥加密)和支持的压缩算法。
  2. 服务端发送「_ServerHello_」,内容包括:客户端与服务端支持的最高协议版本,一个服务器生成的随机数Random2,CipherSuite与压缩算法(如RSA)。如果是复用session,还会带上session ID。
  3. 服务端发送「_ServerCertificate_」证书。服务器会将自己的证书下发给客户端,其中Certificates即是证书(除了网站的CA证书外,还一并把该CA证书的中级证书下发,所以是一个证书链),证书内包含公钥。
  4. (双向认证)服务端发送CertificateRequest。请求客户端证书。
  5. 服务端发送「_ServerHelloDone_」。完成协商。
  6. (双向认证)客户端发送Certificate。包含客户端证书以及公钥。
  7. 客户端发送「_ClientKeyExchange_」。生成随机数Random3,用证书的公钥加密生成PreMasterSecret。服务端用私钥解密PreMasterSecret得到Random3。
  8. (双向认证)客户端发送CertificateVerify。用客户端证书私钥根据上一个消息生成签名,服务端用客户端公钥解密,确认客户端证书有效。
  9. 双端根据Random1、Random2、Random3用协商的加密算法生成密钥
  10. 客户端发送「_ChangeCipherSpec_」。表示之后数据均以加密方式传输。
  11. 客户端发送「_Finished_」。发送加密的Finished消息,内容是基于前一次消息生成的hash以及Message Authentication Code (MAC)。服务端验证Finished消息是否有效,无效则关闭连接。
  12. 服务端发送「_ChangeCipherSpec_」以及「_Finished_」。同上。
  13. 开始加密数据传输。

基础流程:
The-TLS-handshake-protocol-messages-sequence.png

公私钥交换流程:
1920px-SSL_handshake_with_two_way_authentication_with_certificates.svg.png

TLS 1.3改进
冷启动握手从2-RTT到1-RTT。

  1. 客户端将预测的协议版本和key share发给服务端。
  2. 服务端选择协议并返回key share跟证书(用key share加密)以及Finished。
  3. 客户端用key share验证证书获取公钥,发送Finished。

1_sitCoc2_vodeiFMC1hcU9A.png

Resumption热启动
tls 1.2热启动实现方式是发送ClientHello时带上session ID(缺点是需要每个连接服务器保存session状态)或者session Ticket(序列化的session),服务端确认后直接返回Finished,然后双端复用Pre-master secret,这样只需要1-RTT即可完成握手。但是存在风险是如果Pre-master secret被破解,则session数据就会泄露。
tls 1.3改进了热启动方式,达到0-RTT。具体实现是在初次握手后通过加密通道传输Pre-Shared Key(用于确认使用者身份,而不是密钥),客户端热启动时同时传加密数据以及Pre-Shared Key,服务端如果验证Pre-Shared Key有效则直接解密数据。

tls 1.3冷热启动握手图见spec,搜索figure即可。
https://tools.ietf.org/html/rfc8446#section-4.2.11

常见攻击
Downgrade attack。man-in-the-middle攻击的一种,篡改客户端请求向服务端协商旧版本的加密方式,然后通过已知的旧版本漏洞破解加密请求。通常服务端去掉向后兼容性就可以解决问题,但是会牺牲部分可用性。另外tls 1.3标准定义在双端Finished消息中校验之前所有握手消息的MAC,如果存在篡改则关闭连接。
Replay attack。攻击者sniff并录制正常客户端请求,然后向服务端请求同样的内容,从而欺骗服务端获取敏感数据。例如0-RTT的首次数据场景,因为服务端无法验证数据来源,所以最好的方式是首次请求避免敏感信息、状态改变等。

HTTP/2

相比HTTP1.x,2.0在以下方面做了改进:
Streams, messages, and frames
HTTP2在应用层引入Binary framing机制将传输数据从单一请求-响应包细分成更小的部分进行数据传输,从而可以更灵活地控制数据,引入多路复用、优先级、数据流控制等传输策略。
Binary framing引入Stream、message和frame概念。一个TCP连接传输多个bidirectional streams(包含stream id跟priority);stream由多个messages构成,message是HTTP消息例如一次request或response,包含一个或多个frames;frame包含不同类型的数据,是数据传输最小单位,例如header,body为不同的frame,可以通过stream id进行组装。
image

multiplexing单TCP连接多路复用
一次TCP连接在HTTP1只能一次请求响应,HTTP2将多次请求响应划分为frames,交替(interleave)传输,最终在对端根据stream id进行组装。
image

Stream prioritization
客户端给每个stream分配1-256优先级附在header frame中,再根据stream依赖树请求服务器。RFC没有规定服务端的行为,不同的服务提供商可能实现不同的处理策略,例如cloudflare根据客户端优先级将stream划分为多个池,每个池分配一定的带宽传输数据。

cloudflare solution:https://blog.cloudflare.com/better-http-2-prioritization-for-a-faster-web/
RFC:https://tools.ietf.org/html/rfc7540#page-24

HTTP headers压缩
基本思路是对标准header键值用固定字典编码,自定义键值用动态字典编码,无法用字典情况下用Huffman编码。固定字典是基于RFC标准定义的固定键值字符串排列;动态字典是在一次connection过程中动态更新自定义键值字符串;Huffman编码是用于第一次传输自定义键值,双端解码后在动态字典中更新,第二次传输即可用字典方式编码,Huffman表是RFC基于大量现实header统计的概率表。对自定义头部用预定义字典或动态字典(随一次connection更新)编码。

例子:https://blog.cloudflare.com/hpack-the-silent-killer-feature-of-http-2/
ref:https://tools.ietf.org/html/rfc7541

HTTP/2 Server Push
用于服务端控制资源下发。服务端基于客户端已有的connection,发送PUSH_PROMISE header frame带上资源url以及预留的stream id给客户端,然后传输data frame将资源下发给客户端,期间客户端也可以控制Push参数。与一般客户端请求响应不一样的是,Push需要遵守same-origin policy以及服务端必须是authoritative。
image

RFC: https://tools.ietf.org/html/rfc7540#page-60

HTTP3

HTTP3是将传输层的TCP替换为基于UDP的QUIC协议,应用层对齐实现HTTP1/2的语法,从而解决TCP建立连接慢、队头拥塞等问题。目前HTTP3与QUIC标准处于Internet-Draft状态,还要经过Proposed Standard、Internet Standard两个阶段才能正式成为标准。客户端Chrome和Firefox仅在主线版本支持,另外也有三方库支持服务端/客户端HTTP3,具体见wiki资料。

1_p9TLTlflvZwUQgo4YEpC-g.png

wiki: https://en.wikipedia.org/wiki/HTTP/3

QUIC

QUIC最初被提案时是"Quick UDP Internet Connections"的缩写,是基于UDP的多路复用和安全的通用传输层协议。目前客户端有Chrome、Firefox、Opera、Curl支持,服务端有LiteSpeed、Nginx、Cloudflare支持,截至2019年8月,有3.2%的网站使用QUIC。区别于IETF(Internet Engineering Task Force)的标准QUIC,Google QUIC(gQUIC)本意是设计为通用协议在Chromium中支持HTTP(S),同时也在跟进支持最新的QUIC标准。QUIC具有以下特性:
o Stream multiplexing
o Stream and connection-level flow control
o Low-latency connection establishment
o Connection migration and resilience to NAT rebinding
o Authenticated and encrypted header and payload

QUIC协议内容:
Connection
与服务端的连接。包括握手流程定义,传输协议、加密协议协商。connection ID用于定义endpoints之间的QUIC路由,即使某一端ip或端口改变了,也可以将数据传输中的connection迁移到新的地址,而不需要重新传输已送达的数据。类似IP报头的source/destination address,QUIC数据包Packet的header也包含Source Connection ID(非必须)和Destination Connection ID,这两个ID在双端定义了Packet归属于哪个connection,用于重组数据。ID在QUIC握手时初始化,连接过程中可能被改变。

Stream
用于传输有序字节流数据。分为单向unidirectional和双向bidirectional stream。可以在流程控制(flow control)和限制(stream limits)条件下同时创建任意多个stream传输任意大小的数据,但是不能保证不同stream中传输字节的顺序。发送数据是通过STREAM frames带上stream ID、Offset fields以及data,对端再根据ID和Offset进行重组。

Packet and Frame

  • Packet和Frame是QUIC传输的基础单元,有规定的头部和payload。Packet是从功能角度将QUIC协议划分为不同类型的报文,例如Initial Packet是客户端跟服务端握手过程中的第一个初始化包,Retry Packet是服务端通知客户端重试的包。Frame是从数据类型角度将QUIC协议划分为不同类型的数据帧。例如Initial Packet的Payload字段填充的是CRYPTO frame,CRYPTO frame包含cryptographic handshake message, ACK frames, or both。
  • QUIC将Stream分为Packet以及Frame传输是为了解决队头拥塞(head-of-line blocking)问题。Stream某个Packet丢失只需要重传这个Packet就可以,其他Packet不会因此阻塞。
  • 一个UDP包可以装载多个Packet,一个Packet可以装载多个Frame。

QUIC-Figure-2.png

关于Packet:

  • Packet分为Long Header Packets和Short Header Packets,LHP用于控制类例如Version Negotiation/Initial/Handshake Packet等固定header较多的Packet。SHP用于建立连接后,用最少的overhead传输数据。
  • 除了Version Negotiation和Retry类型,其他所有packet都用AEAD(authenticated encryption with additional data)方式加密保证数据的保密和完整性。
  • 应用层可以在Packet中打包尽可能多的frames以减少带宽浪费和CPU消耗,但是等待新的frame可能导致Packet迟迟不发。

握手流程
下图是1-RTT握手流程,每行格式是"{packet_type}[{packet_num}]: {frame_type}[{frame_payload}] {frame_type1}[{frame_payload1}] ..."
1.客户端发送Initial包。包含客户端Source Connection ID(从0开始递增)以及TLS握手帧CRYPTO Frame(Client Hello bytes)。
2.服务端发送UDP包。UDP中包括三类Packet。Initial包,包含CRYPTO Frame(Server Hello bytes)以及ACK(请求的packet_num);QUIC握手帧HandShake包,包含CRYPTO Frame(证书);1-RTT encrypted包,包含数据帧STREAM Frame(Stream ID,帧Offset,数据长度以及字节数据)。
3.客户端发送UDP包。UDP中包括三类Packet。Initial包,包含ACK;HandShake包,包含结束的CRYPTO Frame以及ACK;1-RTT encrypted包,包含返回数据帧STREAM Frame以及ACK。
4.服务端发送UDP包。UDP中包括两类Packet。数据包1-RTT encrypted以及握手包HandShake。

WX20191221-110539@2x.png

下图是QUIC 0-RTT握手流程。与TLS Resumption热启动优化思路类似。具体流程见RFC。
WX20191221-195632@2x.png

流量控制(Flow Control)
流量控制是对接收方的数据缓冲大小限制,从而避免快速发送方碾压慢速接收方及恶意发送者大量消耗接收方内存的情况。同样,为了限制连接内的并发,QUIC终端控制其对端可以发起的最大累计stream。具体有以下几项:

  • 数据流控制(Data Flow Control)。限制单个stream或单个connection接收的字节数。
  • 流余额增量(Flow Credit Increments)。RFC未强制规定,只是提供了一些建议。例如服务端通过发送MAX_STREAM_DATA或MAX_DATA帧给客户端动态放水,控制流量。
  • Stream取消机制(Handling Stream Cancellation)。当双端对流量控制策略不一致时,需要有取消机制结束或者重置Stream。RESET_STREAM或CONNECTION_CLOSE帧可以重置或关闭Stream。
  • Stream总大小(Stream Final Size)。当RESET_STREAM或者有新的STREAM帧到达,如果实际的size跟预定的final size不一致,则发送FINAL_SIZE_ERROR帧。
  • 并发控制(Controlling Concurrency)。只有stream ID小于(max_stream * 4 + initial_stream_id_for_type)才能被open。

连接迁移(Connection Migration)
当连接一方的地址发生改变,将旧连接迁移到新的地址上,避免重传已接收的数据。
必要条件:
因为QUIC在握手过程中地址必须不变,所以需要在握手完成之后才能发起连接迁移。
除了服务端使用Preferred Address情况下,迁移只能由客户端发起。
迁移步骤:
1.探测地址是否可达。客户端发送PATH_CHALLENGE帧(包含自定义Data),服务端响应PATH_RESPONSE(包含请求的自定义Data)。如果发生超时,则地址不可达。同时为了确保服务端有可用的connection ID,客户端可以发送NEW_CONNECTION_ID帧创建新的connection。
2.(可选)初始化新的connection。重置拥塞控制congestion controller以及拥塞通知ECN capability。
3.发起迁移。客户端用新地址发送non-probing帧(除了PATH_CHALLENGE, PATH_RESPONSE, NEW_CONNECTION_ID, PADDING以外的帧类型),服务端回包并且验证客户端地址,即可完成连接迁移。

常见网络攻击以及防御方案
Handshake Denial of Service
攻击方法:其目的在於使目標電腦的網路或系統資源耗盡,使服务暂时中斷或停止,导致其正常用户无法访问。例如针对TCP常见的SYN flood attack,不断发送SYN包要求服务器建立连接,导致所有端口被异常占用。
QUIC防御方案:加密握手完成后,所有包都是加密并且身份验证过,不符合的包会被丢弃。

Amplification Attack
攻击方法:思路是攻击者伪造目标IP向第三方发起请求,第三方返回更多数据给目标导致资源耗尽。针对QUIC攻击的具体实现是攻击者首先连接第三方获得address validation token,然后用此token以及目标IP发起0-RTT请求,伪造目标IP热启动,第三方验证热启动token合法,则发送0-RTT响应给目标IP。
防御方案:限制address validation tokens的使用和生命周期,例如短时间内不接收多个相同token。

Optimistic ACK Attack
攻击方法:增加ACK参数中收到数据长度,欺骗服务端传输比实际带宽要多得多的数据。
防御方案:QUIC在发送Packet时会累加packet numbers,所以服务端通过刻意跳过某些packet numbers刻意检测出客户端是否恶意发包。

Slowloris Attacks
Stream Commitment Attack
攻击方法:客户端创建尽可能多的connection或者stream,持续发送少量心跳数据,导致服务端资源被占用。
防御方案:通过接入层防御,部署QUIC时限制每个IP的连接数、限制长连接等。

Stream Fragmentation and Reassembly Attacks
攻击方法:发送方故意只发送stream部分数据,导致接收方需要创建整个stream大小的buffer或数据结构。或者接收方故意不发送ACK包,导致发送方一直持有并重传发送数据。
防御方案:根据可用内存限制flow control的window大小,防止内存占用超过资源。

Stateless Reset Oracle
攻击方法:思路是攻击者伪造RESET包使服务端正常连接被重置,类似的攻击有TCP reset injection,最常见的例子是访问google出现"The connection was reset"。QUIC的RESET包的stateless reset token是由static key以及connection ID计算得出,攻击者将正常Packet转发到其他共享static key并且没有connection的endpoint,则服务端会误以为connection不存在继而发送RESET包并且重置连接。
防御方案:服务端管理共享static key的endpoint,确保Packet能发送到有connection的endpoint。

Version Downgrade
攻击方法:通过版本协商使用低版本不安全的QUIC。
防御方案:QUIC标准暂无多版本的协商行为。

QUIC RFC: https://tools.ietf.org/html/draft-ietf-quic-transport-24
QUIC with TLS RFC: https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-introduction
中文QUIC RFC: http://docs.wxclimb.top/draft-ietf-quic-transport-zh.html#fc-credit

Challenges remaining for QUIC

网络基础设施已经基于TCP存在广泛的优化,但是对UDP是限速甚至是禁止。Google在早期实验中就存在少量连接被拒绝的问题。

Does QUIC make the world faster ?

对于网络耗时,论文[1]对比了HTTP2跟QUIC+SPDY,在不同网络环境下测试网页加载时间/资源请求耗时。结论是:

  1. QUIC在少量小资源/大资源/弱网情况下占优:QUIC is faster (1.2-4.5X) when pages consist of few small-sized objects. QUIC also performs better when the page consists of large-sized objects. QUIC can achieve faster page loads in poor network conditions of lower bandwidth, high delay and lossy network.
  2. QUIC在大量小资源情况下不如HTTP2:However, Page load with QUIC is slower (1.1-3.2X) when page consists of many small-sized objects. One possible reason for this is that the QUIC toy server is not optimized to be used efficiently with Chromium browser.

2019年论文[2]对TCP做业界通用的优化,对齐QUIC传输层参数,测试不同网络环境下页面加载/显示时间。结论是QUIC均优于TCP(HTTP2),弱网环境下优势更明显。
还有资料[3]从实际应用角度提出对QUIC质疑。例如端对端加密限制网络链路的优化,CPU以及内存占用高,拥塞控制(congestion control)可能抢占其他类型的连接带宽等。

[1]P. Biswal, O. Gnawali, "Does QUIC make the Web faster?", Proc. IEEE GLOBECOM, pp. 1-6, Dec. 2016. http://www2.cs.uh.edu/~gnawali/papers/quic-globecom2016.pdf
[2]"A Performance Perspective on Web Optimized Protocol Stacks: TCP+TLS+HTTP/2 vs. QUIC" arXiv:1906.07415v1 [cs.NI] 18 Jun 2019. https://arxiv.org/pdf/1906.07415.pdf
[3]"QUIC and HTTP/3 : Too big to fail?!" https://calendar.perfplanet.com/2018/quic-and-http-3-too-big-to-fail/
https://en.wikipedia.org/wiki/QUIC#cite_note-QUIC_Design_Doc-3
https://blog.cloudflare.com/the-road-to-quic/
https://yucianga.info/?p=819

附录

常用请求码:
1xx(临时响应)
表示临时响应并需要请求者继续执行操作的状态代码。

代码 说明
100 Continue(继续) 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。
101 Switching Protocols(切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。

2xx (成功)
表示成功处理了请求的状态代码。

代码 说明
200 OK(成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
201 Created(已创建) 请求成功并且服务器创建了新的资源。
202 Accepted(已接受) 服务器已接受请求,但尚未处理。
203 Non-Authoritative Information(非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
204 No Content(无内容) 服务器成功处理了请求,但没有返回任何内容。
205 Reset Content(重置内容) 服务器成功处理了请求,但没有返回任何内容。
206 Partial Content(部分内容) 服务器成功处理了部分 GET 请求。

3xx (重定向)
表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。

代码 说明
300 Multiple Choices(多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301 Moved Permanently(永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 Found(临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303 See Other(查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304 Not Modified(未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305 Use Proxy(使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307 Temporary Redirect(临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

4xx(请求错误)
这些状态代码表示请求可能出错,妨碍了服务器的处理。

代码 说明
400 Bad Request(错误请求) 服务器不理解请求的语法。
401 Unauthorized(未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
403 Forbidden(禁止) 服务器拒绝请求。
404 Not Found(未找到) 服务器找不到请求的网页。
405 Method Not Allowed(方法禁用) 禁用请求中指定的方法。
406 Not Acceptable(不接受) 无法使用请求的内容特性响应请求的网页。
407 Proxy Authentication Required(需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408 Request Timeout(请求超时) 服务器等候请求时发生超时。
409 Conflict(冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
410 Gone(已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
411 Length Required(需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412 Precondition Failed(未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
413 Request Entity Too Large(请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414 Request-URI Too Long(请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
415 Unsupported Media Type(不支持的媒体类型) 请求的格式不受请求页面的支持。
416 Requested Range Not Satisfiable(请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
417 Expectation Failed(未满足期望值) 服务器未满足"期望"请求标头字段的要求。

5xx(服务器错误)
这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。

代码 说明
500 Internal Server Error(服务器内部错误) 服务器遇到错误,无法完成请求。
501 Not Implemented(尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 Bad Gateway(错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 Service Unavailable(服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 Gateway Timeout(网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 HTTP Version Not Supported(HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

阅读 486发布于 2019-12-24

推荐阅读
目录