http2
http2:
链接地址:http://http2.github.io/http2-spec/index.html
http1.1:采用文本协议,虽然支持连接复用,但是在返回的时候仍然是顺序串行话的,导致很多网站采用多个域名同时建立多个链接来提升性能,
造成冗长和重复,导致不必要的网络io及tcp消耗
http2:由于上一个版本存在的问题,采用了spdy的思想,使用binary 协议,加上frame、stream的概念
1、header压缩
2、connection共用
3、使用二进制frame作为单元传输
4、push promise 服务器端的预推送
5、增加优先级概念及flow control
http2有两个版本通过h2、h2c来标识,h2标识通过TLS传输、h2c标识cleartext明文传输
在查询server是否使用http2时可以使用如下头
GET / HTTP/1.1 Host: server.example.com Connection: Upgrade, HTTP2-Settings Upgrade: h2c HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>
A server 如果不支持那么upgrade头不会出现如下:
HTTP/1.1 200 OK Content-Length: 243 Content-Type: text/html
支持的话如下:
HTTP/1.1 101 Switching Protocols Connection: Upgrade Upgrade: h2c [ HTTP/2 connection ...
如果一个请求升级到http2的头必须包含一个HTTP2-Settings header field. The HTTP2-Settings header field is a connection-specific header field that includes parameters that govern the HTTP/2 connection, provided in anticipation of the server accepting the request to upgrade.
HTTP2-Settings = token68
Frame的格式
All frames begin with a fixed 9-octet header followed by a variable-length payload.
+-----------------------------------------------+ | Length (24) | +---------------+---------------+---------------+ | Type (8) | Flags (8) | +-+-------------+---------------+-------------------------------+ |R| Stream Identifier (31) | +=+=============================================================+ | Frame Payload (0...) ... +---------------------------------------------------------------+
Figure 1: Frame Layout
The fields of the frame header are defined as:
- Length:
-
The length of the frame payload expressed as an unsigned 24-bit integer. Values greater than 214(16,384) MUST NOT be sent unless the receiver has set a larger value forSETTINGS_MAX_FRAME_SIZE.
The 9 octets of the frame header are not included in this value.
- Type:
-
The 8-bit type of the frame. The frame type determines the format and semantics of the frame. Implementations MUST ignore and discard any frame that has a type that is unknown.
- Flags:
-
An 8-bit field reserved for boolean flags specific to the frame type.
Flags are assigned semantics specific to the indicated frame type. Flags that have no defined semantics for a particular frame type MUST be ignored and MUST be left unset (0x0) when sending.
- R:
-
A reserved 1-bit field. The semantics of this bit are undefined, and the bit MUST remain unset (0x0) when sending and MUST be ignored when receiving.
- Stream Identifier:
-
A stream identifier (see Section 5.1.1) expressed as an unsigned 31-bit integer. The value 0x0 is reserved for frames that are associated with the connection as a whole as opposed to an individual stream.
The structure and content of the frame payload is dependent entirely on the frame type.
frame的大小由SETTINGS_MAX_FRAME_SIZE settings 决定
HEADER传输采用由一系列不中断的header blocks,最后一个headers或者CONTINUATION包含end_headers 标识,如下组成
+---------------+ |Pad Length? (8)| +-+-------------+-----------------------------------------------+ |E| Stream Dependency? (31) | +-+-------------+-----------------------------------------------+ | Weight? (8) | +-+-------------+-----------------------------------------------+ | Header Block Fragment (*) ... +---------------------------------------------------------------+ | Padding (*) ... +---------------------------------------------------------------+
DATA:如下组成
+---------------+ |Pad Length? (8)| +---------------+-----------------------------------------------+ | Data (*) ... +---------------------------------------------------------------+ | Padding (*) ... +---------------------------------------------------------------+
http2还包含各种frame如SETTINGS(包含全局设置如flow control大小,也包含stream设置)、RST_STREAM(取消或重置当前的stream)、PUSH_PROMISE(预推送)、PING(侦测链接是否可用)、GOAWAY(关闭链接一般包含一个比当前链接的stream都要大的id,可以优雅的结束当前的小于id的stream)、WINDOW_UPDATE(窗口大小用于flow control)
http1.1与http2例子对比:
request:
GET /resource HTTP/1.1 HEADERS Host: example.org ==> + END_STREAM Accept: image/jpeg + END_HEADERS :method = GET :scheme = https :path = /resource host = example.org accept = image/jpeg
reponse:
HTTP/1.1 304 Not Modified HEADERS ETag: "xyzzy" ==> + END_STREAM Expires: Thu, 23 Jan ... + END_HEADERS :status = 304 etag = "xyzzy" expires = Thu, 23 Jan ...
request:
POST /resource HTTP/1.1 HEADERS Host: example.org ==> - END_STREAM Content-Type: image/jpeg - END_HEADERS Content-Length: 123 :method = POST :path = /resource {binary data} :scheme = https CONTINUATION + END_HEADERS content-type = image/jpeg host = example.org content-length = 123 DATA + END_STREAM {binary data}
reponse:
HTTP/1.1 200 OK HEADERS Content-Type: image/jpeg ==> - END_STREAM Content-Length: 123 + END_HEADERS :status = 200 {binary data} content-type = image/jpeg content-length = 123 DATA + END_STREAM {binary data}
HTTP/1.1 100 Continue HEADERS Extension-Field: bar ==> - END_STREAM + END_HEADERS :status = 100 extension-field = bar HTTP/1.1 200 OK HEADERS Content-Type: image/jpeg ==> - END_STREAM Transfer-Encoding: chunked + END_HEADERS Trailer: Foo :status = 200 content-length = 123 123 content-type = image/jpeg {binary data} trailer = Foo 0 Foo: bar DATA - END_STREAM {binary data} HEADERS + END_STREAM + END_HEADERS foo = bar