一条HTTP请求的生命周期(一)-- HTTP/1.1

1 Introduction https://www.rfc-editor.org/in...
1.1 Purpose

超文本传输协议(HTTP)是一种为分布式,合作式,多媒体信息系统服务的,面向应用层的协议允许消息以类似MIME的格式传送 功能缺失:分层代理缓存持久化连接虚拟主机建立在 URI(URL URN)之上 请求方法 请求头 Multipurpose Internet Mail Extensions (MIME)是一种用户代理和网关/代理到其他互联网服务器的通用协议。 这些网络程序可能由 SMTP [16], NNTP [13], FTP [18], Gopher [2], and WAIS [10] 协议构成

1.3 Terminology 术语
connection A transport layer virtual circuit established between two programs for the purpose of communication.message HTTP 通信基本单元,使用字节序列通过 connection 传输request An HTTP request messageresponse An HTTP response messageresource 用 URI 标识网络数据对象和服务,资源可以有多种表示形式(例如多种语言、数据格式、大小和分辨率)entity 请求头(metainformation 元信息) + 请求体,section 7representation 表示 特定 response status 有多种表示content negotiation 内容协商 处理请求选择适当的表现机制。所有响应中实体的表示都是可以协商的(包括错误响应) section 12variant 变体 给定任何时候,一个 resource 可能对应一个或多个 representation,每种 representation 都称为 varriant varriant 不代表 resource 受制于 content negotiationclient 为发送请求而建立连接的程序user agent 用户代理 发起请求的客户端server 接收连接返回响应的应用程序。每个程序都可以是 origin server, proxy, gateway, or tunnel, 基于他们每个请求的行为。origin server 源服务器 The server on which a given resource resides or is to be created. 特定资源创建或所在的服务器proxy 代理器 中间服务器,MUST 同时实现 client sever。为请求提供服务或转发(可能会转换)到其他服务器。 transparent proxy:透明服务器,不修改请求和响应,用户验证和识别除外 non-transparent proxy:非透明服务器,修改请求和响应。为 user agent 添加一个服务,比如 group annotation services, media type transformation, protocol reduction, or anonymity filtering。 除非明确声明了透明、非透明,否则 HTTP proxy requirements 同时支持这两种模式gateway 网关 网关对请求方来说就像源服务器一样tunnel 请求的两端关闭,隧道也不复存在first-head 响应直接来自 origin server,没经过 proxy。upstream/downstream 上游 下游 Upstream and downstream 描述信息流,所有信息都是从上游流向下游。 此处的信息是指请求+响应码?inbound/outbound inbound:向 origin server 移动 outbound:向 user agent 移动

1.4 Overall Operation
HTTP protocol 是 request/response 协议. 客户端通过一条与服务端的连接发送请求, 服务端处理请求后返回响应请求格式: request method, URI, protocol version MIME-like message containing reques modifiers, client information, possible body content响应格式: status line:message's protocol version, success or error code MIME-like message containing server information, entity metainformation, possible entity-body content.HTTP 与 MIME 的关系位于附录 19.4.---------------------------- demo 1 ---------------------------- connection (v)user agent (UA)origin server (O).request chain ------------------------> UA -------------------v------------------- O <----------------------- response chain---------------------------- demo 2 ----------------------------当 request/response chain 中存在 intermediaries 时,情况会变复杂。 有三种常见 intermediaries:proxy, gateway, and tunnel. proxy:转发代理,接受绝对形式的 uri 请求,重写 message,重新格式化 request 然后转发 gateway:必要时转换请求的协议。 tunnel:不改写消息,通过 intermediary(例如 firewall),或者 intermediary 无法理解消息时可以使用 tunnelrequest chain --------------------------------------> UA -----v----- A -----v----- B -----v----- C -----v----- O <------------------------------------- response chain上图显示了 user agent/origin server 之间的三个中介体(A、B和C),需要四个独立的连接。 这个区别很重要,某些HTTP通信选项分别适用于临近节点,非隧道的临近节点,调用链的终端,任意节点。---------------------------- demo 3 | 缓存 ----------------------------request chain ----------> UA -----v----- A -----v----- B - - - - - - C - - - - - - O <--------- response chain省略关于缓存的一千字 ......---------------------------- ---------------------------- ----------------------------HTTP 通信通常使用 TCP/IP connections,默认端口 TCP 80。可以使用任意 Internet 或其他协议。 HTTP 假设传输是可靠的,任意可靠传输的协议都可以使用; HTTP1.1 请求、响应的结构到 transport data units 的映射不在本规范范围内。 HTTP1.1 连接可复用,尽管可能因各种原因关闭(see section 8.1)

