Say hello to HTTP/2 for Node.js Core

James M Snell
Jul 14, 2017 · 2 min read

A few minutes ago I opened the initial pull-request that would provide an implementation of HTTP/2 for Node.js core. While it’s far from being production ready, this marks a key milestone.

Because this is just a pull-request, it’s possible to play around with, but there are a few additional steps.

First, you’ll need to make sure you’re set up for building Node.js locally by following the instructions here: https://github.com/nodejs/node/blob/master/BUILDING.md.

After that, check out the working branch:

$ git clone https://github.com/jasnell/node
$ git checkout initial-pr

Then build…

$ ./configure
$ make -j8

Warning, building Node.js from scratch takes quite a bit of time. So go grab a quick snack while things get going.

Once complete, you can create a functioning HTTP/2 server in a few lines of code:

const http2 = require('http2');const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200, 'content-type': 'text/plain' });
stream.write('hello ');
stream.end('world');
});
server.listen(8000);

Because the HTTP/2 support is still experimental, in order to run this server, the Node.js instance must be started using the command line argument:

$ node --expose-http2 h2server.js

Note that the server above uses plain-text TCP connection so the server will not be accessible from Web Browsers, which require using TLS. We can, however, create a simple HTTP/2 client:

const http2 = require('http2');const client = http2.connect('http://localhost:8000');
const req = client.request({ ':method': 'GET', ':path': '/' });
req.on('response', (responseHeaders) => {
// do something with the headers
});
req.on('data', (chunk) => {
// do something with the data
});
req.on('end', () => client.destroy());

Setting up a TLS-enabled HTTP/2 server requires just a few more additional steps:

const http2 = require('http2');const options = {
key: getKeySomehow(),
cert: getCertSomehow()
};
const server = http2.createSecureServer(options);
server.on('stream', (stream, requestHeaders) => {
stream.respond();
stream.end('secured hello world!');
});
server.listen(43);

Refer to the Node.js documentation for more information regarding the required and configuration options.

While there are many details that still need to worked through, and likely many issues that need to be fixed… this initial implementation provides enough functionality to get started, including:

  • Push Stream Support
  • and APIs that allow extremely efficient sending of raw file data that bypasses the Streams API.
  • TLS and Plain-text connections
  • Full support for stream multiplexing
  • HTTP/2 Prioritization and Flow Control
  • Support for HTTP/2 trailers
  • HPACK header compression support
  • A compatibility API layer that operates as close as possible to the existing HTTP/1 API

Development will be ongoing, as will security hardening, performance optimization, and API refinement. The more input we get on this, the better it will become.

Happy Multiplexing to All :-)

Node.js Collection

Community-curated content for the millions of Node.js

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store