Skip to content

We "need" a way to create an Http2Session from a socket #16256

Closed
@grantila

Description

@grantila

While building fetch-h2 and when discussing with node-fetch, and while participating in #14671 I realize that we need this in Node.js; a protocol-agnostic connect() to a TLS-enabled web server and let the ALPN handshake allow for both "h2" and "http/1.1". Without this, we won't be able to connect to an https-server without knowing in beforehand if that server wants to (or even can!) speak HTTP/1.1 or HTTP/2.

I'm thinking of something like tls.handoverConnect() which doesn't take application-level (http) arguments (path, headers, etc), it just connects and returns (through a callback, likely) the protocol ("http/1.1" or "h2") and a corresponding session.

A question is what the session data is. In case of HTTP/2, it should be an Http2Session, but for HTTP/1.1 it must be something where the user can perform the request, and it should probably be integrated with Agents. There's unfortunately an inheritance jungle in the design of these old functions, like https.request() where ip/tcp/application-level options are merged into one blob, but the "https/1.1 session" here (let's call it Http1SessionProxy) should be something that looks like the http module, in how it has a request() function, with the tcp/ip-level options removed.

Let's say this feature belongs in tls (which I think it does):

const connectOpts = { host: "my-server.com", port: 443, /* ... */ };

tls.handoverConnect( connectOpts, ( err, protocol ) =>
{
    if ( err ) ... ;

    // session is an Http2Session or Http1SessionProxy
    const { name, session } = protocol;

    if ( name === 'http/1.1' )
    {
        // session.request acts just like http.request
        const req = session.request(
            { path: '/foo', headers, ... },
            ( res ) => { ... }
        );
    }
    else if ( name === 'h2' )
    {
        // well, the usual http2-stuff
        const stream = session.request( headers, options );
    }
} );

In this example, perhaps an Agent could be passed in the connectOpts, so that if the session turns out to be HTTP/1.1, the connection will be added to this agent (and by default the global Agent is used, just like traditional http{s}.request()).

Any thoughts on this? I guess it's a good time to look into this now, as the http2 module is being tested in the wild, but before it's "stable".

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestIssues that request new features to be added to Node.js.httpIssues or PRs related to the http subsystem.http2Issues or PRs related to the http2 subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions