1

I am learning how to build an http2 server with NodeJS 10 LTS official documentation. I copy pasted the server side code into server.js and run node on it, but when I try to connect with postman (REST testing tool) I receive an error.

const http2 = require('http2');
const fs = require('fs');

const server = http2.createSecureServer({
  key: fs.readFileSync('localhost-privkey.pem'),
  cert: fs.readFileSync('localhost-cert.pem')
});
server.on('error', (err) => console.error(err));

server.on('stream', (stream, headers) => {
  // stream is a Duplex
  stream.respond({
    'content-type': 'text/html',
    ':status': 200
  });
  stream.end('<h1>Hello World</h1>');
});

server.listen(8443);

The error I receive from postman is as follows:

Unknown ALPN Protocol, expected `h2` to be available.
If this is a HTTP request: The server was not configured with the `allowHTTP1` option or a listener for the `unknownProtocol` event.

Things I have tried to solve the problem:

  1. As required in the official documentation I have created private and public certificate (.pem).
  2. I have included the public certificate inside postman software. So now the only error I receive is the one mentioned above (Unknown ALPN protocol).

What else is needed to make the example in the official docs work? I could not find online resources for that, and all the previous questions on stackoverflow relates to old versions of NodeJS when http2 was not still native.

Arto Kalishian
  • 496
  • 1
  • 6
  • 11

2 Answers2

2

Try to add allowHTTP1: true in Server options at it says server not configure with the allowHTTP1

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

To

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

From github http2 documentation :

allowHTTP1 {boolean} Incoming client connections that do not support HTTP/2 will be downgraded to HTTP/1.x when set to true. See the 'unknownProtocol' event. See ALPN negotiation. Default: false.

Here i found better answer already on Stackoverflow Configure HTTP2 NodeJS Server

Mandeep Gill
  • 4,577
  • 1
  • 28
  • 34
  • Thanks for your response. Adding allow http1 works on the browser and print Hello World, but now https is disabled and the browser just switches to HTTP1, so it's pointless. As for postman the ALPN error disappears but the request is never returned, it keeps loading forever. I will check the other answer link you provided to see if it helps. – Arto Kalishian Apr 24 '19 at 11:48
  • Yes that's why i added Stackoverflow link where we have old answer with HTTP2 – Mandeep Gill Apr 24 '19 at 11:53
  • I can see many answers in that thread, can you point out which answer specifically works for my need? – Arto Kalishian Apr 24 '19 at 11:54
  • That post is since 2 years ago where http2 client was "experimental" in nodejs. I am not sure if that code is sitll valid. – Arto Kalishian Apr 24 '19 at 11:56
  • 1
    You can try but i don't think so anything major deprecated. – Mandeep Gill Apr 24 '19 at 11:59
  • 1
    It works for me, thanks! ``` curl "https://localhost:8443" --insecure -i HTTP/2 200 content-type: text/plain; charset=utf-8 content-length: 15 date: Sun, 11 Apr 2021 10:57:43 GMT ``` – Anton Mitsev Apr 11 '21 at 10:58
0

Ok, after thorough investigation I found a satisfactory answer to a great extent.

  1. The https request should be https://localhost:8443/stream to get a response from the server with Hello World. Without the stream path there is no response.
  2. postman gives 403 response after installing the public certificate, but insomnia doesn't give any response.
  3. Using google chrome developer tools in the Network tab I can finally get response 200 OK from the server as shown below.

enter image description here

Arto Kalishian
  • 496
  • 1
  • 6
  • 11