Trust is earned, not given

A different perspective

2019-08-13 · Projects

Node.js, part 7: HTTP/2 in core — multiplexing, headers, and the end of the connection pool hack

Part 7from the Node.js series · 24 parts in all

HTTP/1.1's workaround for concurrency is to open several TCP connections and keep them alive, because one connection carries one request at a time. HTTP/2 multiplexes streams over a single connection, compresses headers, and (originally) pushed resources. Node grew a first-class http2 module — part 7 is what changes in your code and what does not.

A server is close to the HTTP/1 one

const http2 = require('http2');
const { readFileSync } = require('fs');

const server = http2.createSecureServer({
  key: readFileSync('localhost-key.pem'),
  cert: readFileSync('localhost-cert.pem'),
});

server.on('stream', (stream, headers) => {
  // headers[":method"], headers[":path"] carry what used to be separate fields
  stream.respond({ ':status': 200, 'content-type': 'application/json' });
  stream.end(JSON.stringify({ path: headers[':path'] }));
});

server.listen(8443);

Two structural differences are visible here. HTTP/2 is encrypted in practice — browsers only speak it over TLS, so there is a certificate even locally. And each request is a stream, which is why the handler is on 'stream' rather than 'request': many streams share one socket, interleaved.

What multiplexing changes downstream

The practical recommendation

Terminate HTTP/2 at your proxy (nginx, a cloud load balancer) and let Node speak plain HTTP/1.1 on the inside, unless you specifically need server-to-server multiplexing or streaming. You get the protocol benefits for browsers without teaching every internal service a new API — and http2.createSecureServer supports an allowHTTP1: true option precisely so one listener can serve both. Next: dependency hygiene, the least glamorous thing on this list and the one that keeps you out of incidents.