Exploring http2 (Part 2): with node-http2 core and hapijs

Jeevan D C
3 min readJun 15, 2018

--

source: https://www.thewebmaster.com/

Pre-requisites: Understanding of javascript, client-server architecture.

The complete code can be found on github.

Part 1: Overview (Why, What, When, How of http2)
Part 2: Exploring with node-http2 core and hapijs

Disclaimer: Will be using http2 module shipped with node@v9+ in this article. Several other http2 client-server library implementations are listed here.

Let’s get started by creating a simple http1.1 server with single route.

mkdir hapijs-http2 && \
cd hapijs-http2 && \
npm init -y && \
npm i hapi@^16.6 -s && \
touch http1Server.js

copy the code below tohttp1Server.js or clone entire repo from here.

Now, let’s do the sanity check.

Start server with, node http1Server.js

⇒  curl http://127.0.0.1:8000/ping
pong

Cool! if we get pong for a ping, let’s try integrating http2 into our hapijs server.

Inherently, http2 requires to be run with https. To make this happen we will be needing ssl certificate.
We will be using OpenSSL to create a self signed certificate or you can use one from here.

openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
-keyout localhost-privkey.pem -out localhost-cert.pem

We will be using generatedlocalhost-privkey.pem and localhost-cert.pem in our http2Server.js.

Let’s make the following changes,

What changed?

Line 7–10: We are reading the certificate and private-key previously generated.

Line 13: Creating a secured Http2 server with certificate and private-key being passed as server options from http2 module.

Line 17: We can provide our own server implementation when creating a connection using the listener option. (more info here).

FYI: I am using node@v10.4.1, anything above 9 would be just fine.

Restart your server, and hit your browser with https://127.0.0.1:8000/ping

Voila!

server replies with pong

Points to notice,

  • Protocol value is h2 alias http2
  • We see not secure in our browser address bar, though we are running with https; because we Self Signed the ssl certificate and browser doesn’t identify it to be from valid Certificate Authority.
  • If we try curl we might get
    ➜ curl https://127.0.0.1:8000/ping
    curl: (1) Unsupported protocol

    This is because http2 might not be supported with default curl shipped by your OS. You can upgrade your curl by following this (macOS).
  • Once we are done with setup, we can try
    curl --http2 --cacert localhost-cert.pem https://127.0.0.1:8000/ping
    We can use curl with —-http2 flag to support http2 protocol, also we need to pass certificate file with—-cacert flag since its self signed and not recognized by curl.
  • We can verify the protocol by asking curl to return only response headers with -I (head) or with -v (verbose).

So far so good. But all our clients may or may not be supporting http2.
We handle this by adding additional server option: allowHttp1: true

adding “allowHTTP1: true” in serverOptions

And here we go! Falls back to serving http1.1 when client does not support http2

serving both http1.1 and http2 clients

Just with these changes we can get performance improvement of ~135% according to this.

Closely observe the differences,

Through waterfall section, it’s evident to grasp differences between single TCP connection usage against multiple.

If you want to get first hand experience of what http2 can offer, run the above demo in your machine as instructed here.

So pick your client or server library implementation and get started with http2!

The complete code can be found on github.

--

--