From 89212301163b0906d800c28487aa01c6a2a177cd Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Fri, 15 Nov 2024 11:30:59 +0000 Subject: [PATCH] Fixes for Swift 6 mode with latest SwiftNIO (#605) Co-authored-by: Joannis Orlandos --- Sources/HummingbirdHTTP2/HTTP2Channel.swift | 39 ++++++++++----------- Sources/HummingbirdTLS/TLSChannel.swift | 4 ++- Sources/HummingbirdTesting/TestClient.swift | 4 +-- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Sources/HummingbirdHTTP2/HTTP2Channel.swift b/Sources/HummingbirdHTTP2/HTTP2Channel.swift index 9103e741..78636b99 100644 --- a/Sources/HummingbirdHTTP2/HTTP2Channel.swift +++ b/Sources/HummingbirdHTTP2/HTTP2Channel.swift @@ -215,27 +215,26 @@ extension Channel { http1ConnectionInitializer: @escaping NIOChannelInitializerWithOutput, http2ConnectionInitializer: @escaping NIOChannelInitializerWithOutput ) -> EventLoopFuture>> { - let alpnHandler = NIOTypedApplicationProtocolNegotiationHandler>() { result in - switch result { - case .negotiated("h2"): - // Successful upgrade to HTTP/2. Let the user configure the pipeline. - return http2ConnectionInitializer(self).map { http2Output in .http2(http2Output) } - case .negotiated("http/1.1"), .fallback: - // Explicit or implicit HTTP/1.1 choice. - return http1ConnectionInitializer(self).map { http1Output in .http1_1(http1Output) } - case .negotiated: - // We negotiated something that isn't HTTP/1.1. This is a bad scene, and is a good indication - // of a user configuration error. We're going to close the connection directly. - return self.close().flatMap { self.eventLoop.makeFailedFuture(NIOHTTP2Errors.invalidALPNToken()) } - } - } - - return self.pipeline - .addHandler(alpnHandler) - .flatMap { _ in - self.pipeline.handler(type: NIOTypedApplicationProtocolNegotiationHandler>.self).map { alpnHandler in - alpnHandler.protocolNegotiationResult + return self.eventLoop.makeCompletedFuture { + let alpnHandler = NIOTypedApplicationProtocolNegotiationHandler>() { result in + switch result { + case .negotiated("h2"): + // Successful upgrade to HTTP/2. Let the user configure the pipeline. + return http2ConnectionInitializer(self).map { http2Output in .http2(http2Output) } + case .negotiated("http/1.1"), .fallback: + // Explicit or implicit HTTP/1.1 choice. + return http1ConnectionInitializer(self).map { http1Output in .http1_1(http1Output) } + case .negotiated: + // We negotiated something that isn't HTTP/1.1. This is a bad scene, and is a good indication + // of a user configuration error. We're going to close the connection directly. + return self.close().flatMap { self.eventLoop.makeFailedFuture(NIOHTTP2Errors.invalidALPNToken()) } } } + try self.pipeline.syncOperations.addHandler(alpnHandler) + }.flatMap { _ in + self.pipeline.handler(type: NIOTypedApplicationProtocolNegotiationHandler>.self).map { alpnHandler in + alpnHandler.protocolNegotiationResult + } + } } } diff --git a/Sources/HummingbirdTLS/TLSChannel.swift b/Sources/HummingbirdTLS/TLSChannel.swift index afa44f9c..8df0f7c1 100644 --- a/Sources/HummingbirdTLS/TLSChannel.swift +++ b/Sources/HummingbirdTLS/TLSChannel.swift @@ -37,7 +37,9 @@ public struct TLSChannel: ServerChildChannel { /// - Returns: Object to process input/output on child channel @inlinable public func setup(channel: Channel, logger: Logger) -> EventLoopFuture { - return channel.pipeline.addHandler(NIOSSLServerHandler(context: self.sslContext)).flatMap { + return channel.eventLoop.makeCompletedFuture { + try channel.pipeline.syncOperations.addHandler(NIOSSLServerHandler(context: self.sslContext)) + }.flatMap { self.baseChannel.setup(channel: channel, logger: logger) } } diff --git a/Sources/HummingbirdTesting/TestClient.swift b/Sources/HummingbirdTesting/TestClient.swift index 9d59897d..a3257439 100644 --- a/Sources/HummingbirdTesting/TestClient.swift +++ b/Sources/HummingbirdTesting/TestClient.swift @@ -83,14 +83,14 @@ public struct TestClient: Sendable { .channelOption(ChannelOptions.socket(SocketOptionLevel(IPPROTO_TCP), TCP_NODELAY), value: 1) .channelInitializer { channel in return channel.pipeline.addHTTPClientHandlers() - .flatMap { + .flatMapThrowing { let handlers: [ChannelHandler] = [ HTTP1ToHTTPClientCodec(), HTTPClientRequestSerializer(), HTTPClientResponseHandler(), HTTPTaskHandler(), ] - return channel.pipeline.addHandlers(handlers) + return try channel.pipeline.syncOperations.addHandlers(handlers) } } .connectTimeout(.seconds(5))