diff --git a/Sources/Hummingbird/Application.swift b/Sources/Hummingbird/Application.swift index 302fd5ffb..6770f361b 100644 --- a/Sources/Hummingbird/Application.swift +++ b/Sources/Hummingbird/Application.swift @@ -51,9 +51,9 @@ public protocol HBApplicationProtocol: Service where Context: HBRequestContext { typealias Context = Responder.Context /// Build the responder - func buildResponder() async throws -> Responder + var responder: Responder { get async throws } /// Server channel setup - func channelSetup(httpResponder: @escaping @Sendable (HBRequest, Channel) async throws -> HBResponse) throws -> ChannelSetup + var channelSetup: HBHTTPChannelSetupBuilder { get } /// event loop group used by application var eventLoopGroup: EventLoopGroup { get } @@ -67,11 +67,9 @@ public protocol HBApplicationProtocol: Service where Context: HBRequestContext { var services: [any Service] { get } } -extension HBApplicationProtocol where ChannelSetup == HTTP1Channel { - /// Defautl channel setup function for HTTP1 channels - public func channelSetup(httpResponder: @escaping @Sendable (HBRequest, Channel) async throws -> HBResponse) -> ChannelSetup { - HTTP1Channel(responder: httpResponder) - } +extension HBApplicationProtocol { + /// Server channel setup + public var channelSetup: HBHTTPChannelSetupBuilder { .http1() } } extension HBApplicationProtocol { @@ -92,7 +90,7 @@ extension HBApplicationProtocol { /// Construct application and run it public func run() async throws { let dateCache = HBDateCache() - let responder = try await self.buildResponder() + let responder = try await self.responder // Function responding to HTTP request @Sendable func respond(to request: HBRequest, channel: Channel) async throws -> HBResponse { @@ -110,7 +108,7 @@ extension HBApplicationProtocol { return response } // get channel Setup - let channelSetup = try self.channelSetup(httpResponder: respond) + let channelSetup = try self.channelSetup.build(respond) // create server let server = HBServer( childChannelSetup: channelSetup, @@ -181,7 +179,7 @@ public struct HBApplication Void /// Server channel setup - let channelSetup: ChannelSetup + public let channelSetup: HBHTTPChannelSetupBuilder /// services attached to the application. public var services: [any Service] @@ -190,7 +188,7 @@ public struct HBApplication = .http1(), configuration: HBApplicationConfiguration = HBApplicationConfiguration(), eventLoopGroupProvider: EventLoopGroupProvider = .singleton ) { @@ -219,12 +217,6 @@ public struct HBApplication HBResponse) throws -> ChannelSetup { - var channelSetup = self.channelSetup - channelSetup.responder = httpResponder - return channelSetup - } - public func onServerRunning(_ channel: Channel) async { await self._onServerRunning(channel) } diff --git a/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift b/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift index 50f5130b6..775af9eb8 100644 --- a/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift +++ b/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift @@ -22,8 +22,8 @@ public struct HTTP1Channel: HBChannelSetup, HTTPChannelHandler { public typealias Value = NIOAsyncChannel public init( - additionalChannelHandlers: @autoclosure @escaping @Sendable () -> [any RemovableChannelHandler] = [], - responder: @escaping @Sendable (HBRequest, Channel) async throws -> HBResponse = { _, _ in throw HBHTTPError(.notImplemented) } + responder: @escaping @Sendable (HBRequest, Channel) async throws -> HBResponse, + additionalChannelHandlers: @escaping @Sendable () -> [any RemovableChannelHandler] = { [] } ) { self.additionalChannelHandlers = additionalChannelHandlers self.responder = responder @@ -51,6 +51,6 @@ public struct HTTP1Channel: HBChannelSetup, HTTPChannelHandler { await handleHTTP(asyncChannel: asyncChannel, logger: logger) } - public var responder: @Sendable (HBRequest, Channel) async throws -> HBResponse + public let responder: @Sendable (HBRequest, Channel) async throws -> HBResponse let additionalChannelHandlers: @Sendable () -> [any RemovableChannelHandler] } diff --git a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift index 03b1d0599..80411dfb0 100644 --- a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift +++ b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift @@ -21,7 +21,8 @@ import ServiceLifecycle /// Protocol for HTTP channels public protocol HTTPChannelHandler: HBChannelSetup { - var responder: @Sendable (HBRequest, Channel) async throws -> HBResponse { get set } + typealias Responder = @Sendable (HBRequest, Channel) async throws -> HBResponse + var responder: Responder { get } } /// Internal error thrown when an unexpected HTTP part is received eg we didn't receive diff --git a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelSetupBuilder.swift b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelSetupBuilder.swift new file mode 100644 index 000000000..fc094550b --- /dev/null +++ b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelSetupBuilder.swift @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 2023 the Hummingbird authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore + +/// Build Channel Setup that takes an HTTP responder +public struct HBHTTPChannelSetupBuilder: Sendable { + public let build: @Sendable (@escaping HTTPChannelHandler.Responder) throws -> ChannelSetup + public init(_ build: @escaping @Sendable (@escaping HTTPChannelHandler.Responder) throws -> ChannelSetup) { + self.build = build + } +} + +extension HBHTTPChannelSetupBuilder { + public static func http1( + additionalChannelHandlers: @autoclosure @escaping @Sendable () -> [any RemovableChannelHandler] = [] + ) -> HBHTTPChannelSetupBuilder { + return .init { responder in + return HTTP1Channel(responder: responder, additionalChannelHandlers: additionalChannelHandlers) + } + } +} diff --git a/Sources/HummingbirdHTTP2/HTTP2Channel.swift b/Sources/HummingbirdHTTP2/HTTP2Channel.swift index b7a7ff61a..2101f032f 100644 --- a/Sources/HummingbirdHTTP2/HTTP2Channel.swift +++ b/Sources/HummingbirdHTTP2/HTTP2Channel.swift @@ -27,23 +27,20 @@ public struct HTTP2Channel: HTTPChannelHandler { public typealias Value = EventLoopFuture, NIOHTTP2Handler.AsyncStreamMultiplexer)>> private let sslContext: NIOSSLContext - private var http1: HTTP1Channel + private let http1: HTTP1Channel private let additionalChannelHandlers: @Sendable () -> [any RemovableChannelHandler] - public var responder: @Sendable (HBRequest, Channel) async throws -> HBResponse { - get { http1.responder } - set { http1.responder = newValue } - } + public var responder: @Sendable (HBRequest, Channel) async throws -> HBResponse { http1.responder } public init( tlsConfiguration: TLSConfiguration, - additionalChannelHandlers: @autoclosure @escaping @Sendable () -> [any RemovableChannelHandler] = [], + additionalChannelHandlers: @escaping @Sendable () -> [any RemovableChannelHandler] = { [] }, responder: @escaping @Sendable (HBRequest, Channel) async throws -> HBResponse = { _, _ in throw HBHTTPError(.notImplemented) } ) throws { var tlsConfiguration = tlsConfiguration tlsConfiguration.applicationProtocols = NIOHTTP2SupportedALPNProtocols self.sslContext = try NIOSSLContext(configuration: tlsConfiguration) self.additionalChannelHandlers = additionalChannelHandlers - self.http1 = HTTP1Channel(additionalChannelHandlers: additionalChannelHandlers(), responder: responder) + self.http1 = HTTP1Channel(responder: responder, additionalChannelHandlers: additionalChannelHandlers) } public func initialize(channel: Channel, configuration: HBServerConfiguration, logger: Logger) -> EventLoopFuture { diff --git a/Sources/HummingbirdHTTP2/HTTP2ChannelSetupBuilder.swift b/Sources/HummingbirdHTTP2/HTTP2ChannelSetupBuilder.swift new file mode 100644 index 000000000..01563585e --- /dev/null +++ b/Sources/HummingbirdHTTP2/HTTP2ChannelSetupBuilder.swift @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 2023 the Hummingbird authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import HummingbirdCore +import NIOCore +import NIOSSL + +extension HBHTTPChannelSetupBuilder { + public static func http2( + tlsConfiguration: TLSConfiguration, + additionalChannelHandlers: @autoclosure @escaping @Sendable () -> [any RemovableChannelHandler] = [] + ) throws -> HBHTTPChannelSetupBuilder { + return .init { responder in + return try HTTP2Channel( + tlsConfiguration: tlsConfiguration, + additionalChannelHandlers: additionalChannelHandlers, + responder: responder + ) + } + } +} diff --git a/Sources/HummingbirdTLS/TLSChannelSetup.swift b/Sources/HummingbirdTLS/TLSChannelSetup.swift index 9eb1e7e8b..90eb03a9e 100644 --- a/Sources/HummingbirdTLS/TLSChannelSetup.swift +++ b/Sources/HummingbirdTLS/TLSChannelSetup.swift @@ -32,7 +32,6 @@ public struct TLSChannel: HBChannelSetup { extension TLSChannel: HTTPChannelHandler where BaseChannel: HTTPChannelHandler { public var responder: @Sendable (HBRequest, Channel) async throws -> HBResponse { - get { baseChannel.responder } - set { baseChannel.responder = newValue } + baseChannel.responder } } diff --git a/Sources/HummingbirdTLS/TLSChannelSetupBuilder.swift b/Sources/HummingbirdTLS/TLSChannelSetupBuilder.swift new file mode 100644 index 000000000..3035db9ca --- /dev/null +++ b/Sources/HummingbirdTLS/TLSChannelSetupBuilder.swift @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 2023 the Hummingbird authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import HummingbirdCore +import NIOSSL + +extension HBHTTPChannelSetupBuilder { + public static func tls( + _ base: HBHTTPChannelSetupBuilder = .http1(), + tlsConfiguration: TLSConfiguration + ) throws -> HBHTTPChannelSetupBuilder> { + return .init { responder in + return try TLSChannel(base.build(responder), tlsConfiguration: tlsConfiguration) + } + } +} diff --git a/Sources/HummingbirdXCT/HBXCTLive.swift b/Sources/HummingbirdXCT/HBXCTLive.swift index 787a7519f..d2a5cd4da 100644 --- a/Sources/HummingbirdXCT/HBXCTLive.swift +++ b/Sources/HummingbirdXCT/HBXCTLive.swift @@ -32,12 +32,12 @@ final class HBXCTLive: HBXCTApplication { let base: BaseApp - func buildResponder() async throws -> Responder { - try await self.base.buildResponder() + var responder: Responder { + get async throws { try await self.base.responder } } - func channelSetup(httpResponder: @escaping @Sendable (HBRequest, Channel) async throws -> HBResponse) throws -> ChannelSetup { - try self.base.channelSetup(httpResponder: httpResponder) + var channelSetup: HBHTTPChannelSetupBuilder { + self.base.channelSetup } /// event loop group used by application diff --git a/Sources/HummingbirdXCT/HBXCTRouter.swift b/Sources/HummingbirdXCT/HBXCTRouter.swift index 7f75bb2b0..7671d1b36 100644 --- a/Sources/HummingbirdXCT/HBXCTRouter.swift +++ b/Sources/HummingbirdXCT/HBXCTRouter.swift @@ -68,7 +68,7 @@ struct HBXCTRouter: HBXCTApplication where Responder.Con init(app: App) async throws where App.Responder == Responder { self.eventLoopGroup = app.eventLoopGroup - self.responder = try await app.buildResponder() + self.responder = try await app.responder self.logger = app.logger } diff --git a/Tests/HummingbirdCoreTests/CoreTests.swift b/Tests/HummingbirdCoreTests/CoreTests.swift index 1ee2cbf9d..9c36ae34d 100644 --- a/Tests/HummingbirdCoreTests/CoreTests.swift +++ b/Tests/HummingbirdCoreTests/CoreTests.swift @@ -49,7 +49,8 @@ class HummingBirdCoreTests: XCTestCase { func testConnect() async throws { try await testServer( - childChannelSetup: HTTP1Channel(responder: helloResponder), + responder: helloResponder, + httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, logger: Logger(label: "HB") @@ -62,7 +63,7 @@ class HummingBirdCoreTests: XCTestCase { func testMultipleRequests() async throws { try await testServer( - childChannelSetup: HTTP1Channel(responder: helloResponder), + responder: helloResponder, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, logger: Logger(label: "HB") @@ -77,7 +78,8 @@ class HummingBirdCoreTests: XCTestCase { func testError() async throws { try await testServer( - childChannelSetup: HTTP1Channel { _, _ in throw HBHTTPError(.unauthorized) }, + responder: { _, _ in throw HBHTTPError(.unauthorized) }, + httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, logger: Logger(label: "HB") @@ -90,7 +92,7 @@ class HummingBirdCoreTests: XCTestCase { func testConsumeBody() async throws { try await testServer( - childChannelSetup: HTTP1Channel { request, _ in + responder: { request, _ in let buffer = try await request.body.collect(upTo: .max) return HBResponse(status: .ok, body: .init(byteBuffer: buffer)) }, @@ -107,7 +109,7 @@ class HummingBirdCoreTests: XCTestCase { func testWriteBody() async throws { try await testServer( - childChannelSetup: HTTP1Channel { _, _ in + responder: { _, _ in let buffer = self.randomBuffer(size: 1_140_000) return HBResponse(status: .ok, body: .init(byteBuffer: buffer)) }, @@ -123,7 +125,7 @@ class HummingBirdCoreTests: XCTestCase { func testStreamBody() async throws { try await testServer( - childChannelSetup: HTTP1Channel { request, _ in + responder: { request, _ in return HBResponse(status: .ok, body: .init(asyncSequence: request.body)) }, configuration: .init(address: .hostname(port: 0)), @@ -139,7 +141,7 @@ class HummingBirdCoreTests: XCTestCase { func testStreamBodyWriteSlow() async throws { try await testServer( - childChannelSetup: HTTP1Channel { request, _ in + responder: { request, _ in return HBResponse(status: .ok, body: .init(asyncSequence: request.body.delayed())) }, configuration: .init(address: .hostname(port: 0)), @@ -167,9 +169,10 @@ class HummingBirdCoreTests: XCTestCase { } } try await testServer( - childChannelSetup: HTTP1Channel(additionalChannelHandlers: [SlowInputChannelHandler()]) { request, _ in + responder: { request, _ in return HBResponse(status: .ok, body: .init(asyncSequence: request.body.delayed())) }, + httpChannelSetup: .http1(additionalChannelHandlers: [SlowInputChannelHandler()]), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, logger: Logger(label: "HB") @@ -194,10 +197,11 @@ class HummingBirdCoreTests: XCTestCase { } } try await testServer( - childChannelSetup: HTTP1Channel(additionalChannelHandlers: [CreateErrorHandler()]) { request, _ in + responder: { request, _ in _ = try await request.body.collect(upTo: .max) return HBResponse(status: .ok) }, + httpChannelSetup: .http1(additionalChannelHandlers: [CreateErrorHandler()]), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, logger: Logger(label: "HB") @@ -210,7 +214,7 @@ class HummingBirdCoreTests: XCTestCase { func testDropRequestBody() async throws { try await testServer( - childChannelSetup: HTTP1Channel { _, _ in + responder: { _, _ in // ignore request body return HBResponse(status: .accepted) }, @@ -229,7 +233,7 @@ class HummingBirdCoreTests: XCTestCase { /// test server closes connection if "connection" header is set to "close" func testConnectionClose() async throws { try await testServer( - childChannelSetup: HTTP1Channel(responder: helloResponder), + responder: helloResponder, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, logger: Logger(label: "HB") @@ -259,13 +263,11 @@ class HummingBirdCoreTests: XCTestCase { } } try await testServer( - childChannelSetup: HTTP1Channel( - additionalChannelHandlers: [HTTPServerIncompleteRequest(), IdleStateHandler(readTimeout: .seconds(1))], - responder: { request, _ in - _ = try await request.body.collect(upTo: .max) - return .init(status: .ok) - } - ), + responder: { request, _ in + _ = try await request.body.collect(upTo: .max) + return .init(status: .ok) + }, + httpChannelSetup: .http1(additionalChannelHandlers: [HTTPServerIncompleteRequest(), IdleStateHandler(readTimeout: .seconds(1))]), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, logger: Logger(label: "HB") @@ -284,13 +286,11 @@ class HummingBirdCoreTests: XCTestCase { func testWriteIdleTimeout() async throws { try await testServer( - childChannelSetup: HTTP1Channel( - additionalChannelHandlers: [IdleStateHandler(writeTimeout: .seconds(1))], - responder: { request, _ in - _ = try await request.body.collect(upTo: .max) - return .init(status: .ok) - } - ), + responder: { request, _ in + _ = try await request.body.collect(upTo: .max) + return .init(status: .ok) + }, + httpChannelSetup: .http1(additionalChannelHandlers: [IdleStateHandler(writeTimeout: .seconds(1))]), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, logger: Logger(label: "HB") @@ -307,11 +307,12 @@ class HummingBirdCoreTests: XCTestCase { let promise = Promise() try await testServer( - childChannelSetup: HTTP1Channel { request, _ in + responder: { request, _ in await promise.complete(()) try await Task.sleep(for: .milliseconds(500)) return HBResponse(status: .ok, body: .init(asyncSequence: request.body.delayed())) }, + httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, logger: Logger(label: "HB") @@ -336,10 +337,11 @@ class HummingBirdCoreTests: XCTestCase { func testIdleChildChannelGracefulShutdown() async throws { try await testServer( - childChannelSetup: HTTP1Channel { request, _ in + responder: { request, _ in try await Task.sleep(for: .milliseconds(500)) return HBResponse(status: .ok, body: .init(asyncSequence: request.body.delayed())) }, + httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, logger: Logger(label: "HB") diff --git a/Tests/HummingbirdCoreTests/HTTP2Tests.swift b/Tests/HummingbirdCoreTests/HTTP2Tests.swift index ceeeb59ee..0931f7f6f 100644 --- a/Tests/HummingbirdCoreTests/HTTP2Tests.swift +++ b/Tests/HummingbirdCoreTests/HTTP2Tests.swift @@ -29,9 +29,10 @@ class HummingBirdHTTP2Tests: XCTestCase { let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 2) defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) } try await testServer( - childChannelSetup: HTTP2Channel(tlsConfiguration: self.getServerTLSConfiguration()) { _, _ in + responder: { _, _ in .init(status: .ok) }, + httpChannelSetup: .http2(tlsConfiguration: self.getServerTLSConfiguration()), configuration: .init(address: .hostname(port: 0), serverName: testServerName), eventLoopGroup: eventLoopGroup, logger: Logger(label: "HB") diff --git a/Tests/HummingbirdCoreTests/TLSTests.swift b/Tests/HummingbirdCoreTests/TLSTests.swift index a2d984e48..6820bcca2 100644 --- a/Tests/HummingbirdCoreTests/TLSTests.swift +++ b/Tests/HummingbirdCoreTests/TLSTests.swift @@ -27,7 +27,8 @@ class HummingBirdTLSTests: XCTestCase { let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 2) defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) } try await testServer( - childChannelSetup: TLSChannel(HTTP1Channel(responder: helloResponder), tlsConfiguration: self.getServerTLSConfiguration()), + responder: helloResponder, + httpChannelSetup: .tls(tlsConfiguration: self.getServerTLSConfiguration()), configuration: .init(address: .hostname(port: 0), serverName: testServerName), eventLoopGroup: eventLoopGroup, logger: Logger(label: "HB"), diff --git a/Tests/HummingbirdCoreTests/TSTests.swift b/Tests/HummingbirdCoreTests/TSTests.swift index c23904850..2bc6a0ca1 100644 --- a/Tests/HummingbirdCoreTests/TSTests.swift +++ b/Tests/HummingbirdCoreTests/TSTests.swift @@ -34,7 +34,7 @@ class TransportServicesTests: XCTestCase { let eventLoopGroup = NIOTSEventLoopGroup() defer { try? eventLoopGroup.syncShutdownGracefully() } try await testServer( - childChannelSetup: HTTP1Channel(responder: helloResponder), + responder: helloResponder, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: eventLoopGroup, logger: Logger(label: "HB") @@ -52,7 +52,7 @@ class TransportServicesTests: XCTestCase { serverIdentity: .p12(filename: p12Path, password: "MyPassword") )) try await testServer( - childChannelSetup: HTTP1Channel(responder: helloResponder), + responder: helloResponder, configuration: .init(address: .hostname(port: 0), serverName: testServerName, tlsOptions: tlsOptions), eventLoopGroup: eventLoopGroup, logger: Logger(label: "HB"), diff --git a/Tests/HummingbirdCoreTests/TestUtils.swift b/Tests/HummingbirdCoreTests/TestUtils.swift index 895d106ab..59be1ff58 100644 --- a/Tests/HummingbirdCoreTests/TestUtils.swift +++ b/Tests/HummingbirdCoreTests/TestUtils.swift @@ -32,7 +32,8 @@ public enum TestErrors: Error { /// Helper function for testing a server public func testServer( - childChannelSetup: ChannelSetup, + responder: @escaping HTTPChannelHandler.Responder, + httpChannelSetup: HBHTTPChannelSetupBuilder, configuration: HBServerConfiguration, eventLoopGroup: EventLoopGroup, logger: Logger, @@ -40,8 +41,8 @@ public func testServer( ) async throws -> Value { try await withThrowingTaskGroup(of: Void.self) { group in let promise = Promise() - let server = HBServer( - childChannelSetup: childChannelSetup, + let server = try HBServer( + childChannelSetup: httpChannelSetup.build(responder), configuration: configuration, onServerRunning: { await promise.complete($0.localAddress!.port!) }, eventLoopGroup: eventLoopGroup, @@ -68,7 +69,8 @@ public func testServer( /// Creates test client, runs test function abd ensures everything is /// shutdown correctly public func testServer( - childChannelSetup: ChannelSetup, + responder: @escaping HTTPChannelHandler.Responder, + httpChannelSetup: HBHTTPChannelSetupBuilder, configuration: HBServerConfiguration, eventLoopGroup: EventLoopGroup, logger: Logger, @@ -77,8 +79,8 @@ public func testServer( ) async throws -> Value { try await withThrowingTaskGroup(of: Void.self) { group in let promise = Promise() - let server = HBServer( - childChannelSetup: childChannelSetup, + let server = try HBServer( + childChannelSetup: httpChannelSetup.build(responder), configuration: configuration, onServerRunning: { await promise.complete($0.localAddress!.port!) }, eventLoopGroup: eventLoopGroup, @@ -109,7 +111,8 @@ public func testServer( } public func testServer( - childChannelSetup: some HBChannelSetup, + responder: @escaping HTTPChannelHandler.Responder, + httpChannelSetup: HBHTTPChannelSetupBuilder = .http1(), configuration: HBServerConfiguration, eventLoopGroup: EventLoopGroup, logger: Logger, @@ -117,7 +120,8 @@ public func testServer( _ test: @escaping @Sendable (HBXCTClient) async throws -> Value ) async throws -> Value { try await testServer( - childChannelSetup: childChannelSetup, + responder: responder, + httpChannelSetup: httpChannelSetup, configuration: configuration, eventLoopGroup: eventLoopGroup, logger: logger, diff --git a/Tests/HummingbirdTests/ApplicationTests.swift b/Tests/HummingbirdTests/ApplicationTests.swift index f51bfbce5..ecc3dcc13 100644 --- a/Tests/HummingbirdTests/ApplicationTests.swift +++ b/Tests/HummingbirdTests/ApplicationTests.swift @@ -480,9 +480,8 @@ final class ApplicationTests: XCTestCase { func testApplicationProtocol() async throws { struct MyApp: HBApplicationProtocol { typealias Context = HBTestRouterContext - typealias ChannelSetup = HTTP1Channel - func buildResponder() async throws -> some HBResponder { + var responder: some HBResponder { let router = HBRouter(context: Context.self) router.get("/hello") { _, context -> ByteBuffer in return context.allocator.buffer(string: "GET: Hello")