Beware the Connection Header in HTTP/2

Whilst tinkering apiman’s Vert.x gateway implementation I ran into a strange issue when invoking an API via curl --http2. It seemed to work fine in Chrome and using Go’s h2c:

$ * http2 error: Invalid HTTP header field was received: frame type: 1, stream: 1, name: [connection], value: [keep-alive]

This is what the setup looks like (distilled):

HTTP/2 Client <--> Apiman Gateway (HTTP/2) <--> Test API (HTTP/1)

What’s going on?

I took to Twitter to figure out what was going on.

Out of the blue, Mr cURL himself (Daniel Stenberg) popped up with the answer quoted from RFC 7540:

Mystery solved

Aha! The backend API apiman was proxying the response from returned a Connection: keep-alive header. Apiman simply forwarded this on, but it turns out this violates the HTTP/2 spec as there should be no connection-specific header fields - in response cURL spits out the error we see above. [1]

HTTP/2 Client (http2 error...) <- Apiman Gateway <- Test API (sets "Connection: keep-alive")

The solution was just to filter out Connection headers in apiman, but I wonder whether Vert.x should do it by default (or show an error message, exception, etc).

That said, I think "it’s the app’s responsibility not to do stupid things" or "we should handle it and filter out Connection headers" are both valid responses depending upon philosophy.

So, I let the Vert.x guys know, and let’s see.

1. Other implementations seem to just ignore these irrelevant fields.
comments powered by Disqus