Recently i’ve been pushing to upgrade a large swath of applications to support newer HTTP/2 methods. It’s been really wonderful to see the adoption and “for free” (well, sort of) speed increases from it.

Most of the work has been simply changing the front door load balancer to our backend apps to support HTTP/2; easy-peasy. Except this only buys us a subset of HTTP/2 services. The other exciting new HTTP/2 features require we make code changes to our underlying apps.

As we rolled out the initial subset of HTTP/2 speed advantages many of our engineers were excited to push the boundaries and do more with HTTP/2. Unfortunately they were met with a major road block in using it: Browsers.

The HTTP/2 spec does not require encryption; it’s at a different layer than TLS encryption after all and outside of ALPN negotiation has little knowledge (nor should it) of the underlying encryption systems. However browser manufactors have made the decision to only support HTTPS only. This has caused a few problems.

Mis-communication

It has unfortunately convinced many developer evangelists, langauage and framework programmers to think that HTTP/2 is only supported over TLS encryption. Or at least has leant to a communications fiasco where that’s what most engineers are hearing.

From a browsers perspective, this is completely true. Browsers refuse to make unencrypted HTTP/2 connections by choice, not by standard. If browser manufactors tout that HTTP/2 is only available via encrypted HTTPS some engineers and framework designers will make their servers and libraries only capable of using TLS, or more likely, they will only provide examples of how to use it with TLS.

This then breaks many platforms which manage encryption for the engineer (surprisingly more than you may think), many very sophisticated service meshes, PaaS and hosting provides perform the acutal TLS termination and then perform mutual TLS authentication in a TCP tunnel completely transparent to the developer (e.g., every service mesh).

These systems suddenly find themselves at odds with engineers while upgrading to HTTP/2. As these systems need to provide the OPPOSITE instructions from what engineers are being told by browser manufactors and language programmers.

The end result? We can’t have nice things.

Yet-Another-Thing

I’d be willing to argue most engineers do not know TLS encryption. Infact, the idea of using private-public key cryptography seems to be intimidating to most people i’ve met. And with good reason. Encryption is very easy to get wrong and has a high risk with one mistake.

Of the great engineers I’ve met, they all seem to acknowledge that encryption is really difficult to get right and would rather not deal with it.

Because browsers only support HTTP/2 over TLS engineers are taught to setup their local development environment with self-signed certificates to make development locally with HTTP/2 possible.

I’ve encountered every one of the below scenarios with every engineer adopting HTTP/2:

How do I generate self-signed certs? How do I mark them as trusted so my browser and other clients (e.g, Postman/curl) don’t reject my requests? Are these certificates something I need to keep private? I’ve been warned that a leak of a private key is a huge ordeal, how can I manage this private key safely? If I switch our app over to HTTP/2 do I need to then train all of our team on these things? Wait… you’re saying none of this matters once we deploy it? So we need to put in switches to flip TLS on or off?

I should also add that most organizations do not permit self-signed certificates to be trusted, so #2 is a complete non-starter.

In my experience not a single engineer has adopted HTTP/2 as its too large of shift in their development workflow and vastly too complicated for the advantages it provides. Forget about HTTP/3, the HTTP/2 battle has already been lost. Long live HTTP/1.1.

What to do