2 Notational Conventions and Generic Grammar 符号习惯和一般语法 2.1 Augmented BNF 增强型 Backus-Naur Form
本文规定的所有机制都可以用两种方式描述:散文体(prose)和类似于RFC 822的扩充Backus-Naur Form(BNF)name = definition name 代表规则的名称(不能包括 '<' '>' 字符),使用 = 将名称和定义分开,空白是定义的分隔符。 基本规则用大写,例如SP, LWS, HT, CRLF, DIGIT, ALPHA '<' '>' 可以包含在定义中,用于标识规则名。literal(字面量) 文本需加 '', 不区分大小写rule1 | rule2rule1 或 rule2 (rule1 rule2)() 包起来的元素视为单一元素 *rule重复 * 表示 0~inf * 表示 n到m次 [rule][foo bar] == *1(foo bar) N rule(element) == *(element) #rule类似于 *,将元素用 (",") 以及 (LWS) 隔开 1#element == ( *LWS element *( *LWS "," *LWS element )) 允许出现 (element), , (element) ; 注释 implied *LWS元素之间需要一个分隔符

2.2 Basic Rules
US-ASCII(美国信息交换标准码)编码字符集是由ANSI X3.4-1986定义
OCTET= CHAR= UPALPHA= LOALPHA= ALPHA= UPALPHA | LOALPHA DIGIT= CTL= CR= LF= SP= HT= <">= CRLF= CR LF HTTP/1.1 将 CR LF 定义为行尾标志 LWS= [CRLF] 1*( SP | HT ) 与 SP 具有相同的语义 TEXT= HEX= "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT token= 1* separators= "(" | ")" | "<" | ">" | "@" | "," | "; " | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT --------------- 注释相关 --------------- comment= "(" *( ctext | quoted-pair | comment ) ")" ctext= quoted-string= ( <"> *(qdtext | quoted-pair ) <"> ) qdtext= >quoted-pair= "\" CHAR

3 Protocol Parameters 协议参数 3.1 HTTP Version
格式 . HTTP-Version= "HTTP" "/" 1*DIGIT "." 1*DIGIT HTTP/1.0HTTP/1.1网关/代理若收到高版本的消息,MUST降低请求的版本、报错、切换到 tunnel不同版本之间,请求头会有一定兼容性问题

3.2 Uniform Resource Identifiers
URIs 别名: WWW addresses, Universal Document Identifiers, Universal Resource Identifiers, URL, URN 对 HTTP 来说 URL 仅仅是格式化的字符串

3.2.2 http URL
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]] port default 80 避免使用 IP 代替 host

3.2.3 URI Comparison
一个一个字节比较,并区分大小写 特殊情况 - 端口有默认值,(见RFC 2396)里的默认端口 - host 不分大小写 - scheme 不分大小写 - abs_path 为空等同与 "/"除了"保留(reserved)"和"不安全(unsafe)"字符集里的字符(参见RFC 2396) 其他字符等效于他们的 "%HEXHEX"编码http://abc.com:80/~smith/home.html http://ABC.com/%7Esmith/home.html http://ABC.com:/%7esmith/home.html

