node.js server and HTTP/2 (2.0) with express.js node.js server and HTTP/2 (2.0) with express.js express express

node.js server and HTTP/2 (2.0) with express.js


var express = require('express');var app = express();app.get('/', function (req, res) {  res.send('hello, http2!');});var options = {  key: fs.readFileSync('./example/localhost.key'),  cert: fs.readFileSync('./example/localhost.crt')};require('http2').createServer(options, app).listen(8080);

EDIT

This code snippet was taken from a conversation on Github.


If you are using express@^5 and http2@^3.3.4, then the correct way to start the server is:

const http2 = require('http2');const express = require('express');const app = express();// app.use('/', ..);http2    .raw    .createServer(app)    .listen(8000, (err) => {        if (err) {            throw new Error(err);        }        /* eslint-disable no-console */        console.log('Listening on port: ' + argv.port + '.');        /* eslint-enable no-console */    });

Notice the https2.raw. This is required if you want to accept TCP connections.

Note that at the time of this writing (2016 05 06), none of the major browsers support HTTP2 over TCP.

If you want to accept TCP and TLS connections, then you need to start the server using the default createServer method:

const http2 = require('http2');const express = require('express');const fs = require('fs');const app = express();// app.use('/', ..);http2    .createServer({        key: fs.readFileSync('./localhost.key'),        cert: fs.readFileSync('./localhost.crt')    }, app)    .listen(8000, (err) => {        if (err) {            throw new Error(err);        }        /* eslint-disable no-console */        console.log('Listening on port: ' + argv.port + '.');        /* eslint-enable no-console */    });

Note that at the time of this writing, I did manage to make express and http2 to work (see https://github.com/molnarg/node-http2/issues/100#issuecomment-217417055). However, I have managed to get http2 (and SPDY) to work using spdy package.

const spdy = require('spdy');const express = require('express');const path = require('path');const fs = require('fs'); const app = express();app.get('/', (req, res) => {    res.json({foo: 'test'});});spdy    .createServer({        key: fs.readFileSync(path.resolve(__dirname, './localhost.key')),        cert: fs.readFileSync(path.resolve(__dirname, './localhost.crt'))    }, app)    .listen(8000, (err) => {        if (err) {            throw new Error(err);        }        /* eslint-disable no-console */        console.log('Listening on port: ' + argv.port + '.');        /* eslint-enable no-console */    });


There is an open pr for express 5.0 since 2018, https://github.com/expressjs/express/pull/3730. Until that is merged, it won't work out of the box.

I have created the solution in the form of a package, https://www.npmjs.com/package/http2-express-bridge

const express = require('express')const http2Express = require('http2-express-bridge')const http2 = require('http2')const { readFileSync } = require('fs')// Use the wrapper function that returns the applicationconst app = http2Express(express)const options = {    key: readFileSync('<Certificate Key>'),    cert: readFileSync('<Certificate file>'),    allowHTTP1: true};app.get('/', function (req, res) {  res.send('Hello World')})const server = http2.createSecureServer(options, app)server.listen(3000, () => {        console.log(`listening on port 3000`)})