Exploring http2 (Part 2): with node-http2 core and hapijs
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!
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
And here we go! Falls back to serving http1.1 when client does not support http2
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.
References:
- https://http2.github.io/faq
- https://http2.akamai.com/demo
- https://github.com/http2/http2-spec/wiki/Implementations
- https://caniuse.com/#feat=http2
- https://nodejs.org/dist/latest-v10.x/docs/api/http2.html
If you found this story useful, please support it by clapping 👏