Raspberry Pi 3: HTTP/2 server setup

In this tutorial we will check how to setup a HTTP/2 server on the Raspberry pi 3, using Node.js. This tutorial was tested on a Raspberry Pi 3 model B+ running version 4.9 of Raspbian.


In this tutorial we will check how to setup a HTTP/2 server on the Raspberry pi 3, using Node.js.

It’s important to take in consideration that you might need to update your Node.js version to have access to the HTTP/2 module. You can check this guide on how to update the Node.js version on the Raspberry Pi.

Currently no browser supports HTTP/2 without encryption [1], which means our server will need to be able to operate with a secure connection (HTTPS).

Consequently, we will need to generate a server certificate and a private key for testing. The certificate will be a self signed, since we are just going to use it locally. The procedure to generate the files is explained in more detail on the next section.

This tutorial was tested on a Raspberry Pi 3 model B+ running version 4.9 of Raspbian. The Node.js version used was 12.2.0.

Generating the certificates

As mentioned in the introductory section, we will need to generate a server certificate and a private key. For that, we will use openssl.

At the time of writing, version 4.9 of Raspbian comes with openssl already installed, so we can just run the following command to generate the files:

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

Note that the previous command is indicated in the Node.js HTTP/2 module documentation, as can be seen here.

So, after sending the command, you should get an output similar to figure 1.

Generating a server self signed certificate and private key on the Raspberry Pi 3, using openssl
Figure 1 – Generating the server certificate and private key with openssl, on the Raspberry Pi.

Upon running this command, you should get two files on the directory where the command line is located:

  • localhost-cert.pem
  • localhost-privkey.pem

In case you are having troubles generating the files, below are examples that you can use to test the server:





In case you use the previous examples, don’t forget to use the correct file names and extensions.

Once you have both files, create a folder in a location of your choice. Then, place both the server certificate an key files on that folder.

After this, create a new file called “testHttp2.js“. This will be the file where we will write the code to run the server. The next section details all the code we need.

Figure 2 illustrates how the content of the folder should look like.

Example of the folder with all the files to run the HTTP/2 server on the Raspberry Pi 3.
Figure 2 – Folder with all the files needed to run the HTTP/2 server.

The code

We will start our code by including the modules we require to setup the HTTP/2 server. We will need the HTTP/2 module, which will expose the functionalities needed to setup the server.

const http2 = require('http2');

We will also need to import the file system module, so later we are able to read the content of the certificate and private key files.

const fs = require('fs');

Moving on to the next part of our code, now we need to define a callback function that will be executed whenever a HTTP/2 is received by the server.

This callback function will be invoked with two arguments:

  • An object of class Http2ServerRequest, which can be used to access the request status, headers, and data;  
  • An object of class Http2ServerResponse, which allow to send data back to the client.

We will call this function onRequest and, as already mentioned, its signature will have two parameters:

function onRequest (req, resp) {
// Implementation of the callback function

The implementation of the function will simply consist on returning an “hello world” message back to the client. We can do this by calling the end method on our Http2ServerResponse object and passing as input the string we want to return to the client.

Additionally to send the data back to the client, this method call will signal to the server that the message was completed.

function onRequest (req, resp) {
    resp.end("Hello World");

After this we need to create our HTTP/2 server. This is done with a call to the createSecureServer function from the HTTP/2 module.

As first input of this method, we will pass an object containing the server key and certificate. This object should have a field called key, with the content of our private key file, and a field called cert, with the content of our certificate.

To get the content of these files we can simply use the readFileSync function of the File System module. As input of this function, we just need to pass the path to the files.

Since the files are located in the same folder where we have the Node.js script, we simply need to use the file names.

Going back to the createSecureServer function, it receives as second parameter a callback function that will be executed when a request is received. Naturally, we should pass our previously defined onRequest function.

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

To finalize, we need to call the listen method on our server object, passing as input the number of the port where it will be listening for incoming requests. For testing, we will be using port 8443.


The final code can be seen below.

const http2 = require('http2');
const fs = require('fs');
function onRequest (req, resp) {
    resp.end("Hello World");
const server = http2.createSecureServer({
  key: fs.readFileSync('localhost-privkey.pem'),
  cert: fs.readFileSync('localhost-cert.pem')
}, onRequest);

Testing the code

To test the code, we first need to run the previous Node.js script. You can check in detail how to run a Node.js script on the Raspberry Pi on this previous tutorial.

So, to execute the script, simply open a command line and navigate to the folder where the script is located. Then, run the following command:

node testHttp2.js

Figure 3 illustrates the previous command, sent on the Raspberry Pi command line.

Running the HTTP/2 server Node.js script.
Figure 3 – Running the HTTP/2 server Node.js script.

After running the script, open the Raspberry Pi web browser. Then, type the following URL in the browser address bar and click enter:


Note that we are using an endpoint called “stream” but we could use any other endpoint instead, since our server implementation will always return an answer back to the client.

After navigating to the URL, if the browser warns about some security issues, choose to advance. This happens because we are using a self signed certificate, which was not issued by any authority that the browser knows. Consequently, the browser will mark it as insecure. Naturally, for a real scenario application, you should not use a self signed certificate.

At the end, you should get a result similar to figure 4. As can be seen, the “Hello World” message we defined on the code is returned to the browser, as expected.

Response of the server rendered in the browser.
Figure 4 – “Hello World” message returned to the browser.

Related Posts


[1] https://nodejs.org/api/http2.html

Leave a Reply

%d bloggers like this: