swift-nio-http2 icon indicating copy to clipboard operation
swift-nio-http2 copied to clipboard

Suport HTTP Protocol Upgrade Mechanism

Open qqvm opened this issue 4 years ago • 7 comments

Is there a possibility to upgrade existing HTTP/1 connection to HTTP/2 on the server side? Mozilla Doc about "Protocol Upgrade": https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade

qqvm avatar Jun 22 '21 14:06 qqvm

We've never implemented support for it, and in practice the plaintext upgrade functionality was essentially never deployed. In fact, it's being removed from the revision of the specification for HTTP/2 because of how little it was used.

Lukasa avatar Jun 22 '21 14:06 Lukasa

I am trying to do that manually, and streamChannel does not get initialized with my final handler. But handshake and settings exchange are successful.

qqvm avatar Jun 22 '21 15:06 qqvm

Can you show me what your pipeline setup looks like?

Lukasa avatar Jun 22 '21 15:06 Lukasa

I have something like this:

self.deleteAllHandlers(context)

context.channel.configureHTTP2Pipeline(mode: .server) { streamChannel -> EventLoopFuture<Void> in
    print("configureHTTP2Pipeline triggered")
    return streamChannel.pipeline.addHandler(HTTP2FramePayloadToHTTP1ServerCodec(normalizeHTTPHeaders: true)).flatMap { () -> EventLoopFuture<Void> in
        streamChannel.pipeline.addHandler(PlainHTTPHandler(fromHTTP2: true)).flatMap { () -> EventLoopFuture<Void> in
            streamChannel.pipeline.addHandler(ErrorHandler())
        }
    }
}.flatMap { (_: HTTP2StreamMultiplexer) in
    context.channel.pipeline.addHandler(ErrorHandler())
}

qqvm avatar Jun 22 '21 20:06 qqvm

And to be clear, this is attempting to do plaintext upgrade?

Lukasa avatar Jun 23 '21 10:06 Lukasa

Yes, this is a plaintext upgrade from HTTP/1.

qqvm avatar Jun 23 '21 11:06 qqvm

Ok, without changes to the core state machine this cannot work. HTTP/2 has a defined upgrade pattern from HTTP/1.1 that requires passing a SETTINGS frame in via a header, and consuming the body payload from the HTTP/1.1 request. You'd need to update the HTTP2Handler and associated state machines in order to get this to work.

Lukasa avatar Jun 23 '21 13:06 Lukasa