Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Channel setup builder #310

Merged
merged 5 commits into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 9 additions & 17 deletions Sources/Hummingbird/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<ChannelSetup> { get }

/// event loop group used by application
var eventLoopGroup: EventLoopGroup { get }
Expand All @@ -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<HTTP1Channel> { .http1() }
}

extension HBApplicationProtocol {
Expand All @@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -181,7 +179,7 @@ public struct HBApplication<Responder: HBResponder, ChannelSetup: HBChannelSetup
/// on server running
private var _onServerRunning: @Sendable (Channel) async -> Void
/// Server channel setup
let channelSetup: ChannelSetup
public let channelSetup: HBHTTPChannelSetupBuilder<ChannelSetup>
/// services attached to the application.
public var services: [any Service]

Expand All @@ -190,7 +188,7 @@ public struct HBApplication<Responder: HBResponder, ChannelSetup: HBChannelSetup
/// Initialize new Application
public init(
responder: Responder,
channelSetup: ChannelSetup = HTTP1Channel(),
channelSetup: HBHTTPChannelSetupBuilder<ChannelSetup> = .http1(),
configuration: HBApplicationConfiguration = HBApplicationConfiguration(),
eventLoopGroupProvider: EventLoopGroupProvider = .singleton
) {
Expand Down Expand Up @@ -219,12 +217,6 @@ public struct HBApplication<Responder: HBResponder, ChannelSetup: HBChannelSetup
return self.responder
}

public func channelSetup(httpResponder: @escaping @Sendable (HBRequest, Channel) async throws -> HBResponse) throws -> ChannelSetup {
var channelSetup = self.channelSetup
channelSetup.responder = httpResponder
return channelSetup
}

public func onServerRunning(_ channel: Channel) async {
await self._onServerRunning(channel)
}
Expand Down
6 changes: 3 additions & 3 deletions Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
public typealias Value = NIOAsyncChannel<HTTPRequestPart, HTTPResponsePart>

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] = { [] }

Check warning on line 26 in Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift

View check run for this annotation

Codecov / codecov/patch

Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift#L26

Added line #L26 was not covered by tests
) {
self.additionalChannelHandlers = additionalChannelHandlers
self.responder = responder
Expand Down Expand Up @@ -51,6 +51,6 @@
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]
}
3 changes: 2 additions & 1 deletion Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 33 additions & 0 deletions Sources/HummingbirdCore/Server/HTTP/HTTPChannelSetupBuilder.swift
Original file line number Diff line number Diff line change
@@ -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<ChannelSetup: HBChannelSetup>: 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<HTTP1Channel> {
return .init { responder in
return HTTP1Channel(responder: responder, additionalChannelHandlers: additionalChannelHandlers)
}
}
}
11 changes: 4 additions & 7 deletions Sources/HummingbirdHTTP2/HTTP2Channel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,20 @@
public typealias Value = EventLoopFuture<NIONegotiatedHTTPVersion<HTTP1Channel.Value, (NIOAsyncChannel<HTTP2Frame, HTTP2Frame>, NIOHTTP2Handler.AsyncStreamMultiplexer<HTTP1Channel.Value>)>>

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] = { [] },

Check warning on line 36 in Sources/HummingbirdHTTP2/HTTP2Channel.swift

View check run for this annotation

Codecov / codecov/patch

Sources/HummingbirdHTTP2/HTTP2Channel.swift#L36

Added line #L36 was not covered by tests
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<Value> {
Expand Down
32 changes: 32 additions & 0 deletions Sources/HummingbirdHTTP2/HTTP2ChannelSetupBuilder.swift
Original file line number Diff line number Diff line change
@@ -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<HTTP2Channel> {
return .init { responder in
return try HTTP2Channel(
tlsConfiguration: tlsConfiguration,
additionalChannelHandlers: additionalChannelHandlers,
responder: responder
)
}
}
}
3 changes: 1 addition & 2 deletions Sources/HummingbirdTLS/TLSChannelSetup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

extension TLSChannel: HTTPChannelHandler where BaseChannel: HTTPChannelHandler {
public var responder: @Sendable (HBRequest, Channel) async throws -> HBResponse {
get { baseChannel.responder }
set { baseChannel.responder = newValue }
baseChannel.responder

Check warning on line 35 in Sources/HummingbirdTLS/TLSChannelSetup.swift

View check run for this annotation

Codecov / codecov/patch

Sources/HummingbirdTLS/TLSChannelSetup.swift#L35

Added line #L35 was not covered by tests
}
}
27 changes: 27 additions & 0 deletions Sources/HummingbirdTLS/TLSChannelSetupBuilder.swift
Original file line number Diff line number Diff line change
@@ -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<BaseChannel: HBChannelSetup>(
_ base: HBHTTPChannelSetupBuilder<BaseChannel> = .http1(),
tlsConfiguration: TLSConfiguration
) throws -> HBHTTPChannelSetupBuilder<TLSChannel<BaseChannel>> {
return .init { responder in
return try TLSChannel(base.build(responder), tlsConfiguration: tlsConfiguration)
}
}
}
8 changes: 4 additions & 4 deletions Sources/HummingbirdXCT/HBXCTLive.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ final class HBXCTLive<App: HBApplicationProtocol>: 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<ChannelSetup> {
self.base.channelSetup
}

/// event loop group used by application
Expand Down
2 changes: 1 addition & 1 deletion Sources/HummingbirdXCT/HBXCTRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ struct HBXCTRouter<Responder: HBResponder>: HBXCTApplication where Responder.Con

init<App: HBApplicationProtocol>(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
}

Expand Down
Loading
Loading