nodejs / web-server-frameworks

A place for Node.js Web-Server Framework authors and users to collaborate
Other
181 stars 27 forks source link

Question about http-next version strategy #113

Open fed135 opened 5 months ago

fed135 commented 5 months ago

I've been working on ideas for the lib API design of http-next and getting inspiration from the strategy document and this old gist.

One question that popped was: does http-next need to handle all versions of http as part of the same core api module, or should it expose versions independently and let the community build modules custom tailored for specific handling/downgrading of http sessions?

Ex:

const {http, http2, http3} = require('node:http-next');
wesleytodd commented 5 months ago

Wow I forgot about that gits I had written! Thanks for the reminder, I should take some of that and turn it into a PR against https://github.com/nodejs/http-next/ so it is not lost in time!

That said, I don't think I have clarity on how best to handle this. I think that we need to have some clear usage examples for "real world" reasons you would start a single application server with multiple http servers on different versions.

I had one specific one I was thinking about back then which would be to leverage this for a local package manager caching proxy. Where we could do some really interesting optimizations for loading package metadata when sometimes the upstream server only supports http1. That said, it was more of an experiment than a real world thing, so I am not sure we should go designing api's around it. Do you have any real world use cases where you have seen folks do this today?

fed135 commented 5 months ago

I don't have any specific use cases in mind at the moment, but I did have some concerns around configuration.

Here's a potential misconfigurations:

{
   allowHTTP1: true,
   allowHTTP2: false,
   allowHTTP3: true
}

I guess this could technically be valid, but the behaviour would be very unintuitive. (Does the server reply with a `GO AWAY | HTTP_1_1_REQUIRED ?) That, and making sure the config doesn't keep growing over time when new versions are released.

One option would be to borrow from other languages and popular http implementations, such as Rust and the Hyper http library and have the default config to be to automatically accept all versions- unless you specify a version, then it only accepts that version. ex:

 {
   httpVersion: 2               // Possible values are: 'auto' | 1 | 2 | 3
 }
wesleytodd commented 5 months ago

I agree that there are many opportunities for foot-guns here, and frankly looking at that gist a few years later I don't like this way. This is why I think we need to understand a real use case to design around and use in testing. If we cannot come up with one then I absolutely think we should take the most simple approach we can and I like the proposed way of httpVersion as much as any I can think of off hand.

fed135 commented 4 months ago

I've dug around and asked cybersecurity friends. The short of it, is that there are scenarios where a developer would like to lock down which specific http version the server accepts, as specified in NIST 800-52. This commonly includes government agencies and other high-security targets with the objective of preventing potential vulnerabilities (ex: TOC/TOU) which could be triggered due to the differences in performance and roundtrips between protocol versions.

This also applies to services that have to interface with legacy systems and want to lock in that system's specific http version to prevent unauthorized connections.

So I'm now wondering if the httpVersions values should be even more specific. I guess it depends on how we want to position Node.js on the market. Is the strategy to focus on modern-web and ease of use, or to make it a viable solution for specialized use cases, like high-security systems.

fed135 commented 4 months ago

As discussed during the last meeting, the idea of selecting a specific httpVersion makes sense, but there's still some unknowns around auto-selection, namely Upgrade paths with http/3 not being possible. A potential solution could be to wait for a user library implementation or http/3 spec updates.

This would mean that setting httpVersion would have these effects:

Hopefully this won't become a future headache when more protocols are released or updated.