What is HTTP/2?

Not so long ago, I happened to do a research about HTTP/2 and how it affects performance of web services for my Masters. In this blog post, I am describing the basic details of the HTTP/2 protocol. 

HTTP/2 the latest version of Hyper Text Transfer Protocol, is an optimized transport for HTTP semantics. Hence, it supports all the core features of HTTP/1.1 [1] . The aim of HTTP/2 is to be more efficient by addressing limitations of HTTP/1.1 [1] .

There are 5 main features of HTTP/2.


  1. Multiplexing
  2. Header Compression
  3. Request prioritization
  4. Server push
  5. Binary message frames. 

Connection establishment in HTTP/2

HTTP/2 also uses the same “http” and “https” URI schemas and same port numbers as HTTP/1.1. Therefore, implementations processing requests for target URIs with“http” and “https” should have a way to discover whether the next hop supports HTTP/2 or not. The determination procedure for HTTP/2 support is different for “http” and “https” URIs [1] .


Starting HTTP/2 for “http” URIs

A client without prior knowledge about HTTP/2 support in next hop, uses an HTTP upgrade  mechanism when sending a request for a “http” URI. The client first sends a HTTP/1.1 request which consists of the “h2c” token [1] .

A server which supports HTTP/2 sends a 101 response in return. This is the switching protocol response. The server can begin sending response to the request which initiated the upgrade by client, right after the empty line which terminates the 101 response. These are sent as HTTP /2 frames. The first HTTP/2 frame sent by the server must be a connection preface and after client receiving 101 response, it also should send a connection preface. This connection preface is the final confirmation
about the protocol being used and this needs to be sent by each endpoint in the connection. A server that doesn’t support HTTP/2 can respond to the upgrade request by ignoring the upgrade header [1] .


Starting HTTP/2 for “https” URIs

A client which sends a request to an “https” URI, uses TLS 1.2 with the Application Layer Protocol Negotiation extension (TLS-ALPN). It uses “h2” as the protocol identifier when sending a HTTP/2 request over TLS. After completion of the TLS negotiation, both server and client must send a connection preface [1].

Frames

All the data that are sent through HTTP/2 protocol are frames. Once HTTP/2 connection is established as above described, endpoints can start sending HTTP/2 frames. There are different frame types in HTTP/2 and each frame has a frame header, followed by some frame payload. The format of the frame payload depends on the frame type [1]. 

Header Compression

As mentioned in RFC7230, header fields are not compressed in HTTP/1.1 [2] . With the advancements in web pages, sometimes it requires sending hundreds of requests to load the page. Hence redundant headers sent in these requests consume bandwidth unnecessarily resulting in increased latency. HTTP/2 addresses this issue by using a new form of header compression known as HPACK. . All the headers sent via HTTP/2 (frames of type HEADRES, CONTNUATION and PUSH_PROMISE) are encoded using HPACK. In HPACK, a header will be encoded either of below
ways [1] .
  • Encode commonly used headers as a reference to the header fields in header tables
  • Encode literals using a static Huffman code
Hence, header fields of HTTP/2 can be references to one of the header tables and encoded literals. In HPACK, there are two types of header tables [2] . Those are the static table and the dynamic table. Both client and server maintain a copy of the dynamic header table. When a client sends a header to the server, the client can tell the server to store it in its dynamic table. If the client has to send the same header again, the index value in the dynamic table can be sent instead of the real header. The
same encoding happens in response path (Server to client) as well. By default, the size of the dynamic table is 4k and it can be changed using a SETTING frame [1] .

HPACK also has a static table which contains set of predefined commonly used static headers. In that case, HPACK enables header compression even before dynamic tables are populated [2] . 

With this approach, it saves a significant amount of bandwidth, when many requests and responses need to be sent with same headers. After the first request, most headers can be represented as index values referencing dynamic or static table [2] . 

Apart from these, HPACK also allows compressing headers by encoding header names and values via a fixed Huffman encoding [2].

Streams and Multiplexing

In HTTP/2, a stream is an independent, bi-directional sequence of frames exchanged between the client and server [1] . In a single HTTP/2 connection, there can be multiple streams operating concurrently. The endpoint initializing the stream gives an identifier to the stream which is an integer number. Each frame sent will have a stream identifier in the header and it allows the endpoints to track the request to which a frame belongs to [1] .

Having streams in HTTP/2 allows sending multiple requests between two endpoints using the same connection and the responses are interleaved whenever they are available. This is known as multiplexing [1] .

Stream Priority

Streams can be assigned to a priority which can be used by client to suggest the server about resource allocation in handling concurrent streams [19] . Moreover, in the client end itself, if there is limited capacity to send frames, this priority can be used to decide which streams will be used to send frames. This priority information is included in the HEADER frame which is sent to open the stream [1] . In order to change the priority of an existing stream, PRIORITY frame shall be used [1] . 

The priority of streams is defined by setting dependencies among streams. A stream that is dependent on another stream is a dependent stream. The stream on which a stream is dependent is a parent stream. Resources will be allocated for dependent streams upon the completion of the parent streams [1] .

References

[1] M. Belshe, R. Peon, and M. Thomson, “Hypertext Transfer Protocol Version 2
(HTTP/2),” Internet Eng. Task Force, no. RFC7540, 2015.

[2] R. Peon and H. Ruellan, “RFC 7541 HPACK: Header Compression for
HTTP/2,” Internet Eng. Task Force, vol. 1, 2015.

Comments

Popular posts from this blog

How to add Maven dependency from a relative path referencing a local jar

Manually install a maven dependency

PHP-SOAP web service with out a WSDL