Skip to content

http: introduce new http Client

I'm opening this PR mostly as a forum for discussion and expect it to probably end up being closed. Not sure if this is the right approach so feel free to point me in a better direction if possible.

During the OpenJS conference session yesterday we discussed the future of HTTP. Mostly focused on the server side but also the client side was briefly mentioned. In particular @jasnell pointed out that in HTTP2/3 the difference between server and client side is much smaller. Though, we all agreed that any plans in this regard is probably a few years away. We basically ended up with two issues (#1, #2) in the web-server-frameworks working group. Again this mostly focuses on the server side so I'm a little unsure where client side discussions should go. Given the mentioned decrease in difference, maybe it should land in the web-server-frameworks WG at some point?

That being said, I have been looking into implementing a simpler and faster http client and ended up working on @mcollina's undici library. It might or might not make sense to include in node core or possibly some kind of WG package. The idea is that this client should provide a building block for higher level client implementations.

I think most of us are familiar with the issues with the current http client in Node core and that it can be a challenge to maintain. How do we get past this?

In this PR I have included undici to discuss whether or not it might make sense to include in core, and if so what things are missing, should be changed or needs further consideration?

As a quick summary:

  • more than 2x faster than the current http client.
  • Uses llhttp for parsing (through Node).
  • Simpler implementation.
  • Testing suite with near 99.99% coverage.
  • HTTP pipelining support.
  • 5 different API's request, pipeline, stream, upgrade and connect.
  • Hopefully less edge cases and semi compliant behavior (e.g. in relation to streams).
  • Async Hook support.
  • https support
  • Works on all LTS versions of Node.
  • keep-alive timeout hint support

For further details it's easiest to check the README.

Some challenges:

  • What should the API be? Could we fit http2/3 into it?
  • Should this be in core, WG package or just leave it separate?
  • Does not sanity check input (i.e. method headers etc...). Should it?
  • Do we end up with 2 different http client API's in core that we need to maintain indefinitely?
  • Does not cache TLS sessions. Does it need to? - Missing 1xx support (in particular 101). - Missing trailers support.
  • Missing 100 continue support (won't fix is current opinion)
  • Pool vs Agent? What pool strategies?
  • Other possible enhancements?

Some TODOs:

Benchmarks:

http - keepalive - pipe x 5,768 ops/sec ±4.17% (71 runs sampled)
undici - pipeline - pipe x 7,151 ops/sec ±2.59% (80 runs sampled)
undici - request - pipe x 11,618 ops/sec ±4.43% (72 runs sampled)
undici - stream - pipe x 12,592 ops/sec ±1.03% (81 runs sampled)
Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

Merge request reports

Loading