3

I'm trying to setup an testing environment for http3 just for learning.

What I did so far:

  • Created a real let's encrypt certificate with dns-01
  • Compiled node.js with the experimental CUIC flag
  • Compiled curl with http3 support

I created a script with the content of the example:

'use strict';

const key = getTLSKeySomehow();
const cert = getTLSCertSomehow();

const { createQuicSocket } = require('net');

// Create the QUIC UDP IPv4 socket bound to local IP port 1234
const socket = createQuicSocket({ endpoint: { port: 1234 } });

socket.on('session', async (session) => {
  // A new server side session has been created!

  // The peer opened a new stream!
  session.on('stream', (stream) => {
    // Let's say hello
    stream.end('Hello World');

    // Let's see what the peer has to say...
    stream.setEncoding('utf8');
    stream.on('data', console.log);
    stream.on('end', () => console.log('stream ended'));
  });

  const uni = await session.openStream({ halfOpen: true });
  uni.write('hi ');
  uni.end('from the server!');
});

// Tell the socket to operate as a server using the given
// key and certificate to secure new connections, using
// the fictional 'hello' application protocol.
(async function() {
  await socket.listen({ key, cert, alpn: 'h3-25' });
  console.log('The socket is listening for sessions!');
})();

Just for future readers the functions getTLSKeySomehow() and getTLSCertSomehow() can be replaced by this:

const fs = require("fs")
const key = fs.readFileSync('privkey.pem')
const cert = fs.readFileSync('cert.pem')

Then I tried to open the webpage by enableding http3 in Firefox with the feature-flag network.http.http3.enabled enabled in about:config. With the address https://my.dev.domain.name:1234/ but this didn't work.

Using curl didn't work ether, might be worth noting that I'm using WSL on Windows 10. Accessing the same url on curl times out everytime. Just to check that my setup is fine: I can verify that Firefox and curl can access www.google.com flawless via http3.

When I implement a second http2 endpoint with the same key this works fine without any certificate warnings.

How can I debug what I'm doing wrong?

rekire
  • 45,039
  • 29
  • 149
  • 249
  • Quic, in some ways and your sample code, replaces TCP, not HTTP. I don't see anything HTTP/3 specific here and the documentation you linked to says 'TBD'. I also don't see how you advertised HTTP/3 (which happens over H/1 or H/2) – Evert Jan 01 '21 at 17:58
  • @Evert thank you for your hint. I fixed the `alpn` value to `h3-25` and I see incoming connections, but I cannot handle it. I guess the headers are packed with [`QPACK`](https://tools.ietf.org/html/draft-ietf-quic-qpack-20). Do you know how to read that? – rekire Jan 03 '21 at 19:42

1 Answers1

2

Your code sample just implements QUIC - which is the transport protocol underneath HTTP/3 (similar to how TCP + TLS are the transport protocols below HTTP/1.1).

This means you need additional code for implementing HTTP/3 on top of Quic. Ideally you want a library, since it's rather complex. Here are links to the most recent draft version of the specifications which need to be implemented:

I assume node.js would eventually also add support for those, so that this task gets easier.

Without HTTP/3 support, you could test pure QUIC streams (without HTTP semantics) against your test server. You can use any of the various QUIC libraries to do this, but there might not be an out of the box CLI tool like curl.

Matthias247
  • 8,111
  • 1
  • 14
  • 25
  • 1
    I know that recommendations are in general not allowed, but can you suggest any QPACK implementation for node.js? I guess I'm looking at this technology too early and there is no implementation yet. Might be we will laugh about this question like [this GitHub issue](https://github.com/nodejs/node/issues/23064#issuecomment-424892639). – rekire Jan 07 '21 at 07:14
  • There exists a TypeScript wrapper around ls-qpack, perhaps you could use it as a starting point: https://github.com/rmarx/quicker/tree/draft-20/lib/ls-qpack – Dmitri Jan 07 '21 at 15:37