Skip to content

Commit

Permalink
Move maxFrameSize into configuration type
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-fowler committed Mar 19, 2024
1 parent 4a91504 commit cc78bdb
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 51 deletions.
39 changes: 9 additions & 30 deletions Sources/HummingbirdWebSocket/Client/WebSocketClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,6 @@ import ServiceLifecycle
/// }
/// ```
public struct WebSocketClient {
public struct Configuration: Sendable {
/// Max websocket frame size that can be sent/received
public var maxFrameSize: Int
/// Additional headers to be sent with the initial HTTP request
public var additionalHeaders: HTTPFields

/// Initialize WebSocketClient configuration
/// - Paramters
/// - maxFrameSize: Max websocket frame size that can be sent/received
/// - additionalHeaders: Additional headers to be sent with the initial HTTP request
public init(
maxFrameSize: Int = (1 << 14),
additionalHeaders: HTTPFields = .init()
) {
self.maxFrameSize = maxFrameSize
self.additionalHeaders = additionalHeaders
}
}

enum MultiPlatformTLSConfiguration: Sendable {
case niossl(TLSConfiguration)
#if canImport(Network)
Expand All @@ -71,7 +52,7 @@ public struct WebSocketClient {
/// WebSocket data handler
let handler: WebSocketDataCallbackHandler
/// configuration
let configuration: Configuration
let configuration: WebSocketClientConfiguration
/// EventLoopGroup to use
let eventLoopGroup: EventLoopGroup
/// Logger
Expand All @@ -90,7 +71,7 @@ public struct WebSocketClient {
/// - logger: Logger
public init(
url: URI,
configuration: Configuration = .init(),
configuration: WebSocketClientConfiguration = .init(),
tlsConfiguration: TLSConfiguration? = nil,
eventLoopGroup: EventLoopGroup = MultiThreadedEventLoopGroup.singleton,
logger: Logger,
Expand All @@ -116,7 +97,7 @@ public struct WebSocketClient {
/// - logger: Logger
public init(
url: URI,
configuration: Configuration = .init(),
configuration: WebSocketClientConfiguration = .init(),
transportServicesTLSOptions: TSTLSOptions,
eventLoopGroup: NIOTSEventLoopGroup = NIOTSEventLoopGroup.singleton,
logger: Logger,
Expand All @@ -143,7 +124,7 @@ public struct WebSocketClient {
case .niossl(let tlsConfiguration):
let client = try ClientConnection(
TLSClientChannel(
WebSocketClientChannel(handler: handler, url: urlPath, maxFrameSize: self.configuration.maxFrameSize),
WebSocketClientChannel(handler: handler, url: urlPath, configuration: self.configuration),
tlsConfiguration: tlsConfiguration
),
address: .hostname(host, port: port),
Expand All @@ -155,7 +136,7 @@ public struct WebSocketClient {
#if canImport(Network)
case .ts(let tlsOptions):
let client = try ClientConnection(
WebSocketClientChannel(handler: handler, url: urlPath, maxFrameSize: self.configuration.maxFrameSize),
WebSocketClientChannel(handler: handler, url: urlPath, configuration: self.configuration),
address: .hostname(host, port: port),
transportServicesTLSOptions: tlsOptions,
eventLoopGroup: self.eventLoopGroup,
Expand All @@ -170,8 +151,7 @@ public struct WebSocketClient {
WebSocketClientChannel(
handler: handler,
url: urlPath,
maxFrameSize: self.configuration.maxFrameSize,
additionalHeaders: self.configuration.additionalHeaders
configuration: self.configuration
),
tlsConfiguration: TLSConfiguration.makeClientConfiguration()
),
Expand All @@ -186,8 +166,7 @@ public struct WebSocketClient {
WebSocketClientChannel(
handler: handler,
url: urlPath,
maxFrameSize: self.configuration.maxFrameSize,
additionalHeaders: self.configuration.additionalHeaders
configuration: self.configuration
),
address: .hostname(host, port: port),
eventLoopGroup: self.eventLoopGroup,
Expand All @@ -210,7 +189,7 @@ extension WebSocketClient {
/// - process: Closure handling webSocket
public static func connect(
url: URI,
configuration: Configuration = .init(),
configuration: WebSocketClientConfiguration = .init(),
tlsConfiguration: TLSConfiguration? = nil,
eventLoopGroup: EventLoopGroup = MultiThreadedEventLoopGroup.singleton,
logger: Logger,
Expand Down Expand Up @@ -239,7 +218,7 @@ extension WebSocketClient {
/// - process: WebSocket data handler
public static func connect(
url: URI,
configuration: Configuration = .init(),
configuration: WebSocketClientConfiguration = .init(),
transportServicesTLSOptions: TSTLSOptions,
eventLoopGroup: NIOTSEventLoopGroup = NIOTSEventLoopGroup.singleton,
logger: Logger,
Expand Down
12 changes: 5 additions & 7 deletions Sources/HummingbirdWebSocket/Client/WebSocketClientChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,18 @@ public struct WebSocketClientChannel<Handler: WebSocketDataHandler>: ClientConne

let url: String
let handler: Handler
let maxFrameSize: Int
let additionalHeaders: HTTPFields
let configuration: WebSocketClientConfiguration

init(handler: Handler, url: String, maxFrameSize: Int = 1 << 14, additionalHeaders: HTTPFields = .init()) {
init(handler: Handler, url: String, configuration: WebSocketClientConfiguration) {
self.url = url
self.handler = handler
self.maxFrameSize = maxFrameSize
self.additionalHeaders = additionalHeaders
self.configuration = configuration
}

public func setup(channel: any Channel, logger: Logger) -> NIOCore.EventLoopFuture<Value> {
channel.eventLoop.makeCompletedFuture {
let upgrader = NIOTypedWebSocketClientUpgrader<UpgradeResult>(
maxFrameSize: maxFrameSize,
maxFrameSize: self.configuration.maxFrameSize,
upgradePipelineHandler: { channel, _ in
channel.eventLoop.makeCompletedFuture {
let asyncChannel = try NIOAsyncChannel<WebSocketFrame, WebSocketFrame>(wrappingChannelSynchronously: channel)
Expand All @@ -55,7 +53,7 @@ public struct WebSocketClientChannel<Handler: WebSocketDataHandler>: ClientConne
var headers = HTTPHeaders()
headers.add(name: "Content-Type", value: "text/plain; charset=utf-8")
headers.add(name: "Content-Length", value: "0")
let additionalHeaders = HTTPHeaders(self.additionalHeaders)
let additionalHeaders = HTTPHeaders(self.configuration.additionalHeaders)
headers.add(contentsOf: additionalHeaders)

let requestHead = HTTPRequestHead(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Hummingbird server framework project
//
// Copyright (c) 2023-2024 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 HTTPTypes

public struct WebSocketClientConfiguration: Sendable {
/// Max websocket frame size that can be sent/received
public var maxFrameSize: Int
/// Additional headers to be sent with the initial HTTP request
public var additionalHeaders: HTTPFields

/// Initialize WebSocketClient configuration
/// - Paramters
/// - maxFrameSize: Max websocket frame size that can be sent/received
/// - additionalHeaders: Additional headers to be sent with the initial HTTP request
public init(
maxFrameSize: Int = (1 << 14),
additionalHeaders: HTTPFields = .init()
) {
self.maxFrameSize = maxFrameSize
self.additionalHeaders = additionalHeaders
}
}
12 changes: 6 additions & 6 deletions Sources/HummingbirdWebSocket/Server/WebSocketChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ public struct HTTP1AndWebSocketChannel<Handler: WebSocketDataHandler>: ServerChi
public init(
additionalChannelHandlers: @escaping @Sendable () -> [any RemovableChannelHandler] = { [] },
responder: @escaping @Sendable (Request, Channel) async throws -> Response = { _, _ in throw HTTPError(.notImplemented) },
maxFrameSize: Int = (1 << 14),
configuration: WebSocketServerConfiguration,
shouldUpgrade: @escaping @Sendable (HTTPRequest, Channel, Logger) throws -> ShouldUpgradeResult<Handler>
) {
self.additionalChannelHandlers = additionalChannelHandlers
self.maxFrameSize = maxFrameSize
self.configuration = configuration
self.shouldUpgrade = { head, channel, logger in
channel.eventLoop.makeCompletedFuture {
try shouldUpgrade(head, channel, logger)
Expand All @@ -65,11 +65,11 @@ public struct HTTP1AndWebSocketChannel<Handler: WebSocketDataHandler>: ServerChi
public init(
additionalChannelHandlers: @escaping @Sendable () -> [any RemovableChannelHandler] = { [] },
responder: @escaping @Sendable (Request, Channel) async throws -> Response = { _, _ in throw HTTPError(.notImplemented) },
maxFrameSize: Int = (1 << 14),
configuration: WebSocketServerConfiguration,
shouldUpgrade: @escaping @Sendable (HTTPRequest, Channel, Logger) async throws -> ShouldUpgradeResult<Handler>
) {
self.additionalChannelHandlers = additionalChannelHandlers
self.maxFrameSize = maxFrameSize
self.configuration = configuration
self.shouldUpgrade = { head, channel, logger in
let promise = channel.eventLoop.makePromise(of: ShouldUpgradeResult<Handler>.self)
promise.completeWithTask {
Expand All @@ -90,7 +90,7 @@ public struct HTTP1AndWebSocketChannel<Handler: WebSocketDataHandler>: ServerChi
return channel.eventLoop.makeCompletedFuture {
let upgradeAttempted = NIOLoopBoundBox(false, eventLoop: channel.eventLoop)
let upgrader = NIOTypedWebSocketServerUpgrader<UpgradeResult>(
maxFrameSize: self.maxFrameSize,
maxFrameSize: self.configuration.maxFrameSize,
shouldUpgrade: { channel, head in
upgradeAttempted.value = true
return self.shouldUpgrade(head, channel, logger)
Expand Down Expand Up @@ -178,6 +178,6 @@ public struct HTTP1AndWebSocketChannel<Handler: WebSocketDataHandler>: ServerChi

public var responder: @Sendable (Request, Channel) async throws -> Response
let shouldUpgrade: @Sendable (HTTPRequest, Channel, Logger) -> EventLoopFuture<ShouldUpgradeResult<Handler>>
let maxFrameSize: Int
let configuration: WebSocketServerConfiguration
let additionalChannelHandlers: @Sendable () -> [any RemovableChannelHandler]
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ extension HTTPChannelBuilder {
/// - parameters
public static func webSocketUpgrade<Handler: WebSocketDataHandler>(
additionalChannelHandlers: @autoclosure @escaping @Sendable () -> [any RemovableChannelHandler] = [],
maxFrameSize: Int = 1 << 14,
configuration: WebSocketServerConfiguration = .init(),
shouldUpgrade: @escaping @Sendable (HTTPRequest, Channel, Logger) async throws -> ShouldUpgradeResult<Handler>
) -> HTTPChannelBuilder<HTTP1AndWebSocketChannel<Handler>> {
return .init { responder in
return HTTP1AndWebSocketChannel(
additionalChannelHandlers: additionalChannelHandlers,
responder: responder,
maxFrameSize: maxFrameSize,
configuration: configuration,
shouldUpgrade: shouldUpgrade
)
}
Expand All @@ -38,14 +38,14 @@ extension HTTPChannelBuilder {
/// HTTP1 channel builder supporting a websocket upgrade
public static func webSocketUpgrade<Handler: WebSocketDataHandler>(
additionalChannelHandlers: @autoclosure @escaping @Sendable () -> [any RemovableChannelHandler] = [],
maxFrameSize: Int = 1 << 14,
configuration: WebSocketServerConfiguration = .init(),
shouldUpgrade: @escaping @Sendable (HTTPRequest, Channel, Logger) throws -> ShouldUpgradeResult<Handler>
) -> HTTPChannelBuilder<HTTP1AndWebSocketChannel<Handler>> {
return .init { responder in
return HTTP1AndWebSocketChannel<Handler>(
additionalChannelHandlers: additionalChannelHandlers,
responder: responder,
maxFrameSize: maxFrameSize,
configuration: configuration,
shouldUpgrade: shouldUpgrade
)
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/HummingbirdWebSocket/Server/WebSocketRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ extension HTTP1AndWebSocketChannel {
public init<Context: WebSocketRequestContext, ResponderBuilder: HTTPResponderBuilder>(
additionalChannelHandlers: @escaping @Sendable () -> [any RemovableChannelHandler] = { [] },
responder: @escaping @Sendable (Request, Channel) async throws -> Response = { _, _ in throw HTTPError(.notImplemented) },
maxFrameSize: Int = (1 << 14),
configuration: WebSocketServerConfiguration,
webSocketRouter: ResponderBuilder
) where Handler == WebSocketDataCallbackHandler, ResponderBuilder.Responder.Context == Context {
let webSocketRouterResponder = webSocketRouter.buildResponder()
self.init(additionalChannelHandlers: additionalChannelHandlers, responder: responder, maxFrameSize: maxFrameSize) { head, channel, logger in
self.init(additionalChannelHandlers: additionalChannelHandlers, responder: responder, configuration: configuration) { head, channel, logger in
let request = Request(head: head, body: .init(buffer: .init()))
let context = Context(channel: channel, logger: logger.with(metadataKey: "hb_id", value: .stringConvertible(RequestID())))
do {
Expand All @@ -104,14 +104,14 @@ extension HTTPChannelBuilder {
/// - parameters
public static func webSocketUpgrade<ResponderBuilder: HTTPResponderBuilder>(
additionalChannelHandlers: @autoclosure @escaping @Sendable () -> [any RemovableChannelHandler] = [],
maxFrameSize: Int = 1 << 14,
configuration: WebSocketServerConfiguration = .init(),
webSocketRouter: ResponderBuilder
) -> HTTPChannelBuilder<HTTP1AndWebSocketChannel<WebSocketDataCallbackHandler>> where ResponderBuilder.Responder.Context: WebSocketRequestContext {
return .init { responder in
return HTTP1AndWebSocketChannel(
additionalChannelHandlers: additionalChannelHandlers,
responder: responder,
maxFrameSize: maxFrameSize,
configuration: configuration,
webSocketRouter: webSocketRouter
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Hummingbird server framework project
//
// Copyright (c) 2023-2024 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
//
//===----------------------------------------------------------------------===//

/// Configuration for a WebSocket server
public struct WebSocketServerConfiguration: Sendable {
/// Max websocket frame size that can be sent/received
public var maxFrameSize: Int

/// Initialize WebSocketClient configuration
/// - Paramters
/// - maxFrameSize: Max websocket frame size that can be sent/received
/// - additionalHeaders: Additional headers to be sent with the initial HTTP request
public init(
maxFrameSize: Int = (1 << 14)
) {
self.maxFrameSize = maxFrameSize
}
}

0 comments on commit cc78bdb

Please sign in to comment.