3.3 Date/Time Formats
3.4 Character Sets
charset = token charset 最好符合IETF Policy on Character Sets and Languages(https://www.rfc-editor.org/rfc/rfc2277) 的要求----------------- demo ----------------- Content-Type: text/plain; charset=UTF-8

3.4.1 被忽略的字符集
有些 HTTP 1.0 不能处理在Content-Type头域里明确指定的字符集参数 (entity body,译注:这里翻译成“实体主体”因为Content-Type头是实体头,消息头可以分为实体头,常用头,请求头,响应头,在译文中多次用到“头”和“头域”,如消息头,消息头域,其实是同一个意思,HTTP1.1协议有时候概念并不是完全统一的)

3.5 内容编码(Content Codings)
content-coding= token gzip compress Welch deflate identity(default)

3.6 传输编码 (Transfer Codings)
3.6.1块传输编码(Chunked Transfer Coding) 3.7 媒体类型(Media Type)
HTTP 在头字段 Content-Type, Accept 中使用 Internet Media Typesmedia-type= type "/" subtype *( "; " parameter ) type= token subtype= tokenContent-Type: text/html; charset=UTF-8 Media-type 必须在 IANA 注册过 未注册的媒体类型不鼓励使用

3.7.1规范化和文本缺省 (Canonicalization and Text Defaults)
HTTP应用程序 MUST 能接收CRLF,CR和LF作为文本媒体的换行符 HTTP允许应用字符集里等价于CR和LF的字节序列来表示换行符实体主体部分可以使用 CR和LF,其他不行 默认 ISO-8859-1

3.7.2多部分类型(Multipart type) 4 HTTP Message 4.1 Message Types 消息类型
HTTP-message = Request|Response ; HTTP/1.1格式: generic-message = start-line *(message-header CRLF) CRLF [ message-body ]start-line = Request-Line | Status-Line为了健壮性,服务器应该忽略任意请求行(Request-Line)前面的空行某些由问题的 HTTP/1.0 实现会在请求后面加一些 CRLF 一个HTTP/1.1客户端MUST NOT在请求前和请求后加 CRLF

4.2 Message Headers
header 分类: general-header (section 4.5) request-header (section 5.3) response-header (section 6.2) entity-header (section 7.1)格式: message-header = field-name ":" [ field-value ] field-name= token field-value= https://www.it610.com/article/*( field-content | LWS ) field-content= LWS 出现在 field-content 中 MAY 会被 SP 代替

头字段顺序的 "good practice" 1. general-header fields 2. request-header or response-header fields 3. entity-header当一个 header 有多个值,网关代理 MUST 按原来的值顺序转发。 cache-control: no-cache, no-store, no-transform

4.3 Message body 消息主体
message-body 用于承载请求和响应的 entity-bodymessage-body = entity-body | Transfer-Encoding MUST 用于指定 transfer-codings Transfer-Encoding 是消息的属性,不是实体的属性消息主体是否出现在消息中的判断条件 1. 由 header Content-Length 或 Transfer-Encoding 来暗示。 2. request Method 3. response Method or 响应状态码(1XX 204 304)

4.4 Message Length 消息长度
message 的 transfer-length 是 message-body 的长度; transfer-length 由以下条件决定 (按优先级排序): 1. response message MUST NOT 包括 message-body such as 1xx, 204, and 304 请求方法为 HEAD 的响应 2. Transfer-Encoding 存在, 值不为 identity。transfer-length 定义在 chunked 中(section 3.6) 3. Content-Length 存在,值为 entity-length 用 OCTETs 表示的十进制。若 entity-length 与 transfer-length 不相等,说明使用了 Transfer-Encoding。同时使用 Transfer-Encoding 和 Content-Length,Content-Length会被忽略 4. multipart/byteranges(自定义媒体),客户端需与服务端协商好传输长度。可以使用 header:RangeHTTP1.1 存在 Transfer-Encoding 包含消息体,但是 Content-Length 不存在, 服务器 SHOULD 响应 400 (bad request) 或者 411 (length required) MUST 接收 "chunked" 传输编码(section 3.6) 同时存在 Transfer-Encoding(值不为 identity)和 Content-Length,Content-Length MUST 被忽略

4.5 General Header Fields 常用头
有些 header 即适用于 请求,也适用于响应,但不适用与 实体。
general-header =Cache-Control; Section 14.9 | Connection; Section 14.10 | Date; Section 14.18 | Pragma; Section 14.32 | Trailer; Section 14.40 | Transfer-Encoding; Section 14.41 | Upgrade; Section 14.42 | Via; Section 14.45 | Warning; Section 14.46

5 Request 请求
Request= Request-Line; Section 5.1 *(( general-header; Section 4.5 | request-header; Section 5.3 | entity-header ) CRLF); Section 7.1 CRLF [ message-body ]; Section 4.3

5.1 Request-Line
Request-Line= Method SP Request-URI SP HTTP-Version CRLF

5.1.1 Method
Method= "OPTIONS"; Section 9.2 | "GET"; Section 9.3 | "HEAD"; Section 9.4 | "POST"; Section 9.5 | "PUT"; Section 9.6 | "DELETE"; Section 9.7 | "TRACE"; Section 9.8 | "CONNECT"; Section 9.9 | extension-method extension-method = token405 (Method Not Allowed) 501 (Not Implemented) GET and HEAD MUST be supported

5.1.2 Request-URI
Request-URI="*" | absoluteURI | abs_path | authotityOPTIONS*HTTP/1.1absoluteURI GET http://www.w3.org/pub/www/TheProject.html HTTP/1.1abs_path GET/pub/WWW/TheProject.htmlHTTP/1.1 Host:www.w3.org

5.2 请求资源 The Resource Identified by a Request
Internet request 资源标识通过 Request-URI 和 Host header field. 1. Request-URI 是 absoluteURI, MUST 忽略 Host 2. Request-URI 非 absoluteURI, Host 决定 host 3. 不满足 1, 2。 response MUST 400(Bad Request)

5.3 请求头 Request Header Fields
请求的附加消息或客户端的附加消息 request-header = Accept; Section 14.1 | Accept-Charset; Section 14.2 | Accept-Encoding; Section 14.3 | Accept-Language; Section 14.4 | Authorization; Section 14.8 | Expect; Section 14.20 | From; Section 14.22 | Host; Section 14.23 | If-Match; Section 14.24 | If-Modified-Since; Section 14.25 | If-None-Match; Section 14.26 | If-Range; Section 14.27 | If-Unmodified-Since; Section 14.28 | Max-Forwards; Section 14.31 | Proxy-Authorization; Section 14.34 | Range; Section 14.35 | Referer; Section 14.36 | TE; Section 14.39 | User-Agent; Section 14.43

6 Response 响应
Response= Status-Line; Section 6.1 *(( general-header; Section 4.5 | response-header; Section 6.2 | entity-header ) CRLF); Section 7.1 CRLF [ message-body ]; Section 7.2

6.1 Status-Line
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

6.1.1 Status Code and Reason Phrase
1xx: Informational 消息 - Request received, continuing process 接收到消息,继续进程 2xx: Success 成功 - The action was successfully received, understood, and accepted 3xx: Redirection 重定向 - Further action must 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

Status-Code = |"200"; 10.2.1节: OK | extension-codeextension-code =3DIGIT Reason-Phrase = *具体 code 见原文 https://www.rfc-editor.org/rfc/rfc2616.html#section-6.1.1

6.2 Response Header Fields
响应的附加消息或服务端的附加消息 response-header = Accept-Ranges; Section 14.5 | Age; Section 14.6 | ETag; Section 14.19 | Location; Section 14.30 | Proxy-Authenticate; Section 14.33 | Retry-After; Section 14.37 | Server; Section 14.38 | Vary; Section 14.44 | WWW-Authenticate; Section 14.47

7 Entity 实体
Request and Response messages MAY 传输实体,如果不受 request method 或 response status code 限制. entity = entity-header fields + entity-body

7.1 Entity Header Fields
entity-header= Allow; Section 14.7 | Content-Encoding; Section 14.11 | Content-Language; Section 14.12 | Content-Length; Section 14.13 | Content-Location; Section 14.14 | Content-MD5; Section 14.15 | Content-Range; Section 14.16 | Content-Type; Section 14.17 | Expires; Section 14.21 | Last-Modified; Section 14.29 | extension-headerextension-header = message-header接收方可以忽略未识别 header

7.2 Entity Body
entity-body= *OCTET entity-body 由 message-body 根据 Transfer-Encoding decoding 后得到

7.2.1 Type 消息体的数据类型由 Content-Encoding 和 Content-Type 指定
entity-body := Content-Encoding( Content-Type( data ) ) Content-Type 指定数据的 media type Content-Encoding 指定 content codingsMAY 媒体类型首先看 Content-Type,其次从数据内容或URI来推断, SHOULD 最后指定为 application/octec-stream

7.2.2 Entity Length
transfer-coding 之前的长度

8 连接 Connections 8.1 持久化连接 Persistent Connections
8.1.1 目的 Purpose
持久化连接有数个优势: 1. 减少TCP开启关闭次数, 节省路由器和主机 (hosts:clients, servers, proxies, gateways, tunnels, or caches) 的CPU time, 节省主机上 TCP protocol control blocks 占用的内存。 2. 可以在连接上开启 Pipelining。允许客户端发出多个请求而无需等待每个响应。 3. 减少报文数量,并有足够的时间确定网络拥塞(congestion)状态,减少网络拥塞 4. 后续连接,节省了三次握手 5. 报错后无需关闭 TCP 连接,可以乐观的尝试新特性。SHOULD 实现持久化连接

8.1.2 整体操作 Overall Operation
HTTP 1.1 默认持久化连接Persistent connections 可以使用 header Connection 来关闭 close of a TCP connection 一旦发送关闭信号, 客户端 MUST NOT 堆这条连接发送任何请求

8.1.2.1 协商(Negotiation)
HTTP/1.1 client 和 server 默认保持连接,直到请求头 Connection 携带 connection-token close HTTP/1.0 向后兼容见 section 19.6.2 持久化连接所有消息 MUST 携带 message length, 详情见 section 4.4

8.1.2.2 流水线Pipelining
MUST:流水线必须在持久化连接上开启 SHOULD:使用流水线时,需要使用幂等方法(see section 9.1.2)。

8.1.3 Proxy Servers
MUST: 代理不能为 HTTP/1.0 的客户端建立持久化连接

8.1.4 最佳实践 Practical Considerations
1. 需要为非活跃中的连接设置一个超时时间(time-out)。 2. SHOULD:客户端服务器超时关闭时,应该按规范关闭连接。客户端和服务器需要时刻查看对方是否关闭了连接。 3. MAY:客户端,服务器,代理可以在任何时候关闭连接。当服务器关闭连接时,客户端发起请求,建议使用重试+幂等方法保障这次请求的成功 4. 服务器的连接数建议保持在2N, N = 同时在线用户数以上准则都是为了降低响应时间和避免阻塞

8.2 消息传送要求 Message Transmission Requirements
8.2.1 持久化连接和流量控制 Persistent Connections and Flow Control
HTTP/1.1服务器应当保持持续连接并使用TCP流量控制机制来解决临时过载。 客户端重试会导致拥塞恶化

8.2.2 监控连接的错误状态
SHOULD:HTTP/1.1 (or later) client 发送 message-body 时应该监控 network connection 的状态。发现错误立即停止消息主体的发送。 使用 chuck 传输,可以用长度为0的块和empty trailer来结束消息。 header 上有 Content-Length MUST 马上关闭连接

8.2.4 服务端过早关闭连接时客户端的行为
// TODO

9 方法定义 方法有很多, 此处只关注 GET POST
9.1 安全和等幂(Idempotent)方法
9.1.1安全方法
GET 获取资源时安全,action(执行动作)时不保证安全 POST 执行动作时安全GET查询安全 POST 增删改查都安全

9.1.2 等幂方法
GET POST 都是幂等方法 除了 error or expiration 问题,相同参数返回相同结果

9.3 GET
当请求头中包含If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range,GET 方法语义将改为 "conditional GET" 满足条件时响应中返回实体,否则使用缓存。GET请求的响应是可缓存的(cacheable),详情见 section 13.使用表单时的安全问题,见 section 15.1.3

9.5 POST
功能如下: -已存在的资源的注释; -发布消息给一个布告板,新闻组,邮件列表,或者相似的文章组。 -提供一个数据块,如提交一个表单给一个数据处理过程。 -通过追加操作来扩展数据库。响应可缓存,除非响应头中包含 Cache-Control 或 Expires。

10 状态码 RFC 2616:超文本传输协议 -- HTTP/1.1#section-10
11 访问认证 12 内容协商 Content Negotiation
HTTP 提供了几种内容协商的机制 -- 多种表示方式可用时,为响应选择最佳表示方式。内容协商不是格式协商,因为 representations 可能是同样的 media type,但是利用了 media type 的不同性质,例如语言内容协商在HTTP中由两种类型:服务器驱动协商和代理驱动协商。也可以联合使用

12.1 服务器驱动协商(Server-driven Negotiation)
通过服务器算法选择响应最好的表现形式。

12.2 代理驱动协商 (Agent-driven Negotiation)
12.3 透明协商(Transparent Negotiation)
13. 缓存 Cache 14. 请求头定义 14.7 Allow
Allow= "Allow" ":" #Method Allow: GET, HEAD, PUT

14.10 Connection
Connection = "Connection" ":" 1#(connection-token) connection-token= token Connection: close

14.13 Content-Length
Content-Length = "Content-Length" ":" 1*DIGIT Content-Length: 3495限制条件见 section 4.4

14.17 Content-Type
Content-Type = "Content-Type" ":" media-type Content-Type: text/html; charset=ISO-8859-4

【一条HTTP请求的生命周期(一)-- HTTP/1.1】......

    推荐阅读