So you still don’t know what’s special about HTTP/2 ?
I know what you are thinking: ‘If I have any chance of considering myself a true computer scientist I should know what HTTP version 2 is all about and what was even wrong with version 1.1?’
I’ll sit down one day, set some time aside and just read all about it
Well if you are anything like me, spare free time never comes easy. When it does, you are too tired and facebook is just so much easier
But what to do when someone around the office mentions it as an argument for using something? Don’t give in to panic… Let me try to help:
If you really are in a hurry then jump to the TL;DR section
Am I too late for the party?
Lets see, the RFC dates from May 2015 … ouch.
- Apache supports it since the 12th of October 2015 — version 2.4.17
- Tomcat implemented the support for version 9 and then back-ported it to version 8.5
- Jetty supports it since version 9.3 which was release on 15th of June 2015
- IIS version 10 released on 29th of July 2015 ticked it off
- Nginx supports it since its version 1.9.5 released on 22nd of September 2015
- Wildfly introduced support for HTTP/2 in its 9th version on the second of July 2015
What was wrong with version 1.1? Heck! what about version 1.0?
“HTTP/1.0 allowed only one request to be outstanding at a time on a given TCP connection”
This is the only thing pointed out in the introduction of the RFC 7540 but if we take a trip back in time and focus on a document presented by Balachander Krishnamurthy, Jeffrey C. Mogul and David M. Kristol on the eighth world web conference, we realise that Version 1.1:
- Was released after a very long debate and around four years of interim versions causing implementors to stick to non final and even erroneous specifications.
- Introduced the OPTIONS method and with it a bunch of pertinent questions regarding its actual semantics.
- Introduced the ‘upgrade’ request-header that suggested newer versions of the protocol that the server could, instead, use with this client.
- Paved the way for better caching techniques that were as semantically transparent as possible by introducing the Cache-Control and Vary headers
- Addressed bandwidth wastes of its predecessor like the inability for a client to request partial objects or for the server to complaint about the oversize of a request after having consumed it.
- Added the ‘Transfer-Encoding’ header that specified the hop by hop possible encoding for the payload and clarified the ‘Accept-Encoding’ header. When used properly these two headers allowed for all sorts of clever compression to be put in place thus further optimising transfer speeds.
- Acknowledged the speed gains associated with reusing the underlying, expensive to setup, TCP connections. So it introduced the ‘Connection’ header and made all connections persistent by default. Connection pipelining was also brought in to allow for a client to send multiple requests before receiving any response.
- Proposed: Chunking, Trailers and Content-Type: multipart/byteranges to address issues with message transmissions.
- Tackled the lack of target specificity of a request in version 1.0 of the protocol. The header ‘host’ was not mandatory until version 1.1 because it was implied that if you have in fact reached this webserver then you must be requesting resources from this host. The introduction of the host header was an attempt to share one single IPV4 address with multiple hosts and already at the time IPV6 was being discussed as a possible further solution to the finite IPV4s.
- Added error codes for every one! With 24 new error codes and a warning header there was now no reason to debate on what to return when … or so we thought.
- Procured a tighter security through the adoption of authentication mechanisms like Digest access authentication and introduced Proxy-Authenticate / Proxy-Authorization headers.
- Re-specifies more cautiously what is meant by ‘content negotiation’ specifically where that choice is made server/client side.
Does version 2 fix everything then?
The protocol version supports everything that the previous 1.1 version did and it does it more efficiently.
HTTP/2 operates based on frames. Each frame has a type. Types like HEADERS and DATA are used on your basic operations like normal requests and responses while others like SETTINGS, WINDOW_UPDATE, and PUSH_PROMISE are used to implement more advanced HTTP/2 features.
Streams are the elegant solution to multiplexing and increased throughput where requests/response exchanges are handled in isolation. Special care was taken to control the usefulness of the data being transmitted. When ensuring that the receiver will not receive any data that it cannot use, the performance of the data being transmitted is naturally improved.
The concept of prioritisation was introduced to ensure that limited resources were delivered to streams that needed them first.
To counter the issues related to latency, HTTP/2 introduces a push mechanism in which a server can send data that it assumes the client will need without it being specifically requested for. The server fabricates a request of frame type PUSH_PROMISE to which it responds with the actual data on a separate stream.
Finally, to address the issue of redundant and repeated headers and thus the verboseness of the previous versions of the protocol, HTTP/2 compresses common bits of data allowing many requests to be sent in one single packet.
OK, if you are just after a few keywords you can use on your meeting tomorrow then here’s what’s special about HTTP/2:
- Binary, no longer textual — This is good because it is less error prone to parse and a lot smaller to transmit
- Multiplexed, no longer ordered or blocking — HTTP 1.x only supported one outstanding connection at the same time. HTTP 1.1 tried to fix it with pipelining but that wasn’t a full fix. HTTP/2 ensures a client only needs one connection to ‘load a page’
- Header compression — If you consider an average page with 80 assets, each on its own request, each request of around 1400 bytes it can take around 8 round trips to get ‘it all on the wire’. Compress it all and you can send everything in the same packet
- Servers can push responses — If the server, serving, the web page ‘knows’ what assets the client will need why won’t it send them and has instead to wait for the client to request them? If used correctly server pushes can actually improve performance quite a bit
For more information on these items check out HTTP/2’s github project’s wiki