From 08383f63a2949fb9573fa75ee2db8770bb155395 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 9 Mar 2024 07:31:39 +0000 Subject: [PATCH 01/11] Rename ChildChannel -> ServerChildChannel, Response -> RequestResponder --- Sources/Hummingbird/Application.swift | 6 +++--- Sources/Hummingbird/Middleware/Middleware.swift | 2 +- Sources/Hummingbird/Middleware/MiddlewareGroup.swift | 2 +- Sources/Hummingbird/Router/EndpointResponder.swift | 6 +++--- Sources/Hummingbird/Router/Router.swift | 6 +++--- Sources/Hummingbird/Router/RouterResponder.swift | 6 +++--- Sources/Hummingbird/Server/Responder.swift | 6 +++--- Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift | 2 +- .../HummingbirdCore/Server/HTTP/HTTPChannelBuilder.swift | 2 +- .../HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift | 2 +- Sources/HummingbirdCore/Server/Server.swift | 2 +- .../Server/{ChildChannel.swift => ServerChildChannel.swift} | 2 +- Sources/HummingbirdRouter/RouterBuilder.swift | 2 +- Sources/HummingbirdTLS/TLSChannel.swift | 2 +- Sources/HummingbirdTLS/TLSChannelBuilder.swift | 2 +- Sources/HummingbirdTesting/RouterTestFramework.swift | 2 +- Tests/HummingbirdCoreTests/ClientTests.swift | 2 +- Tests/HummingbirdCoreTests/TestUtils.swift | 6 +++--- Tests/HummingbirdTests/ApplicationTests.swift | 2 +- 19 files changed, 31 insertions(+), 31 deletions(-) rename Sources/HummingbirdCore/Server/{ChildChannel.swift => ServerChildChannel.swift} (95%) diff --git a/Sources/Hummingbird/Application.swift b/Sources/Hummingbird/Application.swift index ea9cf2566..86b9a1861 100644 --- a/Sources/Hummingbird/Application.swift +++ b/Sources/Hummingbird/Application.swift @@ -43,9 +43,9 @@ public enum EventLoopGroupProvider { public protocol HBApplicationProtocol: Service where Context: HBRequestContext { /// Responder that generates a response from a requests and context - associatedtype Responder: HBResponder + associatedtype Responder: HBRequestResponder /// Child Channel setup. This defaults to support HTTP1 - associatedtype ChildChannel: HBChildChannel & HTTPChannelHandler = HTTP1Channel + associatedtype ChildChannel: HBServerChildChannel & HTTPChannelHandler = HTTP1Channel /// Context passed with HBRequest to responder typealias Context = Responder.Context @@ -159,7 +159,7 @@ extension HBApplicationProtocol { /// try await app.runService() /// ``` /// Editing the application setup after calling `runService` will produce undefined behaviour. -public struct HBApplication: HBApplicationProtocol where Responder.Context: HBRequestContext { +public struct HBApplication: HBApplicationProtocol where Responder.Context: HBRequestContext { public typealias Context = Responder.Context public typealias ChildChannel = ChildChannel public typealias Responder = Responder diff --git a/Sources/Hummingbird/Middleware/Middleware.swift b/Sources/Hummingbird/Middleware/Middleware.swift index f545527b3..bf267ab70 100644 --- a/Sources/Hummingbird/Middleware/Middleware.swift +++ b/Sources/Hummingbird/Middleware/Middleware.swift @@ -55,7 +55,7 @@ public protocol MiddlewareProtocol: Sendable { /// Middleware protocol with HBRequest as input and HBResponse as output public protocol HBMiddlewareProtocol: MiddlewareProtocol where Input == HBRequest, Output == HBResponse {} -struct MiddlewareResponder: HBResponder { +struct MiddlewareResponder: HBRequestResponder { let middleware: any HBMiddlewareProtocol let next: @Sendable (HBRequest, Context) async throws -> HBResponse diff --git a/Sources/Hummingbird/Middleware/MiddlewareGroup.swift b/Sources/Hummingbird/Middleware/MiddlewareGroup.swift index 0115789b9..0bf2edf89 100644 --- a/Sources/Hummingbird/Middleware/MiddlewareGroup.swift +++ b/Sources/Hummingbird/Middleware/MiddlewareGroup.swift @@ -29,7 +29,7 @@ public final class HBMiddlewareGroup { /// Construct responder chain from this middleware group /// - Parameter finalResponder: The responder the last middleware calls /// - Returns: Responder chain - public func constructResponder(finalResponder: any HBResponder) -> any HBResponder { + public func constructResponder(finalResponder: any HBRequestResponder) -> any HBRequestResponder { var currentResponser = finalResponder for i in (0..: Sendable { self.methods = [:] } - public func getResponder(for method: HTTPRequest.Method) -> (any HBResponder)? { + public func getResponder(for method: HTTPRequest.Method) -> (any HBRequestResponder)? { return self.methods[method] } - mutating func addResponder(for method: HTTPRequest.Method, responder: any HBResponder) { + mutating func addResponder(for method: HTTPRequest.Method, responder: any HBRequestResponder) { guard self.methods[method] == nil else { preconditionFailure("\(method.rawValue) already has a handler") } @@ -42,6 +42,6 @@ struct HBEndpointResponders: Sendable { } } - var methods: [HTTPRequest.Method: any HBResponder] + var methods: [HTTPRequest.Method: any HBRequestResponder] var path: String } diff --git a/Sources/Hummingbird/Router/Router.swift b/Sources/Hummingbird/Router/Router.swift index fa0f68580..c0eeaec31 100644 --- a/Sources/Hummingbird/Router/Router.swift +++ b/Sources/Hummingbird/Router/Router.swift @@ -59,7 +59,7 @@ public final class HBRouter: HBRouterMethods, HBR /// - path: URI path /// - method: http method /// - responder: handler to call - public func add(_ path: String, method: HTTPRequest.Method, responder: any HBResponder) { + public func add(_ path: String, method: HTTPRequest.Method, responder: any HBRequestResponder) { // ensure path starts with a "/" and doesn't end with a "/" let path = "/\(path.dropSuffix("/").dropPrefix("/"))" self.trie.addEntry(.init(path), value: HBEndpointResponders(path: path)) { node in @@ -105,7 +105,7 @@ public final class HBRouter: HBRouterMethods, HBR } /// Responder that return a not found error -struct NotFoundResponder: HBResponder { +struct NotFoundResponder: HBRequestResponder { func respond(to request: HBRequest, context: Context) throws -> HBResponse { throw HBHTTPError(.notFound) } @@ -113,7 +113,7 @@ struct NotFoundResponder: HBResponder { /// A type that has a single method to build a responder public protocol HBResponderBuilder { - associatedtype Responder: HBResponder + associatedtype Responder: HBRequestResponder /// build a responder func buildResponder() -> Responder } diff --git a/Sources/Hummingbird/Router/RouterResponder.swift b/Sources/Hummingbird/Router/RouterResponder.swift index 30a2cc45a..4e6c35c6a 100644 --- a/Sources/Hummingbird/Router/RouterResponder.swift +++ b/Sources/Hummingbird/Router/RouterResponder.swift @@ -17,16 +17,16 @@ /// Conforms to `HBResponder` so need to provide its own implementation of /// `func respond(to request: HBRequest, context: Context) async throws -> HBResponse`. /// -public struct HBRouterResponder: HBResponder { +public struct HBRouterResponder: HBRequestResponder { let trie: RouterPathTrie> - let notFoundResponder: any HBResponder + let notFoundResponder: any HBRequestResponder let options: HBRouterOptions init( context: Context.Type, trie: RouterPathTrie>, options: HBRouterOptions, - notFoundResponder: any HBResponder + notFoundResponder: any HBRequestResponder ) { self.trie = trie self.options = options diff --git a/Sources/Hummingbird/Server/Responder.swift b/Sources/Hummingbird/Server/Responder.swift index fc32a7adb..297e21cd2 100644 --- a/Sources/Hummingbird/Server/Responder.swift +++ b/Sources/Hummingbird/Server/Responder.swift @@ -18,14 +18,14 @@ import ServiceContextModule /// Protocol for object that produces a response given a request /// /// This is the core protocol for Hummingbird. It defines an object that can respond to a request. -public protocol HBResponder: Sendable { +public protocol HBRequestResponder: Sendable { associatedtype Context - /// Return EventLoopFuture that will be fulfilled with response to the request supplied + /// Return response to the request supplied @Sendable func respond(to request: HBRequest, context: Context) async throws -> HBResponse } /// Responder that calls supplied closure -public struct HBCallbackResponder: HBResponder { +public struct HBCallbackResponder: HBRequestResponder { let callback: @Sendable (HBRequest, Context) async throws -> HBResponse public init(callback: @escaping @Sendable (HBRequest, Context) async throws -> HBResponse) { diff --git a/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift b/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift index 47805f884..24c5812c6 100644 --- a/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift +++ b/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift @@ -19,7 +19,7 @@ import NIOHTTPTypes import NIOHTTPTypesHTTP1 /// Child channel for processing HTTP1 -public struct HTTP1Channel: HBChildChannel, HTTPChannelHandler { +public struct HTTP1Channel: HBServerChildChannel, HTTPChannelHandler { public typealias Value = NIOAsyncChannel /// Initialize HTTP1Channel diff --git a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelBuilder.swift b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelBuilder.swift index fbdcef320..4c8b85633 100644 --- a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelBuilder.swift +++ b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelBuilder.swift @@ -18,7 +18,7 @@ import NIOCore /// /// Used when building an ``Hummingbird/HBApplication``. It delays the building /// of the ``HBChildChannel`` until the HTTP responder has been built. -public struct HBHTTPChannelBuilder: Sendable { +public struct HBHTTPChannelBuilder: Sendable { /// build child channel from HTTP responder public let build: @Sendable (@escaping HTTPChannelHandler.Responder) throws -> ChildChannel diff --git a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift index c2296ca91..11759b3a8 100644 --- a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift +++ b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift @@ -20,7 +20,7 @@ import NIOHTTPTypes import ServiceLifecycle /// Protocol for HTTP channels -public protocol HTTPChannelHandler: HBChildChannel { +public protocol HTTPChannelHandler: HBServerChildChannel { typealias Responder = @Sendable (HBRequest, Channel) async throws -> HBResponse var responder: Responder { get } } diff --git a/Sources/HummingbirdCore/Server/Server.swift b/Sources/HummingbirdCore/Server/Server.swift index e8828810c..00d5cf703 100644 --- a/Sources/HummingbirdCore/Server/Server.swift +++ b/Sources/HummingbirdCore/Server/Server.swift @@ -23,7 +23,7 @@ import NIOTransportServices import ServiceLifecycle /// HTTP server class -public actor HBServer: Service { +public actor HBServer: Service { public typealias AsyncChildChannel = ChildChannel.Value public typealias AsyncServerChannel = NIOAsyncChannel enum State: CustomStringConvertible { diff --git a/Sources/HummingbirdCore/Server/ChildChannel.swift b/Sources/HummingbirdCore/Server/ServerChildChannel.swift similarity index 95% rename from Sources/HummingbirdCore/Server/ChildChannel.swift rename to Sources/HummingbirdCore/Server/ServerChildChannel.swift index 4322bcb9f..21471f94e 100644 --- a/Sources/HummingbirdCore/Server/ChildChannel.swift +++ b/Sources/HummingbirdCore/Server/ServerChildChannel.swift @@ -16,7 +16,7 @@ import Logging import NIOCore /// HTTPServer child channel setup protocol -public protocol HBChildChannel: Sendable { +public protocol HBServerChildChannel: Sendable { associatedtype Value: Sendable /// Setup child channel diff --git a/Sources/HummingbirdRouter/RouterBuilder.swift b/Sources/HummingbirdRouter/RouterBuilder.swift index c8d55b37f..02b20dc6f 100644 --- a/Sources/HummingbirdRouter/RouterBuilder.swift +++ b/Sources/HummingbirdRouter/RouterBuilder.swift @@ -44,7 +44,7 @@ public struct HBRouterBuilder Output { try await self.handle(request, context: context) { _, _ in throw HBHTTPError(.notFound) diff --git a/Sources/HummingbirdTLS/TLSChannel.swift b/Sources/HummingbirdTLS/TLSChannel.swift index c56595054..cec4c252e 100644 --- a/Sources/HummingbirdTLS/TLSChannel.swift +++ b/Sources/HummingbirdTLS/TLSChannel.swift @@ -18,7 +18,7 @@ import NIOCore import NIOSSL /// Sets up child channel to use TLS before accessing base channel setup -public struct TLSChannel: HBChildChannel { +public struct TLSChannel: HBServerChildChannel { public typealias Value = BaseChannel.Value /// Initialize TLSChannel diff --git a/Sources/HummingbirdTLS/TLSChannelBuilder.swift b/Sources/HummingbirdTLS/TLSChannelBuilder.swift index 5be65a892..6567ec087 100644 --- a/Sources/HummingbirdTLS/TLSChannelBuilder.swift +++ b/Sources/HummingbirdTLS/TLSChannelBuilder.swift @@ -29,7 +29,7 @@ extension HBHTTPChannelBuilder { /// - base: Base child channel to wrap with TLS /// - tlsConfiguration: TLS configuration /// - Returns: HTTPChannelHandler builder - public static func tls( + public static func tls( _ base: HBHTTPChannelBuilder = .http1(), tlsConfiguration: TLSConfiguration ) throws -> HBHTTPChannelBuilder> { diff --git a/Sources/HummingbirdTesting/RouterTestFramework.swift b/Sources/HummingbirdTesting/RouterTestFramework.swift index 64add338b..50a6916d4 100644 --- a/Sources/HummingbirdTesting/RouterTestFramework.swift +++ b/Sources/HummingbirdTesting/RouterTestFramework.swift @@ -25,7 +25,7 @@ import NIOPosix import ServiceLifecycle /// Test sending requests directly to router. This does not setup a live server -struct HBRouterTestFramework: HBApplicationTestFramework where Responder.Context: HBBaseRequestContext { +struct HBRouterTestFramework: HBApplicationTestFramework where Responder.Context: HBBaseRequestContext { let responder: Responder let makeContext: @Sendable (Logger) -> Responder.Context let services: [any Service] diff --git a/Tests/HummingbirdCoreTests/ClientTests.swift b/Tests/HummingbirdCoreTests/ClientTests.swift index a37df5df3..09748581d 100644 --- a/Tests/HummingbirdCoreTests/ClientTests.swift +++ b/Tests/HummingbirdCoreTests/ClientTests.swift @@ -52,7 +52,7 @@ final class ClientTests: XCTestCase { } func testClient( - server: HBHTTPChannelBuilder, + server: HBHTTPChannelBuilder, clientTLSConfiguration: ClientTLSConfiguration = .none, eventLoopGroup: EventLoopGroup ) async throws { diff --git a/Tests/HummingbirdCoreTests/TestUtils.swift b/Tests/HummingbirdCoreTests/TestUtils.swift index 120643b14..7dac16e7c 100644 --- a/Tests/HummingbirdCoreTests/TestUtils.swift +++ b/Tests/HummingbirdCoreTests/TestUtils.swift @@ -31,7 +31,7 @@ public enum TestErrors: Error { } /// Helper function for testing a server -public func testServer( +public func testServer( responder: @escaping HTTPChannelHandler.Responder, httpChannelSetup: HBHTTPChannelBuilder, configuration: HBServerConfiguration, @@ -68,7 +68,7 @@ public func testServer( /// /// Creates test client, runs test function abd ensures everything is /// shutdown correctly -public func testServer( +public func testServer( responder: @escaping HTTPChannelHandler.Responder, httpChannelSetup: HBHTTPChannelBuilder, configuration: HBServerConfiguration, @@ -99,7 +99,7 @@ public func testServer( public func testServer( responder: @escaping HTTPChannelHandler.Responder, - httpChannelSetup: HBHTTPChannelBuilder = .http1(), + httpChannelSetup: HBHTTPChannelBuilder = .http1(), configuration: HBServerConfiguration, eventLoopGroup: EventLoopGroup, logger: Logger, diff --git a/Tests/HummingbirdTests/ApplicationTests.swift b/Tests/HummingbirdTests/ApplicationTests.swift index fd792529f..fb9c56ef9 100644 --- a/Tests/HummingbirdTests/ApplicationTests.swift +++ b/Tests/HummingbirdTests/ApplicationTests.swift @@ -495,7 +495,7 @@ final class ApplicationTests: XCTestCase { struct MyApp: HBApplicationProtocol { typealias Context = HBBasicRequestContext - var responder: some HBResponder { + var responder: some HBRequestResponder { let router = HBRouter(context: Context.self) router.get("/hello") { _, context -> ByteBuffer in return context.allocator.buffer(string: "GET: Hello") From 547804da3b300cde5e50eea78af01286f8552b7b Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 9 Mar 2024 07:37:38 +0000 Subject: [PATCH 02/11] MiddlewareProtocol -> RouterMiddleware --- Sources/Hummingbird/Files/FileMiddleware.swift | 2 +- Sources/Hummingbird/Middleware/CORSMiddleware.swift | 2 +- .../Middleware/LogRequestMiddleware.swift | 2 +- .../Hummingbird/Middleware/MetricsMiddleware.swift | 2 +- Sources/Hummingbird/Middleware/Middleware.swift | 7 ++----- Sources/Hummingbird/Middleware/MiddlewareGroup.swift | 6 +++--- .../Hummingbird/Middleware/TracingMiddleware.swift | 2 +- Sources/Hummingbird/Router/RouterGroup.swift | 2 +- Sources/HummingbirdRouter/Route.swift | 2 +- Sources/HummingbirdRouter/RouteGroup.swift | 2 +- Tests/HummingbirdRouterTests/MiddlewareTests.swift | 10 +++++----- Tests/HummingbirdRouterTests/RouterTests.swift | 12 ++++++------ Tests/HummingbirdTests/ApplicationTests.swift | 2 +- Tests/HummingbirdTests/MiddlewareTests.swift | 12 ++++++------ Tests/HummingbirdTests/RouterTests.swift | 10 +++++----- Tests/HummingbirdTests/TracingTests.swift | 2 +- 16 files changed, 37 insertions(+), 40 deletions(-) diff --git a/Sources/Hummingbird/Files/FileMiddleware.swift b/Sources/Hummingbird/Files/FileMiddleware.swift index 547759755..13548be8f 100644 --- a/Sources/Hummingbird/Files/FileMiddleware.swift +++ b/Sources/Hummingbird/Files/FileMiddleware.swift @@ -28,7 +28,7 @@ import NIOPosix /// "if-modified-since", "if-none-match", "if-range" and 'range" headers. It will output "content-length", /// "modified-date", "eTag", "content-type", "cache-control" and "content-range" headers where /// they are relevant. -public struct HBFileMiddleware: HBMiddlewareProtocol { +public struct HBFileMiddleware: HBRouterMiddleware { struct IsDirectoryError: Error {} let rootFolder: URL diff --git a/Sources/Hummingbird/Middleware/CORSMiddleware.swift b/Sources/Hummingbird/Middleware/CORSMiddleware.swift index 1cf4ecfc1..1d498530e 100644 --- a/Sources/Hummingbird/Middleware/CORSMiddleware.swift +++ b/Sources/Hummingbird/Middleware/CORSMiddleware.swift @@ -21,7 +21,7 @@ import NIOCore /// then return an empty body with all the standard CORS headers otherwise send /// request onto the next handler and when you receive the response add a /// "access-control-allow-origin" header -public struct HBCORSMiddleware: HBMiddlewareProtocol { +public struct HBCORSMiddleware: HBRouterMiddleware { /// Defines what origins are allowed public enum AllowOrigin: Sendable { case none diff --git a/Sources/Hummingbird/Middleware/LogRequestMiddleware.swift b/Sources/Hummingbird/Middleware/LogRequestMiddleware.swift index b18b2d9f7..afc00605d 100644 --- a/Sources/Hummingbird/Middleware/LogRequestMiddleware.swift +++ b/Sources/Hummingbird/Middleware/LogRequestMiddleware.swift @@ -15,7 +15,7 @@ import Logging /// Middleware outputting to log for every call to server -public struct HBLogRequestsMiddleware: HBMiddlewareProtocol { +public struct HBLogRequestsMiddleware: HBRouterMiddleware { let logLevel: Logger.Level let includeHeaders: Bool diff --git a/Sources/Hummingbird/Middleware/MetricsMiddleware.swift b/Sources/Hummingbird/Middleware/MetricsMiddleware.swift index 5df12fe7b..7785cd963 100644 --- a/Sources/Hummingbird/Middleware/MetricsMiddleware.swift +++ b/Sources/Hummingbird/Middleware/MetricsMiddleware.swift @@ -19,7 +19,7 @@ import Metrics /// /// Records the number of requests, the request duration and how many errors were thrown. Each metric has additional /// dimensions URI and method. -public struct HBMetricsMiddleware: HBMiddlewareProtocol { +public struct HBMetricsMiddleware: HBRouterMiddleware { public init() {} public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { diff --git a/Sources/Hummingbird/Middleware/Middleware.swift b/Sources/Hummingbird/Middleware/Middleware.swift index bf267ab70..a43d91c8f 100644 --- a/Sources/Hummingbird/Middleware/Middleware.swift +++ b/Sources/Hummingbird/Middleware/Middleware.swift @@ -14,9 +14,6 @@ import NIOCore -/// Middleware Handler with generic input, context and output types -public typealias Middleware = @Sendable (Input, Context, _ next: (Input, Context) async throws -> Output) async throws -> Output - /// Middleware protocol with generic input, context and output types public protocol MiddlewareProtocol: Sendable { associatedtype Input @@ -53,10 +50,10 @@ public protocol MiddlewareProtocol: Sendable { /// ``` /// Middleware protocol with HBRequest as input and HBResponse as output -public protocol HBMiddlewareProtocol: MiddlewareProtocol where Input == HBRequest, Output == HBResponse {} +public protocol HBRouterMiddleware: MiddlewareProtocol where Input == HBRequest, Output == HBResponse {} struct MiddlewareResponder: HBRequestResponder { - let middleware: any HBMiddlewareProtocol + let middleware: any HBRouterMiddleware let next: @Sendable (HBRequest, Context) async throws -> HBResponse func respond(to request: HBRequest, context: Context) async throws -> HBResponse { diff --git a/Sources/Hummingbird/Middleware/MiddlewareGroup.swift b/Sources/Hummingbird/Middleware/MiddlewareGroup.swift index 0bf2edf89..da6d761b8 100644 --- a/Sources/Hummingbird/Middleware/MiddlewareGroup.swift +++ b/Sources/Hummingbird/Middleware/MiddlewareGroup.swift @@ -14,15 +14,15 @@ /// Group of middleware that can be used to create a responder chain. Each middleware calls the next one public final class HBMiddlewareGroup { - var middlewares: [any HBMiddlewareProtocol] + var middlewares: [any HBRouterMiddleware] /// Initialize `HBMiddlewareGroup` - init(middlewares: [any HBMiddlewareProtocol] = []) { + init(middlewares: [any HBRouterMiddleware] = []) { self.middlewares = middlewares } /// Add middleware to group - public func add(_ middleware: any HBMiddlewareProtocol) { + public func add(_ middleware: any HBRouterMiddleware) { self.middlewares.append(middleware) } diff --git a/Sources/Hummingbird/Middleware/TracingMiddleware.swift b/Sources/Hummingbird/Middleware/TracingMiddleware.swift index 22458ba91..c8d366292 100644 --- a/Sources/Hummingbird/Middleware/TracingMiddleware.swift +++ b/Sources/Hummingbird/Middleware/TracingMiddleware.swift @@ -23,7 +23,7 @@ import Tracing /// You may opt in to recording a specific subset of HTTP request/response header values by passing /// a set of header names. @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) -public struct HBTracingMiddleware: HBMiddlewareProtocol { +public struct HBTracingMiddleware: HBRouterMiddleware { private let headerNamesToRecord: Set private let attributes: SpanAttributes? diff --git a/Sources/Hummingbird/Router/RouterGroup.swift b/Sources/Hummingbird/Router/RouterGroup.swift index 162c1c231..957c95548 100644 --- a/Sources/Hummingbird/Router/RouterGroup.swift +++ b/Sources/Hummingbird/Router/RouterGroup.swift @@ -42,7 +42,7 @@ public struct HBRouterGroup: HBRouterMethods { } /// Add middleware to RouterEndpoint - @discardableResult public func add(middleware: any HBMiddlewareProtocol) -> HBRouterGroup { + @discardableResult public func add(middleware: any HBRouterMiddleware) -> HBRouterGroup { self.middlewares.add(middleware) return self } diff --git a/Sources/HummingbirdRouter/Route.swift b/Sources/HummingbirdRouter/Route.swift index c56e751a0..7faef7e10 100644 --- a/Sources/HummingbirdRouter/Route.swift +++ b/Sources/HummingbirdRouter/Route.swift @@ -17,7 +17,7 @@ import Hummingbird import ServiceContextModule /// Route definition -public struct Route: HBMiddlewareProtocol where Handler.Context == Context { +public struct Route: HBRouterMiddleware where Handler.Context == Context { /// Full URI path to route public let fullPath: String /// Route path local to group route is defined in. diff --git a/Sources/HummingbirdRouter/RouteGroup.swift b/Sources/HummingbirdRouter/RouteGroup.swift index e9e169be4..774a53531 100644 --- a/Sources/HummingbirdRouter/RouteGroup.swift +++ b/Sources/HummingbirdRouter/RouteGroup.swift @@ -33,7 +33,7 @@ extension ServiceContext { } /// Router middleware that applies a middleware chain to URIs with a specified prefix -public struct RouteGroup: HBMiddlewareProtocol where Handler.Input == HBRequest, Handler.Output == HBResponse, Handler.Context == Context { +public struct RouteGroup: HBRouterMiddleware where Handler.Input == HBRequest, Handler.Output == HBResponse, Handler.Context == Context { public typealias Input = HBRequest public typealias Output = HBResponse diff --git a/Tests/HummingbirdRouterTests/MiddlewareTests.swift b/Tests/HummingbirdRouterTests/MiddlewareTests.swift index eb9e6610b..56d4e27d2 100644 --- a/Tests/HummingbirdRouterTests/MiddlewareTests.swift +++ b/Tests/HummingbirdRouterTests/MiddlewareTests.swift @@ -28,7 +28,7 @@ final class MiddlewareTests: XCTestCase { } func testMiddleware() async throws { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { var response = try await next(request, context) response.headers[.middleware] = "TestMiddleware" @@ -50,7 +50,7 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareOrder() async throws { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { let string: String func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { var response = try await next(request, context) @@ -76,7 +76,7 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareRunOnce() async throws { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { var response = try await next(request, context) XCTAssertNil(response.headers[.alreadyRun]) @@ -98,7 +98,7 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareRunWhenNoRouteFound() async throws { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { do { return try await next(request, context) @@ -130,7 +130,7 @@ final class MiddlewareTests: XCTestCase { try await self.parentWriter.write(output) } } - struct TransformMiddleware: HBMiddlewareProtocol { + struct TransformMiddleware: HBRouterMiddleware { func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { let response = try await next(request, context) var editedResponse = response diff --git a/Tests/HummingbirdRouterTests/RouterTests.swift b/Tests/HummingbirdRouterTests/RouterTests.swift index ba1e7a9da..08a24c3b2 100644 --- a/Tests/HummingbirdRouterTests/RouterTests.swift +++ b/Tests/HummingbirdRouterTests/RouterTests.swift @@ -20,7 +20,7 @@ import NIOCore import XCTest final class RouterTests: XCTestCase { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { let output: String init(_ output: String = "TestMiddleware") { @@ -36,7 +36,7 @@ final class RouterTests: XCTestCase { /// Test endpointPath is set func testEndpointPath() async throws { - struct TestEndpointMiddleware: HBMiddlewareProtocol { + struct TestEndpointMiddleware: HBRouterMiddleware { func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { _ = try await next(request, context) guard let endpointPath = context.endpointPath else { return try await next(request, context) } @@ -61,7 +61,7 @@ final class RouterTests: XCTestCase { /// Test endpointPath is prefixed with a "/" func testEndpointPathPrefix() async throws { - struct TestEndpointMiddleware: HBMiddlewareProtocol { + struct TestEndpointMiddleware: HBRouterMiddleware { func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { _ = try await next(request, context) guard let endpointPath = context.endpointPath else { return try await next(request, context) } @@ -98,7 +98,7 @@ final class RouterTests: XCTestCase { /// Test endpointPath doesn't have "/" at end func testEndpointPathSuffix() async throws { - struct TestEndpointMiddleware: HBMiddlewareProtocol { + struct TestEndpointMiddleware: HBRouterMiddleware { func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { guard let endpointPath = context.endpointPath else { return try await next(request, context) } return .init(status: .ok, body: .init(byteBuffer: ByteBuffer(string: endpointPath))) @@ -233,7 +233,7 @@ final class RouterTests: XCTestCase { /// Test adding middleware to group doesn't affect middleware in parent groups func testGroupGroupMiddleware2() async throws { - struct TestGroupMiddleware: HBMiddlewareProtocol { + struct TestGroupMiddleware: HBRouterMiddleware { typealias Context = HBTestRouterContext2 let output: String @@ -271,7 +271,7 @@ final class RouterTests: XCTestCase { /// Test adding middleware to group doesn't affect middleware in parent groups func testRouteBuilder() async throws { - struct TestGroupMiddleware: HBMiddlewareProtocol { + struct TestGroupMiddleware: HBRouterMiddleware { typealias Context = HBTestRouterContext2 let output: String diff --git a/Tests/HummingbirdTests/ApplicationTests.swift b/Tests/HummingbirdTests/ApplicationTests.swift index fb9c56ef9..922700554 100644 --- a/Tests/HummingbirdTests/ApplicationTests.swift +++ b/Tests/HummingbirdTests/ApplicationTests.swift @@ -258,7 +258,7 @@ final class ApplicationTests: XCTestCase { } func testCollateBody() async throws { - struct CollateMiddleware: HBMiddlewareProtocol { + struct CollateMiddleware: HBRouterMiddleware { public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { var request = request _ = try await request.collateBody(context: context) diff --git a/Tests/HummingbirdTests/MiddlewareTests.swift b/Tests/HummingbirdTests/MiddlewareTests.swift index 70c8bedec..46af27d6c 100644 --- a/Tests/HummingbirdTests/MiddlewareTests.swift +++ b/Tests/HummingbirdTests/MiddlewareTests.swift @@ -24,7 +24,7 @@ final class MiddlewareTests: XCTestCase { } func testMiddleware() async throws { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { var response = try await next(request, context) response.headers[.test] = "TestMiddleware" @@ -45,7 +45,7 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareOrder() async throws { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { let string: String public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { var response = try await next(request, context) @@ -70,7 +70,7 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareRunOnce() async throws { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { var response = try await next(request, context) XCTAssertNil(response.headers[.test]) @@ -91,7 +91,7 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareRunWhenNoRouteFound() async throws { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { do { return try await next(request, context) @@ -113,7 +113,7 @@ final class MiddlewareTests: XCTestCase { } func testEndpointPathInGroup() async throws { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { XCTAssertNotNil(context.endpointPath) return try await next(request, context) @@ -142,7 +142,7 @@ final class MiddlewareTests: XCTestCase { try await self.parentWriter.write(output) } } - struct TransformMiddleware: HBMiddlewareProtocol { + struct TransformMiddleware: HBRouterMiddleware { public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { let response = try await next(request, context) var editedResponse = response diff --git a/Tests/HummingbirdTests/RouterTests.swift b/Tests/HummingbirdTests/RouterTests.swift index 3b1e0b07b..0e533736f 100644 --- a/Tests/HummingbirdTests/RouterTests.swift +++ b/Tests/HummingbirdTests/RouterTests.swift @@ -21,7 +21,7 @@ import Tracing import XCTest final class RouterTests: XCTestCase { - struct TestMiddleware: HBMiddlewareProtocol { + struct TestMiddleware: HBRouterMiddleware { let output: String init(_ output: String = "TestMiddleware") { @@ -37,7 +37,7 @@ final class RouterTests: XCTestCase { /// Test endpointPath is set func testEndpointPath() async throws { - struct TestEndpointMiddleware: HBMiddlewareProtocol { + struct TestEndpointMiddleware: HBRouterMiddleware { public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { guard let endpointPath = context.endpointPath else { return try await next(request, context) } return .init(status: .ok, body: .init(byteBuffer: ByteBuffer(string: endpointPath))) @@ -58,7 +58,7 @@ final class RouterTests: XCTestCase { /// Test endpointPath is prefixed with a "/" func testEndpointPathPrefix() async throws { - struct TestEndpointMiddleware: HBMiddlewareProtocol { + struct TestEndpointMiddleware: HBRouterMiddleware { public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { guard let endpointPath = context.endpointPath else { return try await next(request, context) } return .init(status: .ok, body: .init(byteBuffer: ByteBuffer(string: endpointPath))) @@ -93,7 +93,7 @@ final class RouterTests: XCTestCase { /// Test endpointPath doesn't have "/" at end func testEndpointPathSuffix() async throws { - struct TestEndpointMiddleware: HBMiddlewareProtocol { + struct TestEndpointMiddleware: HBRouterMiddleware { public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { guard let endpointPath = context.endpointPath else { return try await next(request, context) } return .init(status: .ok, body: .init(byteBuffer: ByteBuffer(string: endpointPath))) @@ -222,7 +222,7 @@ final class RouterTests: XCTestCase { /// Test adding middleware to group doesn't affect middleware in parent groups func testGroupGroupMiddleware2() async throws { - struct TestGroupMiddleware: HBMiddlewareProtocol { + struct TestGroupMiddleware: HBRouterMiddleware { let output: String public func handle(_ request: HBRequest, context: HBTestRouterContext2, next: (HBRequest, HBTestRouterContext2) async throws -> HBResponse) async throws -> HBResponse { diff --git a/Tests/HummingbirdTests/TracingTests.swift b/Tests/HummingbirdTests/TracingTests.swift index 33ea5d679..8b766e72d 100644 --- a/Tests/HummingbirdTests/TracingTests.swift +++ b/Tests/HummingbirdTests/TracingTests.swift @@ -342,7 +342,7 @@ final class TracingTests: XCTestCase { let expectation = expectation(description: "Expected span to be ended.") expectation.expectedFulfillmentCount = 2 - struct SpanMiddleware: HBMiddlewareProtocol { + struct SpanMiddleware: HBRouterMiddleware { public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { var serviceContext = ServiceContext.current ?? ServiceContext.topLevel serviceContext.testID = "testMiddleware" From 7c25718ada4ad7df46dbe43f787a8ed54dc15469 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 9 Mar 2024 07:38:57 +0000 Subject: [PATCH 03/11] Replace HB logger labels --- Tests/HummingbirdCoreTests/CoreTests.swift | 32 ++++++++++----------- Tests/HummingbirdCoreTests/HTTP2Tests.swift | 2 +- Tests/HummingbirdCoreTests/TLSTests.swift | 2 +- Tests/HummingbirdCoreTests/TSTests.swift | 4 +-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Tests/HummingbirdCoreTests/CoreTests.swift b/Tests/HummingbirdCoreTests/CoreTests.swift index a750b80f0..54d3bfb32 100644 --- a/Tests/HummingbirdCoreTests/CoreTests.swift +++ b/Tests/HummingbirdCoreTests/CoreTests.swift @@ -45,7 +45,7 @@ class HummingBirdCoreTests: XCTestCase { httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let response = try await client.get("/") var body = try XCTUnwrap(response.body) @@ -58,7 +58,7 @@ class HummingBirdCoreTests: XCTestCase { responder: helloResponder, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in for _ in 0..<10 { let response = try await client.post("/", body: ByteBuffer(string: "Hello")) @@ -74,7 +74,7 @@ class HummingBirdCoreTests: XCTestCase { httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let response = try await client.get("/") XCTAssertEqual(response.status, .unauthorized) @@ -90,7 +90,7 @@ class HummingBirdCoreTests: XCTestCase { }, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let buffer = self.randomBuffer(size: 1_140_000) let response = try await client.post("/", body: buffer) @@ -107,7 +107,7 @@ class HummingBirdCoreTests: XCTestCase { }, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let response = try await client.get("/") let body = try XCTUnwrap(response.body) @@ -122,7 +122,7 @@ class HummingBirdCoreTests: XCTestCase { }, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let buffer = self.randomBuffer(size: 1_140_000) let response = try await client.post("/", body: buffer) @@ -138,7 +138,7 @@ class HummingBirdCoreTests: XCTestCase { }, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let buffer = self.randomBuffer(size: 1_140_000) let response = try await client.post("/", body: buffer) @@ -167,7 +167,7 @@ class HummingBirdCoreTests: XCTestCase { httpChannelSetup: .http1(additionalChannelHandlers: [SlowInputChannelHandler()]), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let buffer = self.randomBuffer(size: 1_140_000) let response = try await client.post("/", body: buffer) @@ -182,7 +182,7 @@ class HummingBirdCoreTests: XCTestCase { httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let response = try await client.get("/") XCTAssertEqual(response.trailerHeaders?[.contentType], "text") @@ -209,7 +209,7 @@ class HummingBirdCoreTests: XCTestCase { httpChannelSetup: .http1(additionalChannelHandlers: [CreateErrorHandler()]), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let buffer = self.randomBuffer(size: 32) let response = try await client.post("/", body: buffer) @@ -225,7 +225,7 @@ class HummingBirdCoreTests: XCTestCase { }, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let buffer = self.randomBuffer(size: 16384) let response = try await client.post("/", body: buffer) @@ -241,7 +241,7 @@ class HummingBirdCoreTests: XCTestCase { responder: helloResponder, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in try await withTimeout(.seconds(5)) { _ = try await client.get("/", headers: [.connection: "close"]) @@ -275,7 +275,7 @@ class HummingBirdCoreTests: XCTestCase { httpChannelSetup: .http1(additionalChannelHandlers: [HTTPServerIncompleteRequest(), IdleStateHandler(readTimeout: .seconds(1))]), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in try await withTimeout(.seconds(5)) { do { @@ -298,7 +298,7 @@ class HummingBirdCoreTests: XCTestCase { httpChannelSetup: .http1(additionalChannelHandlers: [IdleStateHandler(writeTimeout: .seconds(1))]), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in try await withTimeout(.seconds(5)) { _ = try await client.get("/", headers: [.connection: "keep-alive"]) @@ -320,7 +320,7 @@ class HummingBirdCoreTests: XCTestCase { httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { server, client in try await withTimeout(.seconds(5)) { try await withThrowingTaskGroup(of: Void.self) { group in @@ -349,7 +349,7 @@ class HummingBirdCoreTests: XCTestCase { httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { server, client in try await withTimeout(.seconds(5)) { let response = try await client.get("/") diff --git a/Tests/HummingbirdCoreTests/HTTP2Tests.swift b/Tests/HummingbirdCoreTests/HTTP2Tests.swift index 5cc6bbeb5..6b249d24c 100644 --- a/Tests/HummingbirdCoreTests/HTTP2Tests.swift +++ b/Tests/HummingbirdCoreTests/HTTP2Tests.swift @@ -35,7 +35,7 @@ class HummingBirdHTTP2Tests: XCTestCase { httpChannelSetup: .http2Upgrade(tlsConfiguration: getServerTLSConfiguration()), configuration: .init(address: .hostname(port: 0), serverName: testServerName), eventLoopGroup: eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { _, port in var tlsConfiguration = try getClientTLSConfiguration() // no way to override the SSL server name with AsyncHTTPClient so need to set diff --git a/Tests/HummingbirdCoreTests/TLSTests.swift b/Tests/HummingbirdCoreTests/TLSTests.swift index b5e269bb2..74bab8466 100644 --- a/Tests/HummingbirdCoreTests/TLSTests.swift +++ b/Tests/HummingbirdCoreTests/TLSTests.swift @@ -31,7 +31,7 @@ class HummingBirdTLSTests: XCTestCase { httpChannelSetup: .tls(tlsConfiguration: getServerTLSConfiguration()), configuration: .init(address: .hostname(port: 0), serverName: testServerName), eventLoopGroup: eventLoopGroup, - logger: Logger(label: "HB"), + logger: Logger(label: "Hummingbird"), clientConfiguration: .init(tlsConfiguration: getClientTLSConfiguration(), serverName: testServerName) ) { client in let response = try await client.get("/") diff --git a/Tests/HummingbirdCoreTests/TSTests.swift b/Tests/HummingbirdCoreTests/TSTests.swift index 9a7fe90b4..a79c8c278 100644 --- a/Tests/HummingbirdCoreTests/TSTests.swift +++ b/Tests/HummingbirdCoreTests/TSTests.swift @@ -37,7 +37,7 @@ class TransportServicesTests: XCTestCase { responder: helloResponder, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: eventLoopGroup, - logger: Logger(label: "HB") + logger: Logger(label: "Hummingbird") ) { client in let response = try await client.get("/") var body = try XCTUnwrap(response.body) @@ -55,7 +55,7 @@ class TransportServicesTests: XCTestCase { responder: helloResponder, configuration: .init(address: .hostname(port: 0), serverName: testServerName, tlsOptions: tlsOptions), eventLoopGroup: eventLoopGroup, - logger: Logger(label: "HB"), + logger: Logger(label: "Hummingbird"), clientConfiguration: .init(tlsConfiguration: self.getClientTLSConfiguration(), serverName: testServerName) ) { client in let response = try await client.get("/") From d12fa1ee970fa94b99a8c10951c7997b00de8caf Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 9 Mar 2024 07:59:16 +0000 Subject: [PATCH 04/11] Rename URL -> URI --- Sources/HummingbirdCore/Request/Request.swift | 2 +- Sources/HummingbirdCore/Request/{URL.swift => URI.swift} | 4 ++-- Tests/HummingbirdTests/HTTPTests.swift | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename Sources/HummingbirdCore/Request/{URL.swift => URI.swift} (98%) diff --git a/Sources/HummingbirdCore/Request/Request.swift b/Sources/HummingbirdCore/Request/Request.swift index 5eb94927b..95ffc3bc2 100644 --- a/Sources/HummingbirdCore/Request/Request.swift +++ b/Sources/HummingbirdCore/Request/Request.swift @@ -19,7 +19,7 @@ public struct HBRequest: Sendable { // MARK: Member variables /// URI path - public let uri: HBURL + public let uri: HBURI /// HTTP head public let head: HTTPRequest /// Body of HTTP request diff --git a/Sources/HummingbirdCore/Request/URL.swift b/Sources/HummingbirdCore/Request/URI.swift similarity index 98% rename from Sources/HummingbirdCore/Request/URL.swift rename to Sources/HummingbirdCore/Request/URI.swift index 1f0e83da9..4d7fbc546 100644 --- a/Sources/HummingbirdCore/Request/URL.swift +++ b/Sources/HummingbirdCore/Request/URI.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// /// Simple URL parser -public struct HBURL: Sendable, CustomStringConvertible, ExpressibleByStringLiteral { +public struct HBURI: Sendable, CustomStringConvertible, ExpressibleByStringLiteral { public struct Scheme: RawRepresentable, Equatable { public let rawValue: String @@ -74,7 +74,7 @@ public struct HBURL: Sendable, CustomStringConvertible, ExpressibleByStringLiter public var description: String { self.string } - /// Initialize `HBURL` from `String` + /// Initialize `HBURI` from `String` /// - Parameter string: input string public init(_ string: String) { enum ParsingState { diff --git a/Tests/HummingbirdTests/HTTPTests.swift b/Tests/HummingbirdTests/HTTPTests.swift index b57c0599d..f563003de 100644 --- a/Tests/HummingbirdTests/HTTPTests.swift +++ b/Tests/HummingbirdTests/HTTPTests.swift @@ -17,7 +17,7 @@ import HummingbirdCore import XCTest class HTTPTests: XCTestCase { - func testURI(_ uri: HBURL, _ component: KeyPath, _ value: T) { + func testURI(_ uri: HBURI, _ component: KeyPath, _ value: T) { XCTAssertEqual(uri[keyPath: component], value) } @@ -62,7 +62,7 @@ class HTTPTests: XCTestCase { let urlString = "https://hummingbird.co.uk/test/url?test1=hello%20rg&test2=true" let date = Date() for _ in 0..<10000 { - _ = HBURL(urlString).queryParameters + _ = HBURI(urlString).queryParameters } print("\(-date.timeIntervalSinceNow)") } From 3d6bb9a0ada789408768ec4dbef09e5f2b658f7e Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 9 Mar 2024 08:06:23 +0000 Subject: [PATCH 05/11] Client -> ClientConnection --- Sources/HummingbirdCore/Client/ClientChannel.swift | 4 ++-- .../Client/{Client.swift => ClientConnection.swift} | 5 ++++- Sources/HummingbirdTLS/TLSClientChannel.swift | 2 +- Tests/HummingbirdCoreTests/ClientTests.swift | 8 ++++---- 4 files changed, 11 insertions(+), 8 deletions(-) rename Sources/HummingbirdCore/Client/{Client.swift => ClientConnection.swift} (95%) diff --git a/Sources/HummingbirdCore/Client/ClientChannel.swift b/Sources/HummingbirdCore/Client/ClientChannel.swift index 78b0f3385..b204aa70c 100644 --- a/Sources/HummingbirdCore/Client/ClientChannel.swift +++ b/Sources/HummingbirdCore/Client/ClientChannel.swift @@ -15,8 +15,8 @@ import Logging import NIOCore -/// HBClient child channel setup protocol -public protocol HBClientChannel: Sendable { +/// HBClientConnection child channel setup protocol +public protocol HBClientConnectionChannel: Sendable { associatedtype Value: Sendable /// Setup child channel diff --git a/Sources/HummingbirdCore/Client/Client.swift b/Sources/HummingbirdCore/Client/ClientConnection.swift similarity index 95% rename from Sources/HummingbirdCore/Client/Client.swift rename to Sources/HummingbirdCore/Client/ClientConnection.swift index f543870b2..0bff504ee 100644 --- a/Sources/HummingbirdCore/Client/Client.swift +++ b/Sources/HummingbirdCore/Client/ClientConnection.swift @@ -21,7 +21,10 @@ import Network import NIOTransportServices #endif -public struct HBClient: Sendable { +/// A generic client connection to a server. +/// +/// Actual client protocol is implemented in `ClientChannel` generic parameter +public struct HBClientConnection: Sendable { typealias ChannelResult = ClientChannel.Value /// Logger used by Server let logger: Logger diff --git a/Sources/HummingbirdTLS/TLSClientChannel.swift b/Sources/HummingbirdTLS/TLSClientChannel.swift index 0928b2349..52923c276 100644 --- a/Sources/HummingbirdTLS/TLSClientChannel.swift +++ b/Sources/HummingbirdTLS/TLSClientChannel.swift @@ -18,7 +18,7 @@ import NIOCore import NIOSSL /// Sets up client channel to use TLS before accessing base channel setup -public struct TLSClientChannel: HBClientChannel { +public struct TLSClientChannel: HBClientConnectionChannel { public typealias Value = BaseChannel.Value /// Initialize TLSChannel diff --git a/Tests/HummingbirdCoreTests/ClientTests.swift b/Tests/HummingbirdCoreTests/ClientTests.swift index 09748581d..eedc5b273 100644 --- a/Tests/HummingbirdCoreTests/ClientTests.swift +++ b/Tests/HummingbirdCoreTests/ClientTests.swift @@ -87,7 +87,7 @@ final class ClientTests: XCTestCase { } switch clientTLSConfiguration { case .niossl(let tlsConfiguration): - let client = try HBClient( + let client = try HBClientConnection( TLSClientChannel(clientChannel, tlsConfiguration: tlsConfiguration, serverHostname: testServerName), address: .hostname("127.0.0.1", port: port), eventLoopGroup: eventLoopGroup, @@ -97,7 +97,7 @@ final class ClientTests: XCTestCase { #if canImport(Network) case .ts(let options): - let client = try HBClient( + let client = try HBClientConnection( clientChannel, address: .hostname("127.0.0.1", port: port), transportServicesTLSOptions: options, @@ -107,7 +107,7 @@ final class ClientTests: XCTestCase { try await client.run() #endif case .none: - let client = HBClient( + let client = HBClientConnection( clientChannel, address: .hostname("127.0.0.1", port: port), eventLoopGroup: eventLoopGroup, @@ -168,7 +168,7 @@ final class ClientTests: XCTestCase { #endif } -struct HTTP1ClientChannel: HBClientChannel { +struct HTTP1ClientChannel: HBClientConnectionChannel { let handler: @Sendable (NIOAsyncChannelInboundStream, NIOAsyncChannelOutboundWriter) async throws -> Void /// Setup child channel for HTTP1 From 3ba5daa93d0a45fd7755774a9f8893d57e7a948a Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 9 Mar 2024 08:13:57 +0000 Subject: [PATCH 06/11] ResponderBuilder -> RequestResponderBuilder --- Sources/Hummingbird/Application.swift | 2 +- Sources/Hummingbird/Router/Router.swift | 4 ++-- .../Server/{Responder.swift => RequestResponder.swift} | 0 Sources/HummingbirdRouter/RouterBuilder.swift | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename Sources/Hummingbird/Server/{Responder.swift => RequestResponder.swift} (100%) diff --git a/Sources/Hummingbird/Application.swift b/Sources/Hummingbird/Application.swift index 86b9a1861..04f96df12 100644 --- a/Sources/Hummingbird/Application.swift +++ b/Sources/Hummingbird/Application.swift @@ -228,7 +228,7 @@ public struct HBApplication( + public init( router: ResponderBuilder, server: HBHTTPChannelBuilder = .http1(), configuration: HBApplicationConfiguration = HBApplicationConfiguration(), diff --git a/Sources/Hummingbird/Router/Router.swift b/Sources/Hummingbird/Router/Router.swift index c0eeaec31..a3c2126e6 100644 --- a/Sources/Hummingbird/Router/Router.swift +++ b/Sources/Hummingbird/Router/Router.swift @@ -43,7 +43,7 @@ import NIOCore /// Both of these match routes which start with "/user" and the next path segment being anything. /// The second version extracts the path segment out and adds it to `HBRequest.parameters` with the /// key "id". -public final class HBRouter: HBRouterMethods, HBResponderBuilder { +public final class HBRouter: HBRouterMethods, HBRequestResponderBuilder { var trie: RouterPathTrieBuilder> public let middlewares: HBMiddlewareGroup let options: HBRouterOptions @@ -112,7 +112,7 @@ struct NotFoundResponder: HBRequestResponder { } /// A type that has a single method to build a responder -public protocol HBResponderBuilder { +public protocol HBRequestResponderBuilder { associatedtype Responder: HBRequestResponder /// build a responder func buildResponder() -> Responder diff --git a/Sources/Hummingbird/Server/Responder.swift b/Sources/Hummingbird/Server/RequestResponder.swift similarity index 100% rename from Sources/Hummingbird/Server/Responder.swift rename to Sources/Hummingbird/Server/RequestResponder.swift diff --git a/Sources/HummingbirdRouter/RouterBuilder.swift b/Sources/HummingbirdRouter/RouterBuilder.swift index 02b20dc6f..f2b5ad91b 100644 --- a/Sources/HummingbirdRouter/RouterBuilder.swift +++ b/Sources/HummingbirdRouter/RouterBuilder.swift @@ -44,7 +44,7 @@ public struct HBRouterBuilder Output { try await self.handle(request, context: context) { _, _ in throw HBHTTPError(.notFound) From 94251a6d3933c60ae3cdc8c4880f1c1b11a9c0b5 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 9 Mar 2024 08:19:24 +0000 Subject: [PATCH 07/11] Remove HB prefix --- .../HTTP1/HTTP1ChannelBenchmarks.swift | 2 +- .../Benchmarks/Router/RouterBenchmarks.swift | 30 +-- README.md | 4 +- Sources/Hummingbird/Application.swift | 58 +++--- .../Codable/CodableProtocols.swift | 8 +- .../Hummingbird/Codable/JSON/JSONCoding.swift | 16 +- .../Codable/ResponseEncodable.swift | 30 +-- .../URLEncodedForm+Request.swift | 14 +- Sources/Hummingbird/Configuration.swift | 18 +- Sources/Hummingbird/Environment.swift | 14 +- Sources/Hummingbird/Exports.swift | 16 +- Sources/Hummingbird/Files/CacheControl.swift | 8 +- Sources/Hummingbird/Files/FileIO.swift | 18 +- .../Hummingbird/Files/FileMiddleware.swift | 40 ++-- Sources/Hummingbird/HTTP/Cookie.swift | 12 +- Sources/Hummingbird/HTTP/Cookies.swift | 14 +- Sources/Hummingbird/HTTP/MediaType.swift | 20 +- .../Hummingbird/HTTP/Request+Cookies.swift | 8 +- .../Hummingbird/HTTP/Response+Cookies.swift | 8 +- .../Middleware/CORSMiddleware.swift | 8 +- .../Middleware/LogRequestMiddleware.swift | 8 +- .../Middleware/MetricsMiddleware.swift | 22 +-- .../Hummingbird/Middleware/Middleware.swift | 20 +- .../Middleware/MiddlewareGroup.swift | 12 +- .../Middleware/TracingMiddleware.swift | 14 +- .../Router/EndpointResponder.swift | 10 +- .../Hummingbird/Router/Parameters+UUID.swift | 10 +- Sources/Hummingbird/Router/Parameters.swift | 18 +- .../Router/ResponseGenerator.swift | 46 ++--- Sources/Hummingbird/Router/RouteHandler.swift | 42 ++--- Sources/Hummingbird/Router/Router.swift | 48 ++--- Sources/Hummingbird/Router/RouterGroup.swift | 18 +- .../Hummingbird/Router/RouterMethods.swift | 44 ++--- .../Hummingbird/Router/RouterResponder.swift | 20 +- Sources/Hummingbird/Router/TrieRouter.swift | 10 +- Sources/Hummingbird/Server/Request.swift | 18 +- .../Hummingbird/Server/RequestContext.swift | 32 ++-- .../Hummingbird/Server/RequestResponder.swift | 12 +- Sources/Hummingbird/Server/Response.swift | 6 +- .../Storage/MemoryPersistDriver.swift | 4 +- .../Hummingbird/Storage/PersistDriver.swift | 8 +- .../Hummingbird/Storage/PersistError.swift | 2 +- .../Hummingbird/Utils/DateCache+Date.swift | 2 +- Sources/Hummingbird/Utils/DateCache.swift | 2 +- .../Client/ClientChannel.swift | 4 +- .../Client/ClientConnection.swift | 10 +- Sources/HummingbirdCore/Error/HTTPError.swift | 4 +- .../Error/HTTPErrorResponse.swift | 10 +- Sources/HummingbirdCore/Request/Request.swift | 12 +- .../HummingbirdCore/Request/RequestBody.swift | 18 +- Sources/HummingbirdCore/Request/URI.swift | 28 +-- .../HummingbirdCore/Response/Response.swift | 8 +- .../Response/ResponseBody.swift | 24 +-- Sources/HummingbirdCore/Server/Address.swift | 2 +- .../Server/HTTP/HTTP1Channel.swift | 8 +- .../Server/HTTP/HTTPChannelBuilder.swift | 16 +- .../Server/HTTP/HTTPChannelHandler.swift | 20 +- .../Server/HTTPUserEventHandler.swift | 2 +- Sources/HummingbirdCore/Server/Server.swift | 14 +- .../Server/ServerChildChannel.swift | 2 +- .../Server/ServerConfiguration.swift | 8 +- Sources/HummingbirdCore/Utils/HBParser.swift | 48 ++--- Sources/HummingbirdHTTP2/HTTP2Channel.swift | 8 +- .../HTTP2ChannelBuilder.swift | 8 +- Sources/HummingbirdJobs/Job.swift | 8 +- Sources/HummingbirdJobs/JobContext.swift | 2 +- Sources/HummingbirdJobs/JobDefinition.swift | 10 +- Sources/HummingbirdJobs/JobIdentifier.swift | 8 +- Sources/HummingbirdJobs/JobQueue.swift | 36 ++-- Sources/HummingbirdJobs/JobQueueDriver.swift | 4 +- Sources/HummingbirdJobs/JobQueueHandler.swift | 18 +- Sources/HummingbirdJobs/JobRegistry.swift | 40 ++-- Sources/HummingbirdJobs/MemoryJobQueue.swift | 20 +- Sources/HummingbirdJobs/QueuedJob.swift | 2 +- .../MiddlewareModule/MiddlewareStack.swift | 2 +- Sources/HummingbirdRouter/Route.swift | 56 +++--- Sources/HummingbirdRouter/RouteBuilder.swift | 22 +-- Sources/HummingbirdRouter/RouteGroup.swift | 8 +- Sources/HummingbirdRouter/RouteHandler.swift | 16 +- Sources/HummingbirdRouter/RouterBuilder.swift | 14 +- .../RouterBuilderContext.swift | 18 +- Sources/HummingbirdRouter/RouterPath.swift | 8 +- Sources/HummingbirdTLS/TLSChannel.swift | 4 +- .../HummingbirdTLS/TLSChannelBuilder.swift | 12 +- Sources/HummingbirdTLS/TLSClientChannel.swift | 2 +- .../HummingbirdTesting/Application+Test.swift | 34 ++-- .../ApplicationTester.swift | 18 +- .../AsyncHTTPClientTestFramework.swift | 12 +- .../LiveTestFramework.swift | 14 +- .../RouterTestFramework.swift | 36 ++-- .../HummingbirdTesting/TestApplication.swift | 8 +- .../HummingbirdTesting/TestClient+types.swift | 2 +- Sources/HummingbirdTesting/TestClient.swift | 60 +++--- Sources/PerformanceTest/main.swift | 10 +- Tests/HummingbirdCoreTests/ClientTests.swift | 16 +- Tests/HummingbirdCoreTests/CoreTests.swift | 24 +-- Tests/HummingbirdCoreTests/TestUtils.swift | 36 ++-- .../HummingbirdJobsTests.swift | 38 ++-- .../MiddlewareTests.swift | 50 ++--- .../HummingbirdRouterTests/RouterTests.swift | 102 +++++----- Tests/HummingbirdTests/ApplicationTests.swift | 178 +++++++++--------- Tests/HummingbirdTests/CookiesTests.swift | 38 ++-- Tests/HummingbirdTests/DateCacheTests.swift | 6 +- Tests/HummingbirdTests/EnvironmentTests.swift | 34 ++-- Tests/HummingbirdTests/FileIOTests.swift | 20 +- .../FileMiddlewareTests.swift | 62 +++--- Tests/HummingbirdTests/HTTPTests.swift | 60 +++--- Tests/HummingbirdTests/HandlerTests.swift | 40 ++-- .../HummingBirdJSONTests.swift | 16 +- Tests/HummingbirdTests/MetricsTests.swift | 50 ++--- Tests/HummingbirdTests/MiddlewareTests.swift | 84 ++++----- Tests/HummingbirdTests/ParserTests.swift | 28 +-- Tests/HummingbirdTests/PersistTests.swift | 40 ++-- Tests/HummingbirdTests/RouterTests.swift | 112 +++++------ Tests/HummingbirdTests/TracingTests.swift | 74 ++++---- Tests/HummingbirdTests/TrieRouterTests.swift | 2 +- .../Application+URLEncodedFormTests.swift | 16 +- Tests/HummingbirdTests/UUIDTests.swift | 16 +- scripts/generate-certs.sh | 2 +- 119 files changed, 1338 insertions(+), 1338 deletions(-) diff --git a/Benchmarks/Benchmarks/HTTP1/HTTP1ChannelBenchmarks.swift b/Benchmarks/Benchmarks/HTTP1/HTTP1ChannelBenchmarks.swift index ac4996d62..0871d71b3 100644 --- a/Benchmarks/Benchmarks/HTTP1/HTTP1ChannelBenchmarks.swift +++ b/Benchmarks/Benchmarks/HTTP1/HTTP1ChannelBenchmarks.swift @@ -27,7 +27,7 @@ extension Benchmark { name: String, configuration: Benchmark.Configuration = Benchmark.defaultConfiguration, write: @escaping @Sendable (Benchmark, NIOAsyncTestingChannel) async throws -> Void, - responder: @escaping @Sendable (HBRequest, Channel) async throws -> HBResponse + responder: @escaping @Sendable (Request, Channel) async throws -> Response ) { let http1 = HTTP1Channel(responder: responder) let channel = NIOAsyncTestingChannel() diff --git a/Benchmarks/Benchmarks/Router/RouterBenchmarks.swift b/Benchmarks/Benchmarks/Router/RouterBenchmarks.swift index 92910f8f2..a75c7306c 100644 --- a/Benchmarks/Benchmarks/Router/RouterBenchmarks.swift +++ b/Benchmarks/Benchmarks/Router/RouterBenchmarks.swift @@ -16,14 +16,14 @@ import Benchmark import HTTPTypes import Hummingbird import NIOHTTPTypes -@_spi(HBInternal) import HummingbirdCore +@_spi(Internal) import HummingbirdCore import Logging import NIOCore import NIOPosix /// Implementation of a basic request context that supports everything the Hummingbird library needs -struct BasicBenchmarkContext: HBRequestContext { - var coreContext: HBCoreRequestContext +struct BasicBenchmarkContext: RequestContext { + var coreContext: CoreRequestContext public init(channel: Channel, logger: Logger) { self.coreContext = .init(allocator: channel.allocator, logger: logger) @@ -31,21 +31,21 @@ struct BasicBenchmarkContext: HBRequestContext { } /// Writes ByteBuffers to AsyncChannel outbound writer -struct BenchmarkBodyWriter: Sendable, HBResponseBodyWriter { +struct BenchmarkBodyWriter: Sendable, ResponseBodyWriter { func write(_: ByteBuffer) async throws {} } extension Benchmark { @discardableResult - convenience init?( + convenience init?( name: String, context: Context.Type = BasicBenchmarkContext.self, configuration: Benchmark.Configuration = Benchmark.defaultConfiguration, request: HTTPRequest, - writeBody: @escaping @Sendable (HBStreamedRequestBody.InboundStream.TestSource) async throws -> Void = { _ in }, - setupRouter: @escaping @Sendable (HBRouter) async throws -> Void + writeBody: @escaping @Sendable (StreamedRequestBody.InboundStream.TestSource) async throws -> Void = { _ in }, + setupRouter: @escaping @Sendable (Router) async throws -> Void ) { - let router = HBRouter(context: Context.self) + let router = Router(context: Context.self) self.init(name, configuration: configuration) { benchmark in let responder = router.buildResponder() benchmark.startMeasurement() @@ -58,11 +58,11 @@ extension Benchmark { logger: Logger(label: "Benchmark") ) let (inbound, source) = NIOAsyncChannelInboundStream.makeTestingStream() - let streamer = HBStreamedRequestBody(iterator: inbound.makeAsyncIterator()) - let requestBody = HBRequestBody.stream(streamer) - let hbRequest = HBRequest(head: request, body: requestBody) + let streamer = StreamedRequestBody(iterator: inbound.makeAsyncIterator()) + let requestBody = RequestBody.stream(streamer) + let Request = Request(head: request, body: requestBody) group.addTask { - let response = try await responder.respond(to: hbRequest, context: context) + let response = try await responder.respond(to: Request, context: context) _ = try await response.body.write(BenchmarkBodyWriter()) } try await writeBody(source) @@ -121,7 +121,7 @@ func routerBenchmarks() { bodyStream.yield(.body(buffer)) } setupRouter: { router in router.post { request, _ in - HBResponse(status: .ok, headers: [:], body: .init { writer in + Response(status: .ok, headers: [:], body: .init { writer in for try await buffer in request.body { try await writer.write(buffer) } @@ -134,8 +134,8 @@ func routerBenchmarks() { configuration: .init(warmupIterations: 10), request: .init(method: .get, scheme: "http", authority: "localhost", path: "/") ) { router in - struct EmptyMiddleware: HBMiddlewareProtocol { - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct EmptyMiddleware: MiddlewareProtocol { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { return try await next(request, context) } } diff --git a/README.md b/README.md index 6b82efb10..a7efeefa2 100644 --- a/README.md +++ b/README.md @@ -26,12 +26,12 @@ It provides a router for directing different endpoints to their handlers, middle import Hummingbird // create router and add a single GET /hello route -let router = HBRouter() +let router = Router() router.get("hello") { request, _ -> String in return "Hello" } // create application using router -let app = HBApplication( +let app = Application( router: router, configuration: .init(address: .hostname("127.0.0.1", port: 8080)) ) diff --git a/Sources/Hummingbird/Application.swift b/Sources/Hummingbird/Application.swift index 04f96df12..047b01ffe 100644 --- a/Sources/Hummingbird/Application.swift +++ b/Sources/Hummingbird/Application.swift @@ -41,23 +41,23 @@ public enum EventLoopGroupProvider { } } -public protocol HBApplicationProtocol: Service where Context: HBRequestContext { +public protocol ApplicationProtocol: Service where Context: RequestContext { /// Responder that generates a response from a requests and context - associatedtype Responder: HBRequestResponder + associatedtype Responder: RequestResponder /// Child Channel setup. This defaults to support HTTP1 - associatedtype ChildChannel: HBServerChildChannel & HTTPChannelHandler = HTTP1Channel - /// Context passed with HBRequest to responder + associatedtype ChildChannel: ServerChildChannel & HTTPChannelHandler = HTTP1Channel + /// Context passed with Request to responder typealias Context = Responder.Context /// Build the responder var responder: Responder { get async throws } /// Server channel setup - var server: HBHTTPChannelBuilder { get } + var server: HTTPChannelBuilder { get } /// event loop group used by application var eventLoopGroup: EventLoopGroup { get } /// Application configuration - var configuration: HBApplicationConfiguration { get } + var configuration: ApplicationConfiguration { get } /// Logger var logger: Logger { get } /// This is called once the server is running and we have an active Channel @@ -69,16 +69,16 @@ public protocol HBApplicationProtocol: Service where Context: HBRequestContext { var processesRunBeforeServerStart: [@Sendable () async throws -> Void] { get } } -extension HBApplicationProtocol { +extension ApplicationProtocol { /// Server channel setup - public var server: HBHTTPChannelBuilder { .http1() } + public var server: HTTPChannelBuilder { .http1() } } -extension HBApplicationProtocol { +extension ApplicationProtocol { /// Default event loop group used by application public var eventLoopGroup: EventLoopGroup { MultiThreadedEventLoopGroup.singleton } /// Default Configuration - public var configuration: HBApplicationConfiguration { .init() } + public var configuration: ApplicationConfiguration { .init() } /// Default Logger public var logger: Logger { Logger(label: self.configuration.serverName ?? "HummingBird") } /// Default onServerRunning that does nothing @@ -90,17 +90,17 @@ extension HBApplicationProtocol { } /// Conform to `Service` from `ServiceLifecycle`. -extension HBApplicationProtocol { +extension ApplicationProtocol { /// Construct application and run it public func run() async throws { - let dateCache = HBDateCache() + let dateCache = DateCache() let responder = try await self.responder // Function responding to HTTP request - @Sendable func respond(to request: HBRequest, channel: Channel) async throws -> HBResponse { + @Sendable func respond(to request: Request, channel: Channel) async throws -> Response { let context = Self.Responder.Context( channel: channel, - logger: self.logger.with(metadataKey: "hb_id", value: .stringConvertible(RequestID())) + logger: self.logger.with(metadataKey: "_id", value: .stringConvertible(RequestID())) ) // respond to request var response = try await responder.respond(to: request, context: context) @@ -114,7 +114,7 @@ extension HBApplicationProtocol { // get channel Setup let channelSetup = try self.server.build(respond) // create server - let server = HBServer( + let server = Server( childChannelSetup: channelSetup, configuration: self.configuration.httpServer, onServerRunning: self.onServerRunning, @@ -150,16 +150,16 @@ extension HBApplicationProtocol { /// Application class. Brings together all the components of Hummingbird together /// /// ``` -/// let router = HBRouter() +/// let router = Router() /// router.middleware.add(MyMiddleware()) /// router.get("hello") { _ in /// return "hello" /// } -/// let app = HBApplication(responder: router.buildResponder()) +/// let app = Application(responder: router.buildResponder()) /// try await app.runService() /// ``` /// Editing the application setup after calling `runService` will produce undefined behaviour. -public struct HBApplication: HBApplicationProtocol where Responder.Context: HBRequestContext { +public struct Application: ApplicationProtocol where Responder.Context: RequestContext { public typealias Context = Responder.Context public typealias ChildChannel = ChildChannel public typealias Responder = Responder @@ -171,13 +171,13 @@ public struct HBApplication Void /// Server channel setup - public let server: HBHTTPChannelBuilder + public let server: HTTPChannelBuilder /// services attached to the application. public var services: [any Service] /// Processes to be run before server is started @@ -196,8 +196,8 @@ public struct HBApplication = .http1(), - configuration: HBApplicationConfiguration = HBApplicationConfiguration(), + server: HTTPChannelBuilder = .http1(), + configuration: ApplicationConfiguration = ApplicationConfiguration(), onServerRunning: @escaping @Sendable (Channel) async -> Void = { _ in }, eventLoopGroupProvider: EventLoopGroupProvider = .singleton, logger: Logger? = nil @@ -206,7 +206,7 @@ public struct HBApplication( + public init( router: ResponderBuilder, - server: HBHTTPChannelBuilder = .http1(), - configuration: HBApplicationConfiguration = HBApplicationConfiguration(), + server: HTTPChannelBuilder = .http1(), + configuration: ApplicationConfiguration = ApplicationConfiguration(), onServerRunning: @escaping @Sendable (Channel) async -> Void = { _ in }, eventLoopGroupProvider: EventLoopGroupProvider = .singleton, logger: Logger? = nil @@ -240,7 +240,7 @@ public struct HBApplication HBResponse + func encode(_ value: some Encodable, from request: Request, context: some BaseRequestContext) throws -> Response } /// protocol for decoder deserializing from a Request body -public protocol HBRequestDecoder: Sendable { +public protocol RequestDecoder: Sendable { /// Decode type from request /// - Parameters: /// - type: type to decode to /// - request: request - func decode(_ type: T.Type, from request: HBRequest, context: some HBBaseRequestContext) async throws -> T + func decode(_ type: T.Type, from request: Request, context: some BaseRequestContext) async throws -> T } diff --git a/Sources/Hummingbird/Codable/JSON/JSONCoding.swift b/Sources/Hummingbird/Codable/JSON/JSONCoding.swift index c66716e6b..f8e35c18f 100644 --- a/Sources/Hummingbird/Codable/JSON/JSONCoding.swift +++ b/Sources/Hummingbird/Codable/JSON/JSONCoding.swift @@ -17,16 +17,16 @@ import struct Foundation.Date @_exported import class Foundation.JSONEncoder import NIOFoundationCompat -extension JSONEncoder: HBResponseEncoder { - /// Extend JSONEncoder to support encoding `HBResponse`'s. Sets body and header values +extension JSONEncoder: ResponseEncoder { + /// Extend JSONEncoder to support encoding `Response`'s. Sets body and header values /// - Parameters: /// - value: Value to encode /// - request: Request used to generate response - public func encode(_ value: some Encodable, from request: HBRequest, context: some HBBaseRequestContext) throws -> HBResponse { + public func encode(_ value: some Encodable, from request: Request, context: some BaseRequestContext) throws -> Response { var buffer = context.allocator.buffer(capacity: 0) let data = try self.encode(value) buffer.writeBytes(data) - return HBResponse( + return Response( status: .ok, headers: [.contentType: "application/json; charset=utf-8"], body: .init(byteBuffer: buffer) @@ -34,18 +34,18 @@ extension JSONEncoder: HBResponseEncoder { } } -extension JSONDecoder: HBRequestDecoder { - /// Extend JSONDecoder to decode from `HBRequest`. +extension JSONDecoder: RequestDecoder { + /// Extend JSONDecoder to decode from `Request`. /// - Parameters: /// - type: Type to decode /// - request: Request to decode from - public func decode(_ type: T.Type, from request: HBRequest, context: some HBBaseRequestContext) async throws -> T { + public func decode(_ type: T.Type, from request: Request, context: some BaseRequestContext) async throws -> T { let buffer = try await request.body.collect(upTo: context.maxUploadSize) return try self.decode(T.self, from: buffer) } } -/// `HBRequestDecoder` and `HBResponseEncoder` both require conformance to `Sendable`. Given +/// `RequestDecoder` and `ResponseEncoder` both require conformance to `Sendable`. Given /// `JSONEncoder`` and `JSONDecoder`` conform to Sendable in macOS 13+ I think I can just /// back date the conformance to all versions of Swift, macOS we support #if hasFeature(RetroactiveAttribute) diff --git a/Sources/Hummingbird/Codable/ResponseEncodable.swift b/Sources/Hummingbird/Codable/ResponseEncodable.swift index ce11d7650..e24628314 100644 --- a/Sources/Hummingbird/Codable/ResponseEncodable.swift +++ b/Sources/Hummingbird/Codable/ResponseEncodable.swift @@ -15,35 +15,35 @@ import HummingbirdCore /// Protocol for encodable object that can generate a response. The router will encode -/// the response using the encoder stored in `HBApplication.encoder`. -public protocol HBResponseEncodable: Encodable, HBResponseGenerator {} +/// the response using the encoder stored in `Application.encoder`. +public protocol ResponseEncodable: Encodable, ResponseGenerator {} /// Protocol for codable object that can generate a response -public protocol HBResponseCodable: HBResponseEncodable, Decodable {} +public protocol ResponseCodable: ResponseEncodable, Decodable {} /// Extend ResponseEncodable to conform to ResponseGenerator -extension HBResponseEncodable { - public func response(from request: HBRequest, context: some HBBaseRequestContext) throws -> HBResponse { +extension ResponseEncodable { + public func response(from request: Request, context: some BaseRequestContext) throws -> Response { return try context.responseEncoder.encode(self, from: request, context: context) } } -/// Extend Array to conform to HBResponseGenerator -extension Array: HBResponseGenerator where Element: Encodable {} +/// Extend Array to conform to ResponseGenerator +extension Array: ResponseGenerator where Element: Encodable {} -/// Extend Array to conform to HBResponseEncodable -extension Array: HBResponseEncodable where Element: Encodable { - public func response(from request: HBRequest, context: some HBBaseRequestContext) throws -> HBResponse { +/// Extend Array to conform to ResponseEncodable +extension Array: ResponseEncodable where Element: Encodable { + public func response(from request: Request, context: some BaseRequestContext) throws -> Response { return try context.responseEncoder.encode(self, from: request, context: context) } } -/// Extend Dictionary to conform to HBResponseGenerator -extension Dictionary: HBResponseGenerator where Key: Encodable, Value: Encodable {} +/// Extend Dictionary to conform to ResponseGenerator +extension Dictionary: ResponseGenerator where Key: Encodable, Value: Encodable {} -/// Extend Array to conform to HBResponseEncodable -extension Dictionary: HBResponseEncodable where Key: Encodable, Value: Encodable { - public func response(from request: HBRequest, context: some HBBaseRequestContext) throws -> HBResponse { +/// Extend Array to conform to ResponseEncodable +extension Dictionary: ResponseEncodable where Key: Encodable, Value: Encodable { + public func response(from request: Request, context: some BaseRequestContext) throws -> Response { return try context.responseEncoder.encode(self, from: request, context: context) } } diff --git a/Sources/Hummingbird/Codable/URLEncodedForm/URLEncodedForm+Request.swift b/Sources/Hummingbird/Codable/URLEncodedForm/URLEncodedForm+Request.swift index ac706776f..ae9d48427 100644 --- a/Sources/Hummingbird/Codable/URLEncodedForm/URLEncodedForm+Request.swift +++ b/Sources/Hummingbird/Codable/URLEncodedForm/URLEncodedForm+Request.swift @@ -12,16 +12,16 @@ // //===----------------------------------------------------------------------===// -extension URLEncodedFormEncoder: HBResponseEncoder { - /// Extend URLEncodedFormEncoder to support encoding `HBResponse`'s. Sets body and header values +extension URLEncodedFormEncoder: ResponseEncoder { + /// Extend URLEncodedFormEncoder to support encoding `Response`'s. Sets body and header values /// - Parameters: /// - value: Value to encode /// - request: Request used to generate response - public func encode(_ value: some Encodable, from request: HBRequest, context: some HBBaseRequestContext) throws -> HBResponse { + public func encode(_ value: some Encodable, from request: Request, context: some BaseRequestContext) throws -> Response { var buffer = context.allocator.buffer(capacity: 0) let string = try self.encode(value) buffer.writeString(string) - return HBResponse( + return Response( status: .ok, headers: [.contentType: "application/x-www-form-urlencoded"], body: .init(byteBuffer: buffer) @@ -29,12 +29,12 @@ extension URLEncodedFormEncoder: HBResponseEncoder { } } -extension URLEncodedFormDecoder: HBRequestDecoder { - /// Extend URLEncodedFormDecoder to decode from `HBRequest`. +extension URLEncodedFormDecoder: RequestDecoder { + /// Extend URLEncodedFormDecoder to decode from `Request`. /// - Parameters: /// - type: Type to decode /// - request: Request to decode from - public func decode(_ type: T.Type, from request: HBRequest, context: some HBBaseRequestContext) async throws -> T { + public func decode(_ type: T.Type, from request: Request, context: some BaseRequestContext) async throws -> T { let buffer = try await request.body.collect(upTo: context.maxUploadSize) let string = String(buffer: buffer) return try self.decode(T.self, from: string) diff --git a/Sources/Hummingbird/Configuration.swift b/Sources/Hummingbird/Configuration.swift index 9b5b97054..9beb0551e 100644 --- a/Sources/Hummingbird/Configuration.swift +++ b/Sources/Hummingbird/Configuration.swift @@ -22,11 +22,11 @@ import Network // MARK: Configuration /// Application configuration -public struct HBApplicationConfiguration: Sendable { +public struct ApplicationConfiguration: Sendable { // MARK: Member variables /// Bind address for server - public var address: HBAddress + public var address: Address /// Server name to return in "server" header public var serverName: String? /// Defines the maximum length for the queue of pending connections @@ -40,7 +40,7 @@ public struct HBApplicationConfiguration: Sendable { // MARK: Initialization - /// Initialize HBApplication configuration + /// Initialize Application configuration /// /// - Parameters: /// - address: Bind address for server @@ -49,7 +49,7 @@ public struct HBApplicationConfiguration: Sendable { /// the client may receive an error with an indication of ECONNREFUSE /// - reuseAddress: Allows socket to be bound to an address that is already in use. public init( - address: HBAddress = .hostname(), + address: Address = .hostname(), serverName: String? = nil, backlog: Int = 256, reuseAddress: Bool = true @@ -64,7 +64,7 @@ public struct HBApplicationConfiguration: Sendable { } #if canImport(Network) - /// Initialize HBApplication configuration + /// Initialize Application configuration /// /// - Parameters: /// - address: Bind address for server @@ -72,7 +72,7 @@ public struct HBApplicationConfiguration: Sendable { /// - reuseAddress: Allows socket to be bound to an address that is already in use. /// - tlsOptions: TLS options for when you are using NIOTransportServices public init( - address: HBAddress = .hostname(), + address: Address = .hostname(), serverName: String? = nil, reuseAddress: Bool = true, tlsOptions: TSTLSOptions @@ -88,7 +88,7 @@ public struct HBApplicationConfiguration: Sendable { /// Create new configuration struct with updated values public func with( - address: HBAddress? = nil, + address: Address? = nil, serverName: String? = nil, backlog: Int? = nil, reuseAddress: Bool? = nil @@ -103,7 +103,7 @@ public struct HBApplicationConfiguration: Sendable { /// return HTTP server configuration #if canImport(Network) - var httpServer: HBServerConfiguration { + var httpServer: ServerConfiguration { return .init( address: self.address, serverName: self.serverName, @@ -113,7 +113,7 @@ public struct HBApplicationConfiguration: Sendable { ) } #else - var httpServer: HBServerConfiguration { + var httpServer: ServerConfiguration { return .init( address: self.address, serverName: self.serverName, diff --git a/Sources/Hummingbird/Environment.swift b/Sources/Hummingbird/Environment.swift index 4c3794f7c..bb21ee99c 100644 --- a/Sources/Hummingbird/Environment.swift +++ b/Sources/Hummingbird/Environment.swift @@ -21,7 +21,7 @@ import HummingbirdCore import NIOCore /// Access environment variables -public struct HBEnvironment: Sendable, Decodable, ExpressibleByDictionaryLiteral { +public struct Environment: Sendable, Decodable, ExpressibleByDictionaryLiteral { struct Error: Swift.Error, Equatable { enum Value { case dotEnvParseError @@ -36,7 +36,7 @@ public struct HBEnvironment: Sendable, Decodable, ExpressibleByDictionaryLiteral } // shared environment - public static let shared: HBEnvironment = .init() + public static let shared: Environment = .init() var values: [String: String] @@ -98,7 +98,7 @@ public struct HBEnvironment: Sendable, Decodable, ExpressibleByDictionaryLiteral /// If an environment variable exists in both sets it will choose the version from the second /// set of environment variables /// - Parameter env: environemnt variables to merge into this environment variable set - public func merging(with env: HBEnvironment) -> HBEnvironment { + public func merging(with env: Environment) -> Environment { .init(rawValues: self.values.merging(env.values) { $1 }) } @@ -121,7 +121,7 @@ public struct HBEnvironment: Sendable, Decodable, ExpressibleByDictionaryLiteral return values } - /// Create HBEnvironment initialised from the `.env` file + /// Create Environment initialised from the `.env` file public static func dotEnv(_ dovEnvPath: String = ".env") async throws -> Self { guard let dotEnv = await loadDotEnv(dovEnvPath) else { return [:] } return try .init(rawValues: self.parseDotEnv(dotEnv)) @@ -155,7 +155,7 @@ public struct HBEnvironment: Sendable, Decodable, ExpressibleByDictionaryLiteral case readingValue(key: String) } var dotEnvDictionary: [String: String] = [:] - var parser = HBParser(dotEnv) + var parser = Parser(dotEnv) var state: DotEnvParserState = .readingKey do { while !parser.reachedEnd() { @@ -172,7 +172,7 @@ public struct HBEnvironment: Sendable, Decodable, ExpressibleByDictionaryLiteral do { _ = try parser.read(until: \.isNewline) parser.unsafeAdvance() - } catch HBParser.Error.overflow { + } catch Parser.Error.overflow { parser.moveToEnd() break } @@ -212,7 +212,7 @@ public struct HBEnvironment: Sendable, Decodable, ExpressibleByDictionaryLiteral } } -extension HBEnvironment: CustomStringConvertible { +extension Environment: CustomStringConvertible { public var description: String { String(describing: self.values) } diff --git a/Sources/Hummingbird/Exports.swift b/Sources/Hummingbird/Exports.swift index 06d7ce39b..18d24009b 100644 --- a/Sources/Hummingbird/Exports.swift +++ b/Sources/Hummingbird/Exports.swift @@ -12,14 +12,14 @@ // //===----------------------------------------------------------------------===// -@_exported import struct HummingbirdCore.HBAddress -@_exported import struct HummingbirdCore.HBHTTPError -@_exported import protocol HummingbirdCore.HBHTTPResponseError -@_exported import struct HummingbirdCore.HBRequest -@_exported import struct HummingbirdCore.HBRequestBody -@_exported import struct HummingbirdCore.HBResponse -@_exported import struct HummingbirdCore.HBResponseBody -@_exported import protocol HummingbirdCore.HBResponseBodyWriter +@_exported import struct HummingbirdCore.Address +@_exported import struct HummingbirdCore.HTTPError +@_exported import protocol HummingbirdCore.HTTPResponseError +@_exported import struct HummingbirdCore.Request +@_exported import struct HummingbirdCore.RequestBody +@_exported import struct HummingbirdCore.Response +@_exported import struct HummingbirdCore.ResponseBody +@_exported import protocol HummingbirdCore.ResponseBodyWriter #if canImport(Network) @_exported import struct HummingbirdCore.TSTLSOptions #endif diff --git a/Sources/Hummingbird/Files/CacheControl.swift b/Sources/Hummingbird/Files/CacheControl.swift index dda1718c1..926e24b97 100644 --- a/Sources/Hummingbird/Files/CacheControl.swift +++ b/Sources/Hummingbird/Files/CacheControl.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// /// Associates cache control values with filename -public struct HBCacheControl: Sendable { +public struct CacheControl: Sendable { public enum Value: CustomStringConvertible, Sendable { case noStore case noCache @@ -42,7 +42,7 @@ public struct HBCacheControl: Sendable { /// Initialize cache control /// - Parameter entries: cache control entries - public init(_ entries: [(HBMediaType, [Value])]) { + public init(_ entries: [(MediaType, [Value])]) { self.entries = entries.map { .init(mediaType: $0.0, cacheControl: $0.1) } } @@ -53,7 +53,7 @@ public struct HBCacheControl: Sendable { guard let extPointIndex = file.lastIndex(of: ".") else { return nil } let extIndex = file.index(after: extPointIndex) let ext = String(file.suffix(from: extIndex)) - guard let mediaType = HBMediaType.getMediaType(forExtension: ext) else { return nil } + guard let mediaType = MediaType.getMediaType(forExtension: ext) else { return nil } guard let entry = self.entries.first(where: { mediaType.isType($0.mediaType) }) else { return nil } return entry.cacheControl .map(\.description) @@ -61,7 +61,7 @@ public struct HBCacheControl: Sendable { } private struct Entry: Sendable { - let mediaType: HBMediaType + let mediaType: MediaType let cacheControl: [Value] } diff --git a/Sources/Hummingbird/Files/FileIO.swift b/Sources/Hummingbird/Files/FileIO.swift index a720903d3..c6c70979f 100644 --- a/Sources/Hummingbird/Files/FileIO.swift +++ b/Sources/Hummingbird/Files/FileIO.swift @@ -18,7 +18,7 @@ import NIOCore import NIOPosix /// Manages File reading and writing. -public struct HBFileIO: Sendable { +public struct FileIO: Sendable { let eventLoopGroup: EventLoopGroup let fileIO: NonBlockingFileIO let chunkSize: Int @@ -39,7 +39,7 @@ public struct HBFileIO: Sendable { /// - path: System file path /// - context: Context this request is being called in /// - Returns: Response body - public func loadFile(path: String, context: some HBBaseRequestContext) async throws -> HBResponseBody { + public func loadFile(path: String, context: some BaseRequestContext) async throws -> ResponseBody { do { let (handle, region) = try await self.fileIO.openFile(path: path, eventLoop: self.eventLoopGroup.any()).get() context.logger.debug("[FileIO] GET", metadata: ["file": .string(path)]) @@ -54,7 +54,7 @@ public struct HBFileIO: Sendable { return try await self.loadFile(handle: handle, region: region, context: context) } } catch { - throw HBHTTPError(.notFound) + throw HTTPError(.notFound) } } @@ -67,7 +67,7 @@ public struct HBFileIO: Sendable { /// - range:Range defining how much of the file is to be loaded /// - context: Context this request is being called in /// - Returns: Response body plus file size - public func loadFile(path: String, range: ClosedRange, context: some HBBaseRequestContext) async throws -> (HBResponseBody, Int) { + public func loadFile(path: String, range: ClosedRange, context: some BaseRequestContext) async throws -> (ResponseBody, Int) { do { let (handle, region) = try await self.fileIO.openFile(path: path, eventLoop: self.eventLoopGroup.any()).get() context.logger.debug("[FileIO] GET", metadata: ["file": .string(path)]) @@ -90,7 +90,7 @@ public struct HBFileIO: Sendable { return (buffer, region.readableBytes) } } catch { - throw HBHTTPError(.notFound) + throw HTTPError(.notFound) } } @@ -101,7 +101,7 @@ public struct HBFileIO: Sendable { /// - contents: Request body to write. /// - path: Path to write to /// - logger: Logger - public func writeFile(contents: HBRequestBody, path: String, context: some HBBaseRequestContext) async throws { + public func writeFile(contents: RequestBody, path: String, context: some BaseRequestContext) async throws { let eventLoop = self.eventLoopGroup.any() let handle = try await self.fileIO.openFile(path: path, mode: .write, flags: .allowFileCreation(), eventLoop: eventLoop).get() defer { @@ -114,7 +114,7 @@ public struct HBFileIO: Sendable { } /// Load file as ByteBuffer - func loadFile(handle: NIOFileHandle, region: FileRegion, context: some HBBaseRequestContext) async throws -> HBResponseBody { + func loadFile(handle: NIOFileHandle, region: FileRegion, context: some BaseRequestContext) async throws -> ResponseBody { let buffer = try await self.fileIO.read( fileHandle: handle, fromOffset: Int64(region.readerIndex), @@ -126,10 +126,10 @@ public struct HBFileIO: Sendable { } /// Return streamer that will load file - func streamFile(handle: NIOFileHandle, region: FileRegion, context: some HBBaseRequestContext) throws -> HBResponseBody { + func streamFile(handle: NIOFileHandle, region: FileRegion, context: some BaseRequestContext) throws -> ResponseBody { let fileOffset = region.readerIndex let endOffset = region.endIndex - return HBResponseBody(contentLength: region.readableBytes) { writer in + return ResponseBody(contentLength: region.readableBytes) { writer in let chunkSize = 8 * 1024 var fileOffset = fileOffset diff --git a/Sources/Hummingbird/Files/FileMiddleware.swift b/Sources/Hummingbird/Files/FileMiddleware.swift index 13548be8f..ba99f84fe 100644 --- a/Sources/Hummingbird/Files/FileMiddleware.swift +++ b/Sources/Hummingbird/Files/FileMiddleware.swift @@ -28,16 +28,16 @@ import NIOPosix /// "if-modified-since", "if-none-match", "if-range" and 'range" headers. It will output "content-length", /// "modified-date", "eTag", "content-type", "cache-control" and "content-range" headers where /// they are relevant. -public struct HBFileMiddleware: HBRouterMiddleware { +public struct FileMiddleware: RouterMiddleware { struct IsDirectoryError: Error {} let rootFolder: URL let threadPool: NIOThreadPool - let fileIO: HBFileIO - let cacheControl: HBCacheControl + let fileIO: FileIO + let cacheControl: CacheControl let searchForIndexHtml: Bool - /// Create HBFileMiddleware + /// Create FileMiddleware /// - Parameters: /// - rootFolder: Root folder to look for files /// - cacheControl: What cache control headers to include in response @@ -45,10 +45,10 @@ public struct HBFileMiddleware: HBRouterMiddlewar /// - application: Application we are attaching to public init( _ rootFolder: String = "public", - cacheControl: HBCacheControl = .init([]), + cacheControl: CacheControl = .init([]), searchForIndexHtml: Bool = false, threadPool: NIOThreadPool = NIOThreadPool.singleton, - logger: Logger = Logger(label: "HBFileMiddleware") + logger: Logger = Logger(label: "FileMiddleware") ) { self.rootFolder = URL(fileURLWithPath: rootFolder) self.threadPool = threadPool @@ -70,20 +70,20 @@ public struct HBFileMiddleware: HBRouterMiddlewar logger.info("FileMiddleware serving from \(workingFolder)\(rootFolder)") } - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { do { return try await next(request, context) } catch { - guard let httpError = error as? HBHTTPError, httpError.status == .notFound else { + guard let httpError = error as? HTTPError, httpError.status == .notFound else { throw error } guard let path = request.uri.path.removingPercentEncoding else { - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } guard !path.contains("..") else { - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } let fileResult = try await self.threadPool.runIfActive { () -> FileResult in @@ -106,7 +106,7 @@ public struct HBFileMiddleware: HBRouterMiddlewar contentSize = attributes[.size] as? Int } } catch { - throw HBHTTPError(.notFound) + throw HTTPError(.notFound) } let eTag = createETag([ String(describing: modificationDate?.timeIntervalSince1970 ?? 0), @@ -123,7 +123,7 @@ public struct HBFileMiddleware: HBRouterMiddlewar // modified-date var modificationDateString: String? if let modificationDate { - modificationDateString = HBDateCache.rfc1123Formatter.string(from: modificationDate) + modificationDateString = DateCache.rfc1123Formatter.string(from: modificationDate) headers[.lastModified] = modificationDateString! } // eTag (constructed from modification date and content size) @@ -133,7 +133,7 @@ public struct HBFileMiddleware: HBRouterMiddlewar if let extPointIndex = path.lastIndex(of: ".") { let extIndex = path.index(after: extPointIndex) let ext = String(path.suffix(from: extIndex)) - if let contentType = HBMediaType.getMediaType(forExtension: ext) { + if let contentType = MediaType.getMediaType(forExtension: ext) { headers[.contentType] = contentType.description } } @@ -159,7 +159,7 @@ public struct HBFileMiddleware: HBRouterMiddlewar else if let ifModifiedSince = request.headers[.ifModifiedSince], let modificationDate { - if let ifModifiedSinceDate = HBDateCache.rfc1123Formatter.date(from: ifModifiedSince) { + if let ifModifiedSinceDate = DateCache.rfc1123Formatter.date(from: ifModifiedSince) { // round modification date of file down to seconds for comparison let modificationDateTimeInterval = modificationDate.timeIntervalSince1970.rounded(.down) let ifModifiedSinceDateTimeInterval = ifModifiedSinceDate.timeIntervalSince1970 @@ -171,7 +171,7 @@ public struct HBFileMiddleware: HBRouterMiddlewar if let rangeHeader = request.headers[.range] { guard let range = getRangeFromHeaderValue(rangeHeader) else { - throw HBHTTPError(.rangeNotSatisfiable) + throw HTTPError(.rangeNotSatisfiable) } // range request conditional on etag or modified date being equal to value in if-range if let ifRange = request.headers[.ifRange], ifRange != headers[.eTag], ifRange != headers[.lastModified] { @@ -192,20 +192,20 @@ public struct HBFileMiddleware: HBRouterMiddlewar switch fileResult { case .notModified(let headers): - return HBResponse(status: .notModified, headers: headers) + return Response(status: .notModified, headers: headers) case .loadFile(let fullPath, let headers, let range): switch request.method { case .get: if let range { let (body, _) = try await self.fileIO.loadFile(path: fullPath, range: range, context: context) - return HBResponse(status: .partialContent, headers: headers, body: body) + return Response(status: .partialContent, headers: headers, body: body) } let body = try await self.fileIO.loadFile(path: fullPath, context: context) - return HBResponse(status: .ok, headers: headers, body: body) + return Response(status: .ok, headers: headers, body: body) case .head: - return HBResponse(status: .ok, headers: headers, body: .init()) + return Response(status: .ok, headers: headers, body: .init()) default: throw error @@ -221,7 +221,7 @@ public struct HBFileMiddleware: HBRouterMiddlewar } } -extension HBFileMiddleware { +extension FileMiddleware { /// Convert "bytes=value-value" range header into `ClosedRange` /// /// Also supports open ended ranges diff --git a/Sources/Hummingbird/HTTP/Cookie.swift b/Sources/Hummingbird/HTTP/Cookie.swift index 9db57910e..7c628907d 100644 --- a/Sources/Hummingbird/HTTP/Cookie.swift +++ b/Sources/Hummingbird/HTTP/Cookie.swift @@ -15,7 +15,7 @@ import Foundation /// Structure holding a single cookie -public struct HBCookie: Sendable, CustomStringConvertible { +public struct Cookie: Sendable, CustomStringConvertible { public enum SameSite: String { case lax = "Lax" case secure = "Secure" @@ -30,7 +30,7 @@ public struct HBCookie: Sendable, CustomStringConvertible { public let properties: Properties /// indicates the maximum lifetime of the cookie - public var expires: Date? { return self.properties[.expires].map { HBDateCache.rfc1123Formatter.date(from: $0) } ?? nil } + public var expires: Date? { return self.properties[.expires].map { DateCache.rfc1123Formatter.date(from: $0) } ?? nil } /// indicates the maximum lifetime of the cookie in seconds. Max age has precedence over expires /// (not all user agents support max-age) public var maxAge: Int? { return self.properties[.maxAge].map { Int($0) } ?? nil } @@ -45,7 +45,7 @@ public struct HBCookie: Sendable, CustomStringConvertible { /// The SameSite attribute lets servers specify whether/when cookies are sent with cross-origin requests public var sameSite: SameSite? { return self.properties[.sameSite].map { SameSite(rawValue: $0) } ?? nil } - /// Create `HBCookie` + /// Create `Cookie` /// - Parameters: /// - name: Name of cookie /// - value: Value of cookie @@ -69,7 +69,7 @@ public struct HBCookie: Sendable, CustomStringConvertible { self.name = name self.value = value var properties = Properties() - properties[.expires] = expires.map { HBDateCache.rfc1123Formatter.string(from: $0) } + properties[.expires] = expires.map { DateCache.rfc1123Formatter.string(from: $0) } properties[.maxAge] = maxAge?.description properties[.domain] = domain properties[.path] = path @@ -78,7 +78,7 @@ public struct HBCookie: Sendable, CustomStringConvertible { self.properties = properties } - /// Create `HBCookie` + /// Create `Cookie` /// - Parameters: /// - name: Name of cookie /// - value: Value of cookie @@ -103,7 +103,7 @@ public struct HBCookie: Sendable, CustomStringConvertible { self.name = name self.value = value var properties = Properties() - properties[.expires] = expires.map { HBDateCache.rfc1123Formatter.string(from: $0) } + properties[.expires] = expires.map { DateCache.rfc1123Formatter.string(from: $0) } properties[.maxAge] = maxAge?.description properties[.domain] = domain properties[.path] = path diff --git a/Sources/Hummingbird/HTTP/Cookies.swift b/Sources/Hummingbird/HTTP/Cookies.swift index e0cb9f3a6..faceb4c78 100644 --- a/Sources/Hummingbird/HTTP/Cookies.swift +++ b/Sources/Hummingbird/HTTP/Cookies.swift @@ -14,25 +14,25 @@ /// Structure holding an array of cookies /// -/// Cookies can be accessed from request via `HBRequest.cookies`. -public struct HBCookies: Sendable { - /// Construct cookies accessor from `HBRequest` +/// Cookies can be accessed from request via `Request.cookies`. +public struct Cookies: Sendable { + /// Construct cookies accessor from `Request` /// - Parameter request: request to get cookies from - init(from request: HBRequest) { + init(from request: Request) { self.cookieStrings = request.headers[values: .cookie].flatMap { return $0.split(separator: ";").map { $0.drop { $0.isWhitespace } } } } /// access cookies via dictionary subscript - public subscript(_ key: String) -> HBCookie? { + public subscript(_ key: String) -> Cookie? { guard let cookieString = cookieStrings.first(where: { - guard let cookieName = HBCookie.getName(from: $0) else { return false } + guard let cookieName = Cookie.getName(from: $0) else { return false } return cookieName == key }) else { return nil } - return HBCookie(from: cookieString) + return Cookie(from: cookieString) } var cookieStrings: [Substring] diff --git a/Sources/Hummingbird/HTTP/MediaType.swift b/Sources/Hummingbird/HTTP/MediaType.swift index 0d196c87c..5a426e55b 100644 --- a/Sources/Hummingbird/HTTP/MediaType.swift +++ b/Sources/Hummingbird/HTTP/MediaType.swift @@ -15,7 +15,7 @@ import HummingbirdCore /// Define media type of file -public struct HBMediaType: Sendable, CustomStringConvertible { +public struct MediaType: Sendable, CustomStringConvertible { /// general category public let type: Category /// exact kind of data specified @@ -23,7 +23,7 @@ public struct HBMediaType: Sendable, CustomStringConvertible { /// optional parameter public let parameter: (name: String, value: String)? - /// Initialize `HBMediaType` + /// Initialize `MediaType` /// - Parameters: /// - type: category /// - subType: specific kind of data @@ -34,7 +34,7 @@ public struct HBMediaType: Sendable, CustomStringConvertible { self.parameter = parameter } - /// Construct `HBMediaType` from header value + /// Construct `MediaType` from header value public init?(from header: String) { enum State: Equatable { case readingCategory @@ -43,7 +43,7 @@ public struct HBMediaType: Sendable, CustomStringConvertible { case readingParameterValue(key: String) case finished } - var parser = HBParser(header) + var parser = Parser(header) var state = State.readingCategory var category: Category? @@ -111,7 +111,7 @@ public struct HBMediaType: Sendable, CustomStringConvertible { } /// Return media type with new parameter - public func withParameter(name: String, value: String) -> HBMediaType { + public func withParameter(name: String, value: String) -> MediaType { return .init(type: self.type, subType: self.subType, parameter: (name, value)) } @@ -125,7 +125,7 @@ public struct HBMediaType: Sendable, CustomStringConvertible { } /// Return if media type matches the input - public func isType(_ type: HBMediaType) -> Bool { + public func isType(_ type: MediaType) -> Bool { guard self.type == type.type, self.subType == type.subType || type.subType == "*" else { @@ -141,7 +141,7 @@ public struct HBMediaType: Sendable, CustomStringConvertible { /// Get media type from a file extension /// - Parameter extension: file extension /// - Returns: media type - public static func getMediaType(forExtension: String) -> HBMediaType? { + public static func getMediaType(forExtension: String) -> MediaType? { return extensionMediaTypeMap[forExtension] } @@ -172,7 +172,7 @@ public struct HBMediaType: Sendable, CustomStringConvertible { static let tSpecial = Set(["(", ")", "<", ">", "@", ",", ";", ":", "\\", "\"", "/", "[", "]", "?", ".", "="]) } -extension HBMediaType { +extension MediaType { // types public static var application: Self { .init(type: .application) } public static var audio: Self { .init(type: .audio) } @@ -351,7 +351,7 @@ extension HBMediaType { public static var multipartForm: Self { .init(type: .multipart, subType: "form-data") } /// map from extension string to media type - static let extensionMediaTypeMap: [String: HBMediaType] = [ + static let extensionMediaTypeMap: [String: MediaType] = [ "aac": .audioAac, "abw": .applicationAbiWord, "arc": .applicationArc, @@ -428,7 +428,7 @@ extension HBMediaType { ] } -extension HBMediaType { +extension MediaType { // Allow matching media types in switch statements public static func ~= (_ lhs: Self, _ rhs: Self) -> Bool { rhs.isType(lhs) diff --git a/Sources/Hummingbird/HTTP/Request+Cookies.swift b/Sources/Hummingbird/HTTP/Request+Cookies.swift index c846bf349..cbdbc0c8b 100644 --- a/Sources/Hummingbird/HTTP/Request+Cookies.swift +++ b/Sources/Hummingbird/HTTP/Request+Cookies.swift @@ -14,9 +14,9 @@ import HummingbirdCore -extension HBRequest { - /// access cookies from request. When accessing this for the first time the HBCookies struct will be created - public var cookies: HBCookies { - HBCookies(from: self) +extension Request { + /// access cookies from request. When accessing this for the first time the Cookies struct will be created + public var cookies: Cookies { + Cookies(from: self) } } diff --git a/Sources/Hummingbird/HTTP/Response+Cookies.swift b/Sources/Hummingbird/HTTP/Response+Cookies.swift index 4b9adbd11..fa0e782fb 100644 --- a/Sources/Hummingbird/HTTP/Response+Cookies.swift +++ b/Sources/Hummingbird/HTTP/Response+Cookies.swift @@ -14,18 +14,18 @@ import HummingbirdCore -extension HBResponse { +extension Response { /// Set cookie on response - public mutating func setCookie(_ cookie: HBCookie) { + public mutating func setCookie(_ cookie: Cookie) { self.headers[values: .setCookie].append(cookie.description) } } -extension HBEditedResponse { +extension EditedResponse { /// Set cookie on reponse patch /// /// Can be accessed via `request.response.setCookie(myCookie)` - public mutating func setCookie(_ cookie: HBCookie) { + public mutating func setCookie(_ cookie: Cookie) { self.headers[values: .setCookie].append(cookie.description) } } diff --git a/Sources/Hummingbird/Middleware/CORSMiddleware.swift b/Sources/Hummingbird/Middleware/CORSMiddleware.swift index 1d498530e..f90d81324 100644 --- a/Sources/Hummingbird/Middleware/CORSMiddleware.swift +++ b/Sources/Hummingbird/Middleware/CORSMiddleware.swift @@ -21,7 +21,7 @@ import NIOCore /// then return an empty body with all the standard CORS headers otherwise send /// request onto the next handler and when you receive the response add a /// "access-control-allow-origin" header -public struct HBCORSMiddleware: HBRouterMiddleware { +public struct CORSMiddleware: RouterMiddleware { /// Defines what origins are allowed public enum AllowOrigin: Sendable { case none @@ -29,7 +29,7 @@ public struct HBCORSMiddleware: HBRouterMiddlewar case originBased case custom(String) - func value(for request: HBRequest) -> String? { + func value(for request: Request) -> String? { switch self { case .none: return nil @@ -84,7 +84,7 @@ public struct HBCORSMiddleware: HBRouterMiddlewar } /// apply CORS middleware - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { // if no origin header then don't apply CORS guard request.headers[.origin] != nil else { return try await next(request, context) @@ -110,7 +110,7 @@ public struct HBCORSMiddleware: HBRouterMiddlewar headers[.vary] = "Origin" } - return HBResponse(status: .noContent, headers: headers, body: .init()) + return Response(status: .noContent, headers: headers, body: .init()) } else { // if not OPTIONS then run rest of middleware chain and add origin value at the end var response = try await next(request, context) diff --git a/Sources/Hummingbird/Middleware/LogRequestMiddleware.swift b/Sources/Hummingbird/Middleware/LogRequestMiddleware.swift index afc00605d..6b9173064 100644 --- a/Sources/Hummingbird/Middleware/LogRequestMiddleware.swift +++ b/Sources/Hummingbird/Middleware/LogRequestMiddleware.swift @@ -15,7 +15,7 @@ import Logging /// Middleware outputting to log for every call to server -public struct HBLogRequestsMiddleware: HBRouterMiddleware { +public struct LogRequestsMiddleware: RouterMiddleware { let logLevel: Logger.Level let includeHeaders: Bool @@ -24,18 +24,18 @@ public struct HBLogRequestsMiddleware: HBRouterMi self.includeHeaders = includeHeaders } - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { if self.includeHeaders { context.logger.log( level: self.logLevel, "\(request.headers)", - metadata: ["hb_uri": .stringConvertible(request.uri), "hb_method": .string(request.method.rawValue)] + metadata: ["_uri": .stringConvertible(request.uri), "_method": .string(request.method.rawValue)] ) } else { context.logger.log( level: self.logLevel, "", - metadata: ["hb_uri": .stringConvertible(request.uri), "hb_method": .string(request.method.rawValue)] + metadata: ["_uri": .stringConvertible(request.uri), "_method": .string(request.method.rawValue)] ) } return try await next(request, context) diff --git a/Sources/Hummingbird/Middleware/MetricsMiddleware.swift b/Sources/Hummingbird/Middleware/MetricsMiddleware.swift index 7785cd963..70a0a58b6 100644 --- a/Sources/Hummingbird/Middleware/MetricsMiddleware.swift +++ b/Sources/Hummingbird/Middleware/MetricsMiddleware.swift @@ -19,10 +19,10 @@ import Metrics /// /// Records the number of requests, the request duration and how many errors were thrown. Each metric has additional /// dimensions URI and method. -public struct HBMetricsMiddleware: HBRouterMiddleware { +public struct MetricsMiddleware: RouterMiddleware { public init() {} - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { let startTime = DispatchTime.now().uptimeNanoseconds do { @@ -30,12 +30,12 @@ public struct HBMetricsMiddleware: HBRouterMiddle // need to create dimensions once request has been responded to ensure // we have the correct endpoint path let dimensions: [(String, String)] = [ - ("hb_uri", context.endpointPath ?? request.uri.path), - ("hb_method", request.method.rawValue), + ("_uri", context.endpointPath ?? request.uri.path), + ("_method", request.method.rawValue), ] - Counter(label: "hb_requests", dimensions: dimensions).increment() + Counter(label: "_requests", dimensions: dimensions).increment() Metrics.Timer( - label: "hb_request_duration", + label: "_request_duration", dimensions: dimensions, preferredDisplayUnit: .seconds ).recordNanoseconds(DispatchTime.now().uptimeNanoseconds - startTime) @@ -47,16 +47,16 @@ public struct HBMetricsMiddleware: HBRouterMiddle // Don't record uri in 404 errors, to avoid spamming of metrics if let endpointPath = context.endpointPath { dimensions = [ - ("hb_uri", endpointPath), - ("hb_method", request.method.rawValue), + ("_uri", endpointPath), + ("_method", request.method.rawValue), ] - Counter(label: "hb_requests", dimensions: dimensions).increment() + Counter(label: "_requests", dimensions: dimensions).increment() } else { dimensions = [ - ("hb_method", request.method.rawValue), + ("_method", request.method.rawValue), ] } - Counter(label: "hb_errors", dimensions: dimensions).increment() + Counter(label: "_errors", dimensions: dimensions).increment() throw error } } diff --git a/Sources/Hummingbird/Middleware/Middleware.swift b/Sources/Hummingbird/Middleware/Middleware.swift index a43d91c8f..e1f0846b8 100644 --- a/Sources/Hummingbird/Middleware/Middleware.swift +++ b/Sources/Hummingbird/Middleware/Middleware.swift @@ -23,7 +23,7 @@ public protocol MiddlewareProtocol: Sendable { func handle(_ input: Input, context: Context, next: (Input, Context) async throws -> Output) async throws -> Output } -/// Applied to `HBRequest` before it is dealt with by the router. Middleware passes the processed request onto the next responder +/// Applied to `Request` before it is dealt with by the router. Middleware passes the processed request onto the next responder /// (either the next middleware or a route) by calling `next(request, context)`. If you want to shortcut the request you /// can return a response immediately /// @@ -32,7 +32,7 @@ public protocol MiddlewareProtocol: Sendable { /// Middleware allows you to process a request before it reaches your request handler and then process the response /// returned by that handler. /// ``` -/// func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse +/// func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response /// let request = processRequest(request) /// let response = try await next(request, context) /// return processResponse(response) @@ -40,23 +40,23 @@ public protocol MiddlewareProtocol: Sendable { /// ``` /// Middleware also allows you to shortcut the whole process and not pass on the request to the handler /// ``` -/// func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse +/// func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response /// if request.method == .OPTIONS { -/// return HBResponse(status: .noContent) +/// return Response(status: .noContent) /// } else { /// return try await next(request, context) /// } /// } /// ``` -/// Middleware protocol with HBRequest as input and HBResponse as output -public protocol HBRouterMiddleware: MiddlewareProtocol where Input == HBRequest, Output == HBResponse {} +/// Middleware protocol with Request as input and Response as output +public protocol RouterMiddleware: MiddlewareProtocol where Input == Request, Output == Response {} -struct MiddlewareResponder: HBRequestResponder { - let middleware: any HBRouterMiddleware - let next: @Sendable (HBRequest, Context) async throws -> HBResponse +struct MiddlewareResponder: RequestResponder { + let middleware: any RouterMiddleware + let next: @Sendable (Request, Context) async throws -> Response - func respond(to request: HBRequest, context: Context) async throws -> HBResponse { + func respond(to request: Request, context: Context) async throws -> Response { return try await self.middleware.handle(request, context: context) { request, context in try await self.next(request, context) } diff --git a/Sources/Hummingbird/Middleware/MiddlewareGroup.swift b/Sources/Hummingbird/Middleware/MiddlewareGroup.swift index da6d761b8..e609c69d5 100644 --- a/Sources/Hummingbird/Middleware/MiddlewareGroup.swift +++ b/Sources/Hummingbird/Middleware/MiddlewareGroup.swift @@ -13,23 +13,23 @@ //===----------------------------------------------------------------------===// /// Group of middleware that can be used to create a responder chain. Each middleware calls the next one -public final class HBMiddlewareGroup { - var middlewares: [any HBRouterMiddleware] +public final class MiddlewareGroup { + var middlewares: [any RouterMiddleware] - /// Initialize `HBMiddlewareGroup` - init(middlewares: [any HBRouterMiddleware] = []) { + /// Initialize `MiddlewareGroup` + init(middlewares: [any RouterMiddleware] = []) { self.middlewares = middlewares } /// Add middleware to group - public func add(_ middleware: any HBRouterMiddleware) { + public func add(_ middleware: any RouterMiddleware) { self.middlewares.append(middleware) } /// Construct responder chain from this middleware group /// - Parameter finalResponder: The responder the last middleware calls /// - Returns: Responder chain - public func constructResponder(finalResponder: any HBRequestResponder) -> any HBRequestResponder { + public func constructResponder(finalResponder: any RequestResponder) -> any RequestResponder { var currentResponser = finalResponder for i in (0..: HBRouterMiddleware { +public struct TracingMiddleware: RouterMiddleware { private let headerNamesToRecord: Set private let attributes: SpanAttributes? - /// Intialize a new HBTracingMiddleware. + /// Intialize a new TracingMiddleware. /// /// - Parameters /// - recordingHeaders: A list of HTTP header names to be recorded as span attributes. By default, no headers @@ -39,7 +39,7 @@ public struct HBTracingMiddleware: HBRouterMiddle self.attributes = attributes } - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var serviceContext = ServiceContext.current ?? ServiceContext.topLevel InstrumentationSystem.instrument.extract(request.headers, into: &serviceContext, using: HTTPHeadersExtractor()) @@ -63,7 +63,7 @@ public struct HBTracingMiddleware: HBRouterMiddle attributes["http.user_agent"] = request.headers[.userAgent] attributes["http.request_content_length"] = request.headers[.contentLength].map { Int($0) } ?? nil - if let remoteAddress = (context as? any HBRemoteAddressRequestContext)?.remoteAddress { + if let remoteAddress = (context as? any RemoteAddressRequestContext)?.remoteAddress { attributes["net.sock.peer.port"] = remoteAddress.port switch remoteAddress.protocol { @@ -91,7 +91,7 @@ public struct HBTracingMiddleware: HBRouterMiddle attributes["http.response_content_length"] = response.body.contentLength } return response - } catch let error as HBHTTPResponseError { + } catch let error as HTTPResponseError { span.attributes["http.status_code"] = Int(error.status.code) if 500..<600 ~= error.status.code { @@ -122,9 +122,9 @@ public struct HBTracingMiddleware: HBRouterMiddle /// Protocol for request context that stores the remote address of connected client. /// -/// If you want the HBTracingMiddleware to record the remote address of requests +/// If you want the TracingMiddleware to record the remote address of requests /// then your request context will need to conform to this protocol -public protocol HBRemoteAddressRequestContext: HBBaseRequestContext { +public protocol RemoteAddressRequestContext: BaseRequestContext { /// Connected host address var remoteAddress: SocketAddress? { get } } diff --git a/Sources/Hummingbird/Router/EndpointResponder.swift b/Sources/Hummingbird/Router/EndpointResponder.swift index 6047b2d25..fe947ad25 100644 --- a/Sources/Hummingbird/Router/EndpointResponder.swift +++ b/Sources/Hummingbird/Router/EndpointResponder.swift @@ -15,17 +15,17 @@ import HTTPTypes /// Stores endpoint responders for each HTTP method -struct HBEndpointResponders: Sendable { +struct EndpointResponders: Sendable { init(path: String) { self.path = path self.methods = [:] } - public func getResponder(for method: HTTPRequest.Method) -> (any HBRequestResponder)? { + public func getResponder(for method: HTTPRequest.Method) -> (any RequestResponder)? { return self.methods[method] } - mutating func addResponder(for method: HTTPRequest.Method, responder: any HBRequestResponder) { + mutating func addResponder(for method: HTTPRequest.Method, responder: any RequestResponder) { guard self.methods[method] == nil else { preconditionFailure("\(method.rawValue) already has a handler") } @@ -34,7 +34,7 @@ struct HBEndpointResponders: Sendable { mutating func autoGenerateHeadEndpoint() { if self.methods[.head] == nil, let get = methods[.get] { - self.methods[.head] = HBCallbackResponder { request, context in + self.methods[.head] = CallbackResponder { request, context in var response = try await get.respond(to: request, context: context) response.body = .init() return response @@ -42,6 +42,6 @@ struct HBEndpointResponders: Sendable { } } - var methods: [HTTPRequest.Method: any HBRequestResponder] + var methods: [HTTPRequest.Method: any RequestResponder] var path: String } diff --git a/Sources/Hummingbird/Router/Parameters+UUID.swift b/Sources/Hummingbird/Router/Parameters+UUID.swift index 95c72aecb..36c921925 100644 --- a/Sources/Hummingbird/Router/Parameters+UUID.swift +++ b/Sources/Hummingbird/Router/Parameters+UUID.swift @@ -15,8 +15,8 @@ import Foundation /// It is common for UUID's to be passed in as parameters. So lets add helper -/// functions to extract them from HBParameters -extension HBParameters { +/// functions to extract them from Parameters +extension Parameters { /// Return parameter with specified id as a certain type /// - Parameters: /// - s: parameter id @@ -33,7 +33,7 @@ extension HBParameters { guard let param = self[s[...]], let result = UUID(uuidString: String(param)) else { - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } return result } @@ -53,11 +53,11 @@ extension HBParameters { public func requireAll(_ s: String, as: UUID.Type) throws -> [UUID] { return try self[values: s[...]].map { guard let result = UUID(uuidString: String($0)) else { - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } return result } } } -extension UUID: HBResponseEncodable {} +extension UUID: ResponseEncodable {} diff --git a/Sources/Hummingbird/Router/Parameters.swift b/Sources/Hummingbird/Router/Parameters.swift index 0a4a20168..840c784bc 100644 --- a/Sources/Hummingbird/Router/Parameters.swift +++ b/Sources/Hummingbird/Router/Parameters.swift @@ -14,12 +14,12 @@ import HummingbirdCore -/// HBParameters is a special case of FlatDictionary where both the key +/// Parameters is a special case of FlatDictionary where both the key /// and value types are Substrings. It is used for parameters extracted /// from URIs -public typealias HBParameters = FlatDictionary +public typealias Parameters = FlatDictionary -public extension HBParameters { +public extension Parameters { /// Return parameter with specified id /// - Parameter s: parameter id func get(_ s: String) -> String? { @@ -46,7 +46,7 @@ public extension HBParameters { /// - Parameter s: parameter id func require(_ s: String) throws -> String { guard let param = self[s[...]].map({ String($0) }) else { - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } return param } @@ -59,7 +59,7 @@ public extension HBParameters { guard let param = self[s[...]], let result = T(String(param)) else { - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } return result } @@ -72,7 +72,7 @@ public extension HBParameters { guard let param = self[s[...]], let result = T(rawValue: String(param)) else { - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } return result } @@ -107,7 +107,7 @@ public extension HBParameters { func requireAll(_ s: String, as: T.Type) throws -> [T] { return try self[values: s[...]].map { guard let result = T(String($0)) else { - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } return result } @@ -120,7 +120,7 @@ public extension HBParameters { func requireAll(_ s: String, as: T.Type) throws -> [T] where T.RawValue == String { return try self[values: s[...]].map { guard let result = T(rawValue: String($0)) else { - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } return result } @@ -128,7 +128,7 @@ public extension HBParameters { } /// Catch all support -public extension HBParameters { +public extension Parameters { static let recursiveCaptureKey: Substring = ":**:" /// Return path elements caught by recursive capture diff --git a/Sources/Hummingbird/Router/ResponseGenerator.swift b/Sources/Hummingbird/Router/ResponseGenerator.swift index 712d2ca0d..f7441d41a 100644 --- a/Sources/Hummingbird/Router/ResponseGenerator.swift +++ b/Sources/Hummingbird/Router/ResponseGenerator.swift @@ -16,65 +16,65 @@ import HTTPTypes /// Object that can generate a `Response`. /// -/// This is used by `Router` to convert handler return values into a `HBResponse`. -public protocol HBResponseGenerator { +/// This is used by `Router` to convert handler return values into a `Response`. +public protocol ResponseGenerator { /// Generate response based on the request this object came from - func response(from request: HBRequest, context: some HBBaseRequestContext) throws -> HBResponse + func response(from request: Request, context: some BaseRequestContext) throws -> Response } /// Extend Response to conform to ResponseGenerator -extension HBResponse: HBResponseGenerator { +extension Response: ResponseGenerator { /// Return self as the response - public func response(from request: HBRequest, context: some HBBaseRequestContext) -> HBResponse { self } + public func response(from request: Request, context: some BaseRequestContext) -> Response { self } } /// Extend String to conform to ResponseGenerator -extension String: HBResponseGenerator { +extension String: ResponseGenerator { /// Generate response holding string - public func response(from request: HBRequest, context: some HBBaseRequestContext) -> HBResponse { + public func response(from request: Request, context: some BaseRequestContext) -> Response { let buffer = context.allocator.buffer(string: self) - return HBResponse(status: .ok, headers: [.contentType: "text/plain; charset=utf-8"], body: .init(byteBuffer: buffer)) + return Response(status: .ok, headers: [.contentType: "text/plain; charset=utf-8"], body: .init(byteBuffer: buffer)) } } /// Extend String to conform to ResponseGenerator -extension Substring: HBResponseGenerator { +extension Substring: ResponseGenerator { /// Generate response holding string - public func response(from request: HBRequest, context: some HBBaseRequestContext) -> HBResponse { + public func response(from request: Request, context: some BaseRequestContext) -> Response { let buffer = context.allocator.buffer(substring: self) - return HBResponse(status: .ok, headers: [.contentType: "text/plain; charset=utf-8"], body: .init(byteBuffer: buffer)) + return Response(status: .ok, headers: [.contentType: "text/plain; charset=utf-8"], body: .init(byteBuffer: buffer)) } } /// Extend ByteBuffer to conform to ResponseGenerator -extension ByteBuffer: HBResponseGenerator { +extension ByteBuffer: ResponseGenerator { /// Generate response holding bytebuffer - public func response(from request: HBRequest, context: some HBBaseRequestContext) -> HBResponse { - HBResponse(status: .ok, headers: [.contentType: "application/octet-stream"], body: .init(byteBuffer: self)) + public func response(from request: Request, context: some BaseRequestContext) -> Response { + Response(status: .ok, headers: [.contentType: "application/octet-stream"], body: .init(byteBuffer: self)) } } /// Extend HTTPResponseStatus to conform to ResponseGenerator -extension HTTPResponse.Status: HBResponseGenerator { +extension HTTPResponse.Status: ResponseGenerator { /// Generate response with this response status code - public func response(from request: HBRequest, context: some HBBaseRequestContext) -> HBResponse { - HBResponse(status: self, headers: [:], body: .init()) + public func response(from request: Request, context: some BaseRequestContext) -> Response { + Response(status: self, headers: [:], body: .init()) } } -/// Extend Optional to conform to HBResponseGenerator -extension Optional: HBResponseGenerator where Wrapped: HBResponseGenerator { - public func response(from request: HBRequest, context: some HBBaseRequestContext) throws -> HBResponse { +/// Extend Optional to conform to ResponseGenerator +extension Optional: ResponseGenerator where Wrapped: ResponseGenerator { + public func response(from request: Request, context: some BaseRequestContext) throws -> Response { switch self { case .some(let wrapped): return try wrapped.response(from: request, context: context) case .none: - return HBResponse(status: .noContent, headers: [:], body: .init()) + return Response(status: .noContent, headers: [:], body: .init()) } } } -public struct HBEditedResponse: HBResponseGenerator { +public struct EditedResponse: ResponseGenerator { public var status: HTTPResponse.Status? public var headers: HTTPFields public var responseGenerator: Generator @@ -89,7 +89,7 @@ public struct HBEditedResponse: HBResponseGenera self.responseGenerator = response } - public func response(from request: HBRequest, context: some HBBaseRequestContext) throws -> HBResponse { + public func response(from request: Request, context: some BaseRequestContext) throws -> Response { var response = try responseGenerator.response(from: request, context: context) if let status = self.status { response.status = status diff --git a/Sources/Hummingbird/Router/RouteHandler.swift b/Sources/Hummingbird/Router/RouteHandler.swift index efba9c07d..51e087f5a 100644 --- a/Sources/Hummingbird/Router/RouteHandler.swift +++ b/Sources/Hummingbird/Router/RouteHandler.swift @@ -20,7 +20,7 @@ import HTTPTypes /// create before handling the request. This allows you to separate the extraction of data /// from the request and the processing of the request. For example /// ``` -/// struct UpdateReminder: HBRouteHandler { +/// struct UpdateReminder: RouteHandler { /// struct Request: Codable { /// let description: String /// let date: Date @@ -28,26 +28,26 @@ import HTTPTypes /// let update: Request /// let id: String /// -/// init(from request: HBRequest, context: some HBBaseRequestContext) throws { +/// init(from request: Request, context: some BaseRequestContext) throws { /// self.update = try await request.decode(as: Request.self, context: context) /// self.id = try request.parameters.require("id") /// } -/// func handle(context: some HBBaseRequestContext) async throws -> HTTPResponse.Status { +/// func handle(context: some BaseRequestContext) async throws -> HTTPResponse.Status { /// let reminder = Reminder(id: id, update: update) /// return reminder.update(on: db) /// .map { _ in .ok } /// } /// } /// ``` -public protocol HBRouteHandler { +public protocol RouteHandler { associatedtype Output - init(from: HBRequest, context: some HBBaseRequestContext) async throws - func handle(context: some HBBaseRequestContext) async throws -> Output + init(from: Request, context: some BaseRequestContext) async throws + func handle(context: some BaseRequestContext) async throws -> Output } -extension HBRouterMethods { - /// Add path for `HBRouteHandler` that returns a value conforming to `HBResponseGenerator` - @discardableResult public func on( +extension RouterMethods { + /// Add path for `RouteHandler` that returns a value conforming to `ResponseGenerator` + @discardableResult public func on( _ path: String, method: HTTPRequest.Method, use handlerType: Handler.Type @@ -58,48 +58,48 @@ extension HBRouterMethods { } } - /// GET path for closure returning type conforming to HBResponseGenerator - @discardableResult public func get( + /// GET path for closure returning type conforming to ResponseGenerator + @discardableResult public func get( _ path: String = "", use handler: Handler.Type ) -> Self where Handler.Output == Output { return self.on(path, method: .get, use: handler) } - /// PUT path for closure returning type conforming to HBResponseGenerator - @discardableResult public func put( + /// PUT path for closure returning type conforming to ResponseGenerator + @discardableResult public func put( _ path: String = "", use handler: Handler.Type ) -> Self where Handler.Output == Output { return self.on(path, method: .put, use: handler) } - /// POST path for closure returning type conforming to HBResponseGenerator - @discardableResult public func post( + /// POST path for closure returning type conforming to ResponseGenerator + @discardableResult public func post( _ path: String = "", use handler: Handler.Type ) -> Self where Handler.Output == Output { return self.on(path, method: .post, use: handler) } - /// HEAD path for closure returning type conforming to HBResponseGenerator - @discardableResult public func head( + /// HEAD path for closure returning type conforming to ResponseGenerator + @discardableResult public func head( _ path: String = "", use handler: Handler.Type ) -> Self where Handler.Output == Output { return self.on(path, method: .head, use: handler) } - /// DELETE path for closure returning type conforming to HBResponseGenerator - @discardableResult public func delete( + /// DELETE path for closure returning type conforming to ResponseGenerator + @discardableResult public func delete( _ path: String = "", use handler: Handler.Type ) -> Self where Handler.Output == Output { return self.on(path, method: .delete, use: handler) } - /// PATCH path for closure returning type conforming to HBResponseGenerator - @discardableResult public func patch( + /// PATCH path for closure returning type conforming to ResponseGenerator + @discardableResult public func patch( _ path: String = "", use handler: Handler.Type ) -> Self where Handler.Output == Output { diff --git a/Sources/Hummingbird/Router/Router.swift b/Sources/Hummingbird/Router/Router.swift index a3c2126e6..9a7509fbf 100644 --- a/Sources/Hummingbird/Router/Router.swift +++ b/Sources/Hummingbird/Router/Router.swift @@ -16,12 +16,12 @@ import HTTPTypes import HummingbirdCore import NIOCore -/// Create rules for routing requests and then create `HBResponder` that will follow these rules. +/// Create rules for routing requests and then create `Responder` that will follow these rules. /// -/// `HBRouter` requires an implementation of the `on(path:method:use)` functions but because it -/// also conforms to `HBRouterMethods` it is also possible to call the method specific functions `get`, `put`, +/// `Router` requires an implementation of the `on(path:method:use)` functions but because it +/// also conforms to `RouterMethods` it is also possible to call the method specific functions `get`, `put`, /// `head`, `post` and `patch`. The route handler closures all return objects conforming to -/// `HBResponseGenerator`. This allows us to support routes which return a multitude of types eg +/// `ResponseGenerator`. This allows us to support routes which return a multitude of types eg /// ``` /// router.get("string") { _, _ -> String in /// return "string" @@ -34,21 +34,21 @@ import NIOCore /// } /// ``` /// -/// The default `Router` setup in `HBApplication` is the `TrieRouter` . This uses a +/// The default `Router` setup in `Application` is the `TrieRouter` . This uses a /// trie to partition all the routes for faster access. It also supports wildcards and parameter extraction /// ``` /// router.get("user/*", use: anyUser) /// router.get("user/:id", use: userWithId) /// ``` /// Both of these match routes which start with "/user" and the next path segment being anything. -/// The second version extracts the path segment out and adds it to `HBRequest.parameters` with the +/// The second version extracts the path segment out and adds it to `Request.parameters` with the /// key "id". -public final class HBRouter: HBRouterMethods, HBRequestResponderBuilder { - var trie: RouterPathTrieBuilder> - public let middlewares: HBMiddlewareGroup - let options: HBRouterOptions +public final class Router: RouterMethods, RequestResponderBuilder { + var trie: RouterPathTrieBuilder> + public let middlewares: MiddlewareGroup + let options: RouterOptions - public init(context: Context.Type = HBBasicRequestContext.self, options: HBRouterOptions = []) { + public init(context: Context.Type = BasicRequestContext.self, options: RouterOptions = []) { self.trie = RouterPathTrieBuilder() self.middlewares = .init() self.options = options @@ -59,22 +59,22 @@ public final class HBRouter: HBRouterMethods, HBR /// - path: URI path /// - method: http method /// - responder: handler to call - public func add(_ path: String, method: HTTPRequest.Method, responder: any HBRequestResponder) { + public func add(_ path: String, method: HTTPRequest.Method, responder: any RequestResponder) { // ensure path starts with a "/" and doesn't end with a "/" let path = "/\(path.dropSuffix("/").dropPrefix("/"))" - self.trie.addEntry(.init(path), value: HBEndpointResponders(path: path)) { node in + self.trie.addEntry(.init(path), value: EndpointResponders(path: path)) { node in node.value!.addResponder(for: method, responder: self.middlewares.constructResponder(finalResponder: responder)) } } /// build responder from router - public func buildResponder() -> HBRouterResponder { + public func buildResponder() -> RouterResponder { if self.options.contains(.autoGenerateHeadEndpoints) { self.trie.forEach { node in node.value?.autoGenerateHeadEndpoint() } } - return HBRouterResponder( + return RouterResponder( context: Context.self, trie: self.trie.build(), options: self.options, @@ -82,11 +82,11 @@ public final class HBRouter: HBRouterMethods, HBR ) } - /// Add path for closure returning type conforming to HBResponseGenerator + /// Add path for closure returning type conforming to ResponseGenerator @discardableResult public func on( _ path: String, method: HTTPRequest.Method, - use closure: @escaping @Sendable (HBRequest, Context) async throws -> some HBResponseGenerator + use closure: @escaping @Sendable (Request, Context) async throws -> some ResponseGenerator ) -> Self { let responder = constructResponder(use: closure) var path = path @@ -99,27 +99,27 @@ public final class HBRouter: HBRouterMethods, HBR /// return new `RouterGroup` /// - Parameter path: prefix to add to paths inside the group - public func group(_ path: String = "") -> HBRouterGroup { + public func group(_ path: String = "") -> RouterGroup { return .init(path: path, router: self) } } /// Responder that return a not found error -struct NotFoundResponder: HBRequestResponder { - func respond(to request: HBRequest, context: Context) throws -> HBResponse { - throw HBHTTPError(.notFound) +struct NotFoundResponder: RequestResponder { + func respond(to request: Request, context: Context) throws -> Response { + throw HTTPError(.notFound) } } /// A type that has a single method to build a responder -public protocol HBRequestResponderBuilder { - associatedtype Responder: HBRequestResponder +public protocol RequestResponderBuilder { + associatedtype Responder: RequestResponder /// build a responder func buildResponder() -> Responder } /// Router Options -public struct HBRouterOptions: OptionSet, Sendable { +public struct RouterOptions: OptionSet, Sendable { public let rawValue: Int public init(rawValue: Int) { diff --git a/Sources/Hummingbird/Router/RouterGroup.swift b/Sources/Hummingbird/Router/RouterGroup.swift index 957c95548..62829c6ad 100644 --- a/Sources/Hummingbird/Router/RouterGroup.swift +++ b/Sources/Hummingbird/Router/RouterGroup.swift @@ -19,7 +19,7 @@ import NIOCore /// Used to group together routes under a single path. Additional middleware can be added to the endpoint and each route can add a /// suffix to the endpoint path /// -/// The code below creates an `HBRouterGroup`with path "todos" and adds GET and PUT routes on "todos" and adds GET, PUT and +/// The code below creates an `RouterGroup`with path "todos" and adds GET and PUT routes on "todos" and adds GET, PUT and /// DELETE routes on "todos/:id" where id is the identifier for the todo /// ``` /// app.router @@ -30,27 +30,27 @@ import NIOCore /// .put(":id", use: todoController.update) /// .delete(":id", use: todoController.delete) /// ``` -public struct HBRouterGroup: HBRouterMethods { +public struct RouterGroup: RouterMethods { let path: String - let router: HBRouter - let middlewares: HBMiddlewareGroup + let router: Router + let middlewares: MiddlewareGroup - init(path: String = "", middlewares: HBMiddlewareGroup = .init(), router: HBRouter) { + init(path: String = "", middlewares: MiddlewareGroup = .init(), router: Router) { self.path = path self.router = router self.middlewares = middlewares } /// Add middleware to RouterEndpoint - @discardableResult public func add(middleware: any HBRouterMiddleware) -> HBRouterGroup { + @discardableResult public func add(middleware: any RouterMiddleware) -> RouterGroup { self.middlewares.add(middleware) return self } /// Return a group inside the current group /// - Parameter path: path prefix to add to routes inside this group - @discardableResult public func group(_ path: String = "") -> HBRouterGroup { - return HBRouterGroup( + @discardableResult public func group(_ path: String = "") -> RouterGroup { + return RouterGroup( path: self.combinePaths(self.path, path), middlewares: .init(middlewares: self.middlewares.middlewares), router: self.router @@ -61,7 +61,7 @@ public struct HBRouterGroup: HBRouterMethods { @discardableResult public func on( _ path: String = "", method: HTTPRequest.Method, - use closure: @Sendable @escaping (HBRequest, Context) async throws -> some HBResponseGenerator + use closure: @Sendable @escaping (Request, Context) async throws -> some ResponseGenerator ) -> Self { let responder = constructResponder(use: closure) var path = self.combinePaths(self.path, path) diff --git a/Sources/Hummingbird/Router/RouterMethods.swift b/Sources/Hummingbird/Router/RouterMethods.swift index 8ae895eac..89035183c 100644 --- a/Sources/Hummingbird/Router/RouterMethods.swift +++ b/Sources/Hummingbird/Router/RouterMethods.swift @@ -15,75 +15,75 @@ import HTTPTypes import NIOCore -/// Conform to `HBRouterMethods` to add standard router verb (get, post ...) methods -public protocol HBRouterMethods { - associatedtype Context: HBBaseRequestContext +/// Conform to `RouterMethods` to add standard router verb (get, post ...) methods +public protocol RouterMethods { + associatedtype Context: BaseRequestContext /// Add path for async closure @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) - @discardableResult func on( + @discardableResult func on( _ path: String, method: HTTPRequest.Method, - use: @Sendable @escaping (HBRequest, Context) async throws -> Output + use: @Sendable @escaping (Request, Context) async throws -> Output ) -> Self /// add group - func group(_ path: String) -> HBRouterGroup + func group(_ path: String) -> RouterGroup } -extension HBRouterMethods { - /// GET path for async closure returning type conforming to HBResponseGenerator +extension RouterMethods { + /// GET path for async closure returning type conforming to ResponseGenerator @discardableResult public func get( _ path: String = "", - use handler: @Sendable @escaping (HBRequest, Context) async throws -> some HBResponseGenerator + use handler: @Sendable @escaping (Request, Context) async throws -> some ResponseGenerator ) -> Self { return on(path, method: .get, use: handler) } - /// PUT path for async closure returning type conforming to HBResponseGenerator + /// PUT path for async closure returning type conforming to ResponseGenerator @discardableResult public func put( _ path: String = "", - use handler: @Sendable @escaping (HBRequest, Context) async throws -> some HBResponseGenerator + use handler: @Sendable @escaping (Request, Context) async throws -> some ResponseGenerator ) -> Self { return on(path, method: .put, use: handler) } - /// DELETE path for async closure returning type conforming to HBResponseGenerator + /// DELETE path for async closure returning type conforming to ResponseGenerator @discardableResult public func delete( _ path: String = "", - use handler: @Sendable @escaping (HBRequest, Context) async throws -> some HBResponseGenerator + use handler: @Sendable @escaping (Request, Context) async throws -> some ResponseGenerator ) -> Self { return on(path, method: .delete, use: handler) } - /// HEAD path for async closure returning type conforming to HBResponseGenerator + /// HEAD path for async closure returning type conforming to ResponseGenerator @discardableResult public func head( _ path: String = "", - use handler: @Sendable @escaping (HBRequest, Context) async throws -> some HBResponseGenerator + use handler: @Sendable @escaping (Request, Context) async throws -> some ResponseGenerator ) -> Self { return on(path, method: .head, use: handler) } - /// POST path for async closure returning type conforming to HBResponseGenerator + /// POST path for async closure returning type conforming to ResponseGenerator @discardableResult public func post( _ path: String = "", - use handler: @Sendable @escaping (HBRequest, Context) async throws -> some HBResponseGenerator + use handler: @Sendable @escaping (Request, Context) async throws -> some ResponseGenerator ) -> Self { return on(path, method: .post, use: handler) } - /// PATCH path for async closure returning type conforming to HBResponseGenerator + /// PATCH path for async closure returning type conforming to ResponseGenerator @discardableResult public func patch( _ path: String = "", - use handler: @Sendable @escaping (HBRequest, Context) async throws -> some HBResponseGenerator + use handler: @Sendable @escaping (Request, Context) async throws -> some ResponseGenerator ) -> Self { return on(path, method: .patch, use: handler) } func constructResponder( - use closure: @Sendable @escaping (HBRequest, Context) async throws -> some HBResponseGenerator - ) -> HBCallbackResponder { - return HBCallbackResponder { request, context in + use closure: @Sendable @escaping (Request, Context) async throws -> some ResponseGenerator + ) -> CallbackResponder { + return CallbackResponder { request, context in let output = try await closure(request, context) return try output.response(from: request, context: context) } diff --git a/Sources/Hummingbird/Router/RouterResponder.swift b/Sources/Hummingbird/Router/RouterResponder.swift index 4e6c35c6a..a10fd08c7 100644 --- a/Sources/Hummingbird/Router/RouterResponder.swift +++ b/Sources/Hummingbird/Router/RouterResponder.swift @@ -14,19 +14,19 @@ /// Directs requests to handlers based on the request uri and method. /// -/// Conforms to `HBResponder` so need to provide its own implementation of -/// `func respond(to request: HBRequest, context: Context) async throws -> HBResponse`. +/// Conforms to `Responder` so need to provide its own implementation of +/// `func respond(to request: Request, context: Context) async throws -> Response`. /// -public struct HBRouterResponder: HBRequestResponder { - let trie: RouterPathTrie> - let notFoundResponder: any HBRequestResponder - let options: HBRouterOptions +public struct RouterResponder: RequestResponder { + let trie: RouterPathTrie> + let notFoundResponder: any RequestResponder + let options: RouterOptions init( context: Context.Type, - trie: RouterPathTrie>, - options: HBRouterOptions, - notFoundResponder: any HBRequestResponder + trie: RouterPathTrie>, + options: RouterOptions, + notFoundResponder: any RequestResponder ) { self.trie = trie self.options = options @@ -36,7 +36,7 @@ public struct HBRouterResponder: HBRequestRespond /// Respond to request by calling correct handler /// - Parameter request: HTTP request /// - Returns: EventLoopFuture that will be fulfilled with the Response - public func respond(to request: HBRequest, context: Context) async throws -> HBResponse { + public func respond(to request: Request, context: Context) async throws -> Response { let path: String if self.options.contains(.caseInsensitive) { path = request.uri.path.lowercased() diff --git a/Sources/Hummingbird/Router/TrieRouter.swift b/Sources/Hummingbird/Router/TrieRouter.swift index 07b1a4ea5..99760cc23 100644 --- a/Sources/Hummingbird/Router/TrieRouter.swift +++ b/Sources/Hummingbird/Router/TrieRouter.swift @@ -93,7 +93,7 @@ struct RouterPathTrieBuilder { } } -/// Trie used by HBRouter responder +/// Trie used by Router responder struct RouterPathTrie: Sendable { let root: Node @@ -106,9 +106,9 @@ struct RouterPathTrie: Sendable { /// Get value from trie and any parameters from capture nodes /// - Parameter path: Path to process /// - Returns: value and parameters - func getValueAndParameters(_ path: String) -> (value: Value, parameters: HBParameters?)? { + func getValueAndParameters(_ path: String) -> (value: Value, parameters: Parameters?)? { let pathComponents = path.split(separator: "/", omittingEmptySubsequences: true) - var parameters: HBParameters? + var parameters: Parameters? var node = self.root for component in pathComponents { if let childNode = node.getChild(component) { @@ -161,7 +161,7 @@ struct RouterPathTrie: Sendable { } } -extension Optional { +extension Optional { fileprivate mutating func set(_ s: Substring, value: Substring) { switch self { case .some(var parameters): @@ -178,7 +178,7 @@ extension Optional { parameters.setCatchAll(value) self = .some(parameters) case .none: - self = .some(.init(.init([(HBParameters.recursiveCaptureKey, value)]))) + self = .some(.init(.init([(Parameters.recursiveCaptureKey, value)]))) } } } diff --git a/Sources/Hummingbird/Server/Request.swift b/Sources/Hummingbird/Server/Request.swift index 09cc38353..6195077cb 100644 --- a/Sources/Hummingbird/Server/Request.swift +++ b/Sources/Hummingbird/Server/Request.swift @@ -14,7 +14,7 @@ import HummingbirdCore -extension HBRequest { +extension Request { /// Collapse body into one ByteBuffer. /// /// This will store the collated ByteBuffer back into the request so is a mutating method. If @@ -23,33 +23,33 @@ extension HBRequest { /// /// - Parameter context: request context /// - Returns: Collated body - public mutating func collateBody(context: some HBBaseRequestContext) async throws -> ByteBuffer { + public mutating func collateBody(context: some BaseRequestContext) async throws -> ByteBuffer { let byteBuffer = try await self.body.collect(upTo: context.maxUploadSize) self.body = .init(buffer: byteBuffer) return byteBuffer } - /// Decode request using decoder stored at `HBApplication.decoder`. + /// Decode request using decoder stored at `Application.decoder`. /// - Parameter type: Type you want to decode to - public func decode(as type: Type.Type, context: some HBBaseRequestContext) async throws -> Type { + public func decode(as type: Type.Type, context: some BaseRequestContext) async throws -> Type { do { return try await context.requestDecoder.decode(type, from: self, context: context) } catch DecodingError.dataCorrupted(_) { let message = "The given data was not valid input." - throw HBHTTPError(.badRequest, message: message) + throw HTTPError(.badRequest, message: message) } catch DecodingError.keyNotFound(let key, _) { let path = key.pathKeyValue let message = "Coding key `\(path)` not found." - throw HBHTTPError(.badRequest, message: message) + throw HTTPError(.badRequest, message: message) } catch DecodingError.valueNotFound(_, let context) { let path = context.codingPath.pathKeyValue let message = "Value not found for `\(path)` key." - throw HBHTTPError(.badRequest, message: message) + throw HTTPError(.badRequest, message: message) } catch DecodingError.typeMismatch(let type, let context) { let path = context.codingPath.pathKeyValue let message = "Type mismatch for `\(path)` key, expected `\(type)` type." - throw HBHTTPError(.badRequest, message: message) - } catch let error as HBHTTPResponseError { + throw HTTPError(.badRequest, message: message) + } catch let error as HTTPResponseError { context.logger.debug("Decode Error: \(error)") throw error } diff --git a/Sources/Hummingbird/Server/RequestContext.swift b/Sources/Hummingbird/Server/RequestContext.swift index 8a80c13f8..5f5728a7d 100644 --- a/Sources/Hummingbird/Server/RequestContext.swift +++ b/Sources/Hummingbird/Server/RequestContext.swift @@ -34,7 +34,7 @@ public struct EndpointPath: Sendable { } /// Request context values required by Hummingbird itself. -public struct HBCoreRequestContext: Sendable { +public struct CoreRequestContext: Sendable { /// ByteBuffer allocator used by request @usableFromInline let allocator: ByteBufferAllocator @@ -44,7 +44,7 @@ public struct HBCoreRequestContext: Sendable { /// Endpoint path public var endpointPath: EndpointPath /// Parameters extracted from URI - public var parameters: HBParameters + public var parameters: Parameters @inlinable public init( @@ -60,12 +60,12 @@ public struct HBCoreRequestContext: Sendable { /// Protocol that all request contexts should conform to. Holds data associated with /// a request. Provides context for request processing -public protocol HBBaseRequestContext: Sendable { - associatedtype Decoder: HBRequestDecoder = JSONDecoder - associatedtype Encoder: HBResponseEncoder = JSONEncoder +public protocol BaseRequestContext: Sendable { + associatedtype Decoder: RequestDecoder = JSONDecoder + associatedtype Encoder: ResponseEncoder = JSONEncoder /// Core context - var coreContext: HBCoreRequestContext { get set } + var coreContext: CoreRequestContext { get set } /// Maximum upload size allowed for routes that don't stream the request payload. This /// limits how much memory would be used for one request var maxUploadSize: Int { get } @@ -75,7 +75,7 @@ public protocol HBBaseRequestContext: Sendable { var responseEncoder: Encoder { get } } -extension HBBaseRequestContext { +extension BaseRequestContext { @inlinable public var allocator: ByteBufferAllocator { coreContext.allocator } /// Logger to use with Request @@ -93,13 +93,13 @@ extension HBBaseRequestContext { public var endpointPath: String? { coreContext.endpointPath.value } /// Parameters extracted from URI @inlinable - public var parameters: HBParameters { coreContext.parameters } + public var parameters: Parameters { coreContext.parameters } /// Request ID, extracted from Logger @inlinable - public var id: String { self.logger[metadataKey: "hb_id"]!.description } + public var id: String { self.logger[metadataKey: "_id"]!.description } } -extension HBBaseRequestContext where Decoder == JSONDecoder { +extension BaseRequestContext where Decoder == JSONDecoder { public var requestDecoder: Decoder { let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 @@ -107,7 +107,7 @@ extension HBBaseRequestContext where Decoder == JSONDecoder { } } -extension HBBaseRequestContext where Encoder == JSONEncoder { +extension BaseRequestContext where Encoder == JSONEncoder { public var responseEncoder: Encoder { let encoder = JSONEncoder() encoder.dateEncodingStrategy = .iso8601 @@ -116,8 +116,8 @@ extension HBBaseRequestContext where Encoder == JSONEncoder { } /// Protocol for a request context that can be created from a NIO Channel -public protocol HBRequestContext: HBBaseRequestContext { - /// initialize an `HBRequestContext` +public protocol RequestContext: BaseRequestContext { + /// initialize an `RequestContext` /// - Parameters: /// - channel: Channel that initiated this request /// - logger: Logger used for this request @@ -125,11 +125,11 @@ public protocol HBRequestContext: HBBaseRequestContext { } /// Implementation of a basic request context that supports everything the Hummingbird library needs -public struct HBBasicRequestContext: HBRequestContext { +public struct BasicRequestContext: RequestContext { /// core context - public var coreContext: HBCoreRequestContext + public var coreContext: CoreRequestContext - /// Initialize an `HBRequestContext` + /// Initialize an `RequestContext` /// - Parameters: /// - allocator: Allocator /// - logger: Logger diff --git a/Sources/Hummingbird/Server/RequestResponder.swift b/Sources/Hummingbird/Server/RequestResponder.swift index 297e21cd2..204819035 100644 --- a/Sources/Hummingbird/Server/RequestResponder.swift +++ b/Sources/Hummingbird/Server/RequestResponder.swift @@ -18,21 +18,21 @@ import ServiceContextModule /// Protocol for object that produces a response given a request /// /// This is the core protocol for Hummingbird. It defines an object that can respond to a request. -public protocol HBRequestResponder: Sendable { +public protocol RequestResponder: Sendable { associatedtype Context /// Return response to the request supplied - @Sendable func respond(to request: HBRequest, context: Context) async throws -> HBResponse + @Sendable func respond(to request: Request, context: Context) async throws -> Response } /// Responder that calls supplied closure -public struct HBCallbackResponder: HBRequestResponder { - let callback: @Sendable (HBRequest, Context) async throws -> HBResponse +public struct CallbackResponder: RequestResponder { + let callback: @Sendable (Request, Context) async throws -> Response - public init(callback: @escaping @Sendable (HBRequest, Context) async throws -> HBResponse) { + public init(callback: @escaping @Sendable (Request, Context) async throws -> Response) { self.callback = callback } - public func respond(to request: HBRequest, context: Context) async throws -> HBResponse { + public func respond(to request: Request, context: Context) async throws -> Response { try await self.callback(request, context) } } diff --git a/Sources/Hummingbird/Server/Response.swift b/Sources/Hummingbird/Server/Response.swift index 4f535bf56..48a587ff1 100644 --- a/Sources/Hummingbird/Server/Response.swift +++ b/Sources/Hummingbird/Server/Response.swift @@ -14,7 +14,7 @@ import HummingbirdCore -extension HBResponse { +extension Response { /// Specifies the type of redirect that the client should receive. public enum RedirectType { /// `301 moved permanently`: The URL of the requested resource has been changed permanently. @@ -49,8 +49,8 @@ extension HBResponse { /// - Parameters: /// - location: Location to redirect to /// - type: Redirection type - /// - Returns: HBResponse with redirection - public static func redirect(to location: String, type: RedirectType = .normal) -> HBResponse { + /// - Returns: Response with redirection + public static func redirect(to location: String, type: RedirectType = .normal) -> Response { return .init(status: type.status, headers: [.location: location]) } } diff --git a/Sources/Hummingbird/Storage/MemoryPersistDriver.swift b/Sources/Hummingbird/Storage/MemoryPersistDriver.swift index 54c375096..af2222bb9 100644 --- a/Sources/Hummingbird/Storage/MemoryPersistDriver.swift +++ b/Sources/Hummingbird/Storage/MemoryPersistDriver.swift @@ -17,14 +17,14 @@ import Atomics import NIOCore /// In memory driver for persist system for storing persistent cross request key/value pairs -public actor HBMemoryPersistDriver: HBPersistDriver where C.Duration == Duration { +public actor MemoryPersistDriver: PersistDriver where C.Duration == Duration { public init(_ clock: C = .suspending) { self.values = [:] self.clock = clock } public func create(key: String, value: some Codable & Sendable, expires: Duration?) async throws { - guard self.values[key] == nil else { throw HBPersistError.duplicate } + guard self.values[key] == nil else { throw PersistError.duplicate } self.values[key] = .init(value: value, expires: expires.map { self.clock.now.advanced(by: $0) }) } diff --git a/Sources/Hummingbird/Storage/PersistDriver.swift b/Sources/Hummingbird/Storage/PersistDriver.swift index b928e3112..fffbfe5f0 100644 --- a/Sources/Hummingbird/Storage/PersistDriver.swift +++ b/Sources/Hummingbird/Storage/PersistDriver.swift @@ -16,11 +16,11 @@ import NIOCore import ServiceLifecycle /// Protocol for driver supporting persistent Key/Value pairs across requests -public protocol HBPersistDriver: Service { +public protocol PersistDriver: Service { /// shutdown driver func shutdown() async throws - /// create key/value pair. If key already exist throw `HBPersistError.duplicate` error + /// create key/value pair. If key already exist throw `PersistError.duplicate` error /// - Parameters: /// - key: Key to store value against /// - value: Codable value to store @@ -46,11 +46,11 @@ public protocol HBPersistDriver: Service { func remove(key: String) async throws } -extension HBPersistDriver { +extension PersistDriver { /// default implemenation of shutdown() public func shutdown() async throws {} - /// create key/value pair. If key already exist throw `HBPersistError.duplicate` error + /// create key/value pair. If key already exist throw `PersistError.duplicate` error /// - Parameters: /// - key: Key to store value against /// - value: Codable value to store diff --git a/Sources/Hummingbird/Storage/PersistError.swift b/Sources/Hummingbird/Storage/PersistError.swift index 614ced451..7731df64b 100644 --- a/Sources/Hummingbird/Storage/PersistError.swift +++ b/Sources/Hummingbird/Storage/PersistError.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// /// Errors return by persist framework -public struct HBPersistError: Error, Equatable { +public struct PersistError: Error, Equatable { private enum Internal { case duplicate } diff --git a/Sources/Hummingbird/Utils/DateCache+Date.swift b/Sources/Hummingbird/Utils/DateCache+Date.swift index bbda47cff..6db82f87d 100644 --- a/Sources/Hummingbird/Utils/DateCache+Date.swift +++ b/Sources/Hummingbird/Utils/DateCache+Date.swift @@ -14,7 +14,7 @@ import Foundation -extension HBDateCache { +extension DateCache { /// Date formatter as per section 5.2.14 of RFC 1123 /// https://www.rfc-editor.org/rfc/rfc1123#page-55 static var rfc1123Formatter: DateFormatter { diff --git a/Sources/Hummingbird/Utils/DateCache.swift b/Sources/Hummingbird/Utils/DateCache.swift index 5701f6fc4..ad2eed698 100644 --- a/Sources/Hummingbird/Utils/DateCache.swift +++ b/Sources/Hummingbird/Utils/DateCache.swift @@ -27,7 +27,7 @@ import ServiceLifecycle /// /// Getting the current date formatted is an expensive operation. This creates a task that will /// update a cached version of the date in the format as detailed in RFC1123 once every second. -public final class HBDateCache: Service { +public final class DateCache: Service { final class DateContainer: AtomicReference, Sendable { let date: String diff --git a/Sources/HummingbirdCore/Client/ClientChannel.swift b/Sources/HummingbirdCore/Client/ClientChannel.swift index b204aa70c..fa62299a0 100644 --- a/Sources/HummingbirdCore/Client/ClientChannel.swift +++ b/Sources/HummingbirdCore/Client/ClientChannel.swift @@ -15,8 +15,8 @@ import Logging import NIOCore -/// HBClientConnection child channel setup protocol -public protocol HBClientConnectionChannel: Sendable { +/// ClientConnection child channel setup protocol +public protocol ClientConnectionChannel: Sendable { associatedtype Value: Sendable /// Setup child channel diff --git a/Sources/HummingbirdCore/Client/ClientConnection.swift b/Sources/HummingbirdCore/Client/ClientConnection.swift index 0bff504ee..6db2d5c4a 100644 --- a/Sources/HummingbirdCore/Client/ClientConnection.swift +++ b/Sources/HummingbirdCore/Client/ClientConnection.swift @@ -24,13 +24,13 @@ import NIOTransportServices /// A generic client connection to a server. /// /// Actual client protocol is implemented in `ClientChannel` generic parameter -public struct HBClientConnection: Sendable { +public struct ClientConnection: Sendable { typealias ChannelResult = ClientChannel.Value /// Logger used by Server let logger: Logger let eventLoopGroup: EventLoopGroup let clientChannel: ClientChannel - let address: HBAddress + let address: Address #if canImport(Network) let tlsOptions: NWProtocolTLS.Options? #endif @@ -38,7 +38,7 @@ public struct HBClientConnection: Send /// Initialize Client public init( _ clientChannel: ClientChannel, - address: HBAddress, + address: Address, eventLoopGroup: EventLoopGroup = MultiThreadedEventLoopGroup.singleton, logger: Logger ) { @@ -55,7 +55,7 @@ public struct HBClientConnection: Send /// Initialize Client with TLS options public init( _ clientChannel: ClientChannel, - address: HBAddress, + address: Address, transportServicesTLSOptions: TSTLSOptions, eventLoopGroup: EventLoopGroup = MultiThreadedEventLoopGroup.singleton, logger: Logger @@ -77,7 +77,7 @@ public struct HBClientConnection: Send } /// Connect to server - func makeClient(clientChannel: ClientChannel, address: HBAddress) async throws -> ChannelResult { + func makeClient(clientChannel: ClientChannel, address: Address) async throws -> ChannelResult { // get bootstrap let bootstrap: ClientBootstrapProtocol #if canImport(Network) diff --git a/Sources/HummingbirdCore/Error/HTTPError.swift b/Sources/HummingbirdCore/Error/HTTPError.swift index d8e6a7fa2..4f564123a 100644 --- a/Sources/HummingbirdCore/Error/HTTPError.swift +++ b/Sources/HummingbirdCore/Error/HTTPError.swift @@ -16,7 +16,7 @@ import HTTPTypes import NIOCore /// Default HTTP error. Provides an HTTP status and a message is so desired -public struct HBHTTPError: Error, HBHTTPResponseError, Sendable { +public struct HTTPError: Error, HTTPResponseError, Sendable { /// status code for the error public var status: HTTPResponse.Status /// any addiitional headers required @@ -49,7 +49,7 @@ public struct HBHTTPError: Error, HBHTTPResponseError, Sendable { } } -extension HBHTTPError: CustomStringConvertible { +extension HTTPError: CustomStringConvertible { /// Description of error for logging public var description: String { let status = self.status.reasonPhrase diff --git a/Sources/HummingbirdCore/Error/HTTPErrorResponse.swift b/Sources/HummingbirdCore/Error/HTTPErrorResponse.swift index 0bdfda4c8..eecf4cb66 100644 --- a/Sources/HummingbirdCore/Error/HTTPErrorResponse.swift +++ b/Sources/HummingbirdCore/Error/HTTPErrorResponse.swift @@ -17,9 +17,9 @@ import NIOCore /// An error that is capable of generating an HTTP response /// -/// By conforming to `HBHTTPResponseError` you can control how your error will be presented to +/// By conforming to `HTTPResponseError` you can control how your error will be presented to /// the client. Errors not conforming to this will be returned with status internalServerError. -public protocol HBHTTPResponseError: Error { +public protocol HTTPResponseError: Error { /// status code for the error var status: HTTPResponse.Status { get } /// any addiitional headers required @@ -28,12 +28,12 @@ public protocol HBHTTPResponseError: Error { func body(allocator: ByteBufferAllocator) -> ByteBuffer? } -extension HBHTTPResponseError { +extension HTTPResponseError { /// Generate response from error /// - Parameter allocator: Byte buffer allocator used to allocate message body /// - Returns: Response - public func response(allocator: ByteBufferAllocator) -> HBResponse { - let body: HBResponseBody + public func response(allocator: ByteBufferAllocator) -> Response { + let body: ResponseBody if let buffer = self.body(allocator: allocator) { body = .init(byteBuffer: buffer) } else { diff --git a/Sources/HummingbirdCore/Request/Request.swift b/Sources/HummingbirdCore/Request/Request.swift index 95ffc3bc2..f1cb914b1 100644 --- a/Sources/HummingbirdCore/Request/Request.swift +++ b/Sources/HummingbirdCore/Request/Request.swift @@ -15,15 +15,15 @@ import HTTPTypes /// Holds all the values required to process a request -public struct HBRequest: Sendable { +public struct Request: Sendable { // MARK: Member variables /// URI path - public let uri: HBURI + public let uri: URI /// HTTP head public let head: HTTPRequest /// Body of HTTP request - public var body: HBRequestBody + public var body: RequestBody /// Request HTTP method public var method: HTTPRequest.Method { self.head.method } /// Request HTTP headers @@ -31,14 +31,14 @@ public struct HBRequest: Sendable { // MARK: Initialization - /// Create new HBRequest + /// Create new Request /// - Parameters: /// - head: HTTP head /// - body: HTTP body /// - id: Unique RequestID public init( head: HTTPRequest, - body: HBRequestBody + body: RequestBody ) { self.uri = .init(head.path ?? "") self.head = head @@ -46,7 +46,7 @@ public struct HBRequest: Sendable { } } -extension HBRequest: CustomStringConvertible { +extension Request: CustomStringConvertible { public var description: String { "uri: \(self.uri), method: \(self.method), headers: \(self.headers), body: \(self.body)" } diff --git a/Sources/HummingbirdCore/Request/RequestBody.swift b/Sources/HummingbirdCore/Request/RequestBody.swift index bc4c2d226..9461fdc49 100644 --- a/Sources/HummingbirdCore/Request/RequestBody.swift +++ b/Sources/HummingbirdCore/Request/RequestBody.swift @@ -20,7 +20,7 @@ import NIOHTTPTypes /// Request Body /// /// Can be either a stream of ByteBuffers or a single ByteBuffer -public struct HBRequestBody: Sendable, AsyncSequence { +public struct RequestBody: Sendable, AsyncSequence { @usableFromInline internal enum _Backing: Sendable { case byteBuffer(ByteBuffer) @@ -35,7 +35,7 @@ public struct HBRequestBody: Sendable, AsyncSequence { self._backing = backing } - /// Initialise ``HBRequestBody`` from ByteBuffer + /// Initialise ``RequestBody`` from ByteBuffer /// - Parameter buffer: ByteBuffer public init(buffer: ByteBuffer) { self.init(.byteBuffer(buffer)) @@ -48,7 +48,7 @@ public struct HBRequestBody: Sendable, AsyncSequence { } /// AsyncSequence protocol requirements -extension HBRequestBody { +extension RequestBody { public typealias Element = ByteBuffer public struct AsyncIterator: AsyncIteratorProtocol { @@ -77,8 +77,8 @@ extension HBRequestBody { } } -/// Extend HBRequestBody to create request body streams backed by `NIOThrowingAsyncSequenceProducer`. -extension HBRequestBody { +/// Extend RequestBody to create request body streams backed by `NIOThrowingAsyncSequenceProducer`. +extension RequestBody { @usableFromInline typealias Producer = NIOThrowingAsyncSequenceProducer< ByteBuffer, @@ -125,7 +125,7 @@ extension HBRequestBody { } } - /// A source used for driving a ``HBRequestBody`` stream. + /// A source used for driving a ``RequestBody`` stream. public final class Source { @usableFromInline let source: Producer.Source @@ -176,10 +176,10 @@ extension HBRequestBody { } } - /// Make a new ``HBRequestBody`` stream - /// - Returns: The new `HBRequestBody` and a source to yield ByteBuffers to the `HBRequestBody`. + /// Make a new ``RequestBody`` stream + /// - Returns: The new `RequestBody` and a source to yield ByteBuffers to the `RequestBody`. @inlinable - public static func makeStream() -> (HBRequestBody, Source) { + public static func makeStream() -> (RequestBody, Source) { let delegate = Delegate() let newSequence = Producer.makeSequence( backPressureStrategy: .init(lowWatermark: 2, highWatermark: 4), diff --git a/Sources/HummingbirdCore/Request/URI.swift b/Sources/HummingbirdCore/Request/URI.swift index 4d7fbc546..b7c0d582d 100644 --- a/Sources/HummingbirdCore/Request/URI.swift +++ b/Sources/HummingbirdCore/Request/URI.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// /// Simple URL parser -public struct HBURI: Sendable, CustomStringConvertible, ExpressibleByStringLiteral { +public struct URI: Sendable, CustomStringConvertible, ExpressibleByStringLiteral { public struct Scheme: RawRepresentable, Equatable { public let rawValue: String @@ -47,7 +47,7 @@ public struct HBURI: Sendable, CustomStringConvertible, ExpressibleByStringLiter guard var query = _query else { return .init() } - let queries: [HBParser] = query.split(separator: "&") + let queries: [Parser] = query.split(separator: "&") let queryKeyValues = queries.map { query -> (key: Substring, value: Substring) in do { var query = query @@ -66,15 +66,15 @@ public struct HBURI: Sendable, CustomStringConvertible, ExpressibleByStringLiter return .init(queryKeyValues) } - private let _scheme: HBParser? - private let _host: HBParser? - private let _port: HBParser? - private let _path: HBParser? - private let _query: HBParser? + private let _scheme: Parser? + private let _host: Parser? + private let _port: Parser? + private let _path: Parser? + private let _query: Parser? public var description: String { self.string } - /// Initialize `HBURI` from `String` + /// Initialize `URI` from `String` /// - Parameter string: input string public init(_ string: String) { enum ParsingState { @@ -85,17 +85,17 @@ public struct HBURI: Sendable, CustomStringConvertible, ExpressibleByStringLiter case readingQuery case finished } - var scheme: HBParser? - var host: HBParser? - var port: HBParser? - var path: HBParser? - var query: HBParser? + var scheme: Parser? + var host: Parser? + var port: Parser? + var path: Parser? + var query: Parser? var state: ParsingState = .readingScheme if string.first == "/" { state = .readingPath } - var parser = HBParser(string) + var parser = Parser(string) while state != .finished { if parser.reachedEnd() { break } switch state { diff --git a/Sources/HummingbirdCore/Response/Response.swift b/Sources/HummingbirdCore/Response/Response.swift index 9a649f183..f6d143576 100644 --- a/Sources/HummingbirdCore/Response/Response.swift +++ b/Sources/HummingbirdCore/Response/Response.swift @@ -15,11 +15,11 @@ import HTTPTypes /// Holds all the required to generate a HTTP Response -public struct HBResponse: Sendable { +public struct Response: Sendable { public var head: HTTPResponse - public var body: HBResponseBody + public var body: ResponseBody - public init(status: HTTPResponse.Status, headers: HTTPFields = .init(), body: HBResponseBody = .init()) { + public init(status: HTTPResponse.Status, headers: HTTPFields = .init(), body: ResponseBody = .init()) { self.head = .init(status: status, headerFields: headers) self.body = body if let contentLength = body.contentLength, headers[.contentLength] == nil { @@ -38,7 +38,7 @@ public struct HBResponse: Sendable { } } -extension HBResponse: CustomStringConvertible { +extension Response: CustomStringConvertible { public var description: String { "status: \(self.status), headers: \(self.headers), body: \(self.body)" } diff --git a/Sources/HummingbirdCore/Response/ResponseBody.swift b/Sources/HummingbirdCore/Response/ResponseBody.swift index 821f34986..6f7cdd3b2 100644 --- a/Sources/HummingbirdCore/Response/ResponseBody.swift +++ b/Sources/HummingbirdCore/Response/ResponseBody.swift @@ -15,30 +15,30 @@ import HTTPTypes import NIOCore -public protocol HBResponseBodyWriter { +public protocol ResponseBodyWriter { func write(_ buffer: ByteBuffer) async throws } /// Response body -public struct HBResponseBody: Sendable { - public let write: @Sendable (any HBResponseBodyWriter) async throws -> HTTPFields? +public struct ResponseBody: Sendable { + public let write: @Sendable (any ResponseBodyWriter) async throws -> HTTPFields? public let contentLength: Int? - /// Initialise HBResponseBody with closure writing body contents + /// Initialise ResponseBody with closure writing body contents /// - Parameters: /// - contentLength: Optional length of body /// - write: closure provided with `writer` type that can be used to write to response body - public init(contentLength: Int? = nil, _ write: @Sendable @escaping (any HBResponseBodyWriter) async throws -> Void) { + public init(contentLength: Int? = nil, _ write: @Sendable @escaping (any ResponseBodyWriter) async throws -> Void) { self.write = { try await write($0); return nil } self.contentLength = contentLength } - /// Initialise empty HBResponseBody + /// Initialise empty ResponseBody public init() { self.init(contentLength: 0) { _ in } } - /// Initialise HBResponseBody that contains a single ByteBuffer + /// Initialise ResponseBody that contains a single ByteBuffer /// - Parameter byteBuffer: ByteBuffer to write public init(byteBuffer: ByteBuffer) { self.init(contentLength: byteBuffer.readableBytes) { writer in @@ -46,7 +46,7 @@ public struct HBResponseBody: Sendable { } } - /// Initialise HBResponseBody with an AsyncSequence of ByteBuffers + /// Initialise ResponseBody with an AsyncSequence of ByteBuffers /// - Parameter asyncSequence: ByteBuffer AsyncSequence public init(asyncSequence: BufferSequence) where BufferSequence.Element == ByteBuffer { self.init { writer in @@ -57,7 +57,7 @@ public struct HBResponseBody: Sendable { } } - /// Create HBResponseBody that returns trailing headers from its closure once all the + /// Create ResponseBody that returns trailing headers from its closure once all the /// body parts have been written /// - Parameters: /// - contentLength: Optional length of body @@ -66,16 +66,16 @@ public struct HBResponseBody: Sendable { /// written public static func withTrailingHeaders( contentLength: Int? = nil, - _ write: @Sendable @escaping (any HBResponseBodyWriter) async throws -> HTTPFields? + _ write: @Sendable @escaping (any ResponseBodyWriter) async throws -> HTTPFields? ) -> Self { self.init(contentLength: contentLength, write: write) } - /// Initialise HBResponseBody with closure writing body contents + /// Initialise ResponseBody with closure writing body contents /// /// This version of init is private and only available via ``withTrailingHeaders`` because /// if it is public the compiler gets confused when a complex closure is provided. - private init(contentLength: Int? = nil, write: @Sendable @escaping (any HBResponseBodyWriter) async throws -> HTTPFields?) { + private init(contentLength: Int? = nil, write: @Sendable @escaping (any ResponseBodyWriter) async throws -> HTTPFields?) { self.write = { return try await write($0) } self.contentLength = contentLength } diff --git a/Sources/HummingbirdCore/Server/Address.swift b/Sources/HummingbirdCore/Server/Address.swift index 64354bd89..2ca91b158 100644 --- a/Sources/HummingbirdCore/Server/Address.swift +++ b/Sources/HummingbirdCore/Server/Address.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// /// Address to bind server to -public struct HBAddress: Sendable, Equatable { +public struct Address: Sendable, Equatable { enum _Internal: Equatable { case hostname(_ host: String = "127.0.0.1", port: Int = 8080) case unixDomainSocket(path: String) diff --git a/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift b/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift index 24c5812c6..293a9f5c9 100644 --- a/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift +++ b/Sources/HummingbirdCore/Server/HTTP/HTTP1Channel.swift @@ -19,7 +19,7 @@ import NIOHTTPTypes import NIOHTTPTypesHTTP1 /// Child channel for processing HTTP1 -public struct HTTP1Channel: HBServerChildChannel, HTTPChannelHandler { +public struct HTTP1Channel: ServerChildChannel, HTTPChannelHandler { public typealias Value = NIOAsyncChannel /// Initialize HTTP1Channel @@ -27,7 +27,7 @@ public struct HTTP1Channel: HBServerChildChannel, HTTPChannelHandler { /// - responder: Function returning a HTTP response for a HTTP request /// - additionalChannelHandlers: Additional channel handlers to add to channel pipeline public init( - responder: @escaping @Sendable (HBRequest, Channel) async throws -> HBResponse, + responder: @escaping @Sendable (Request, Channel) async throws -> Response, additionalChannelHandlers: @escaping @Sendable () -> [any RemovableChannelHandler] = { [] } ) { self.additionalChannelHandlers = additionalChannelHandlers @@ -43,7 +43,7 @@ public struct HTTP1Channel: HBServerChildChannel, HTTPChannelHandler { let childChannelHandlers: [any ChannelHandler] = [HTTP1ToHTTPServerCodec(secure: false)] + self.additionalChannelHandlers() + - [HBHTTPUserEventHandler(logger: logger)] + [HTTPUserEventHandler(logger: logger)] return channel.eventLoop.makeCompletedFuture { try channel.pipeline.syncOperations.configureHTTPServerPipeline( withPipeliningAssistance: false, @@ -65,6 +65,6 @@ public struct HTTP1Channel: HBServerChildChannel, HTTPChannelHandler { await handleHTTP(asyncChannel: asyncChannel, logger: logger) } - public let responder: @Sendable (HBRequest, Channel) async throws -> HBResponse + public let responder: @Sendable (Request, Channel) async throws -> Response let additionalChannelHandlers: @Sendable () -> [any RemovableChannelHandler] } diff --git a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelBuilder.swift b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelBuilder.swift index 4c8b85633..6a5291d23 100644 --- a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelBuilder.swift +++ b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelBuilder.swift @@ -16,25 +16,25 @@ import NIOCore /// Build Channel Setup that takes an HTTP responder /// -/// Used when building an ``Hummingbird/HBApplication``. It delays the building -/// of the ``HBChildChannel`` until the HTTP responder has been built. -public struct HBHTTPChannelBuilder: Sendable { +/// Used when building an ``Hummingbird/Application``. It delays the building +/// of the ``ChildChannel`` until the HTTP responder has been built. +public struct HTTPChannelBuilder: Sendable { /// build child channel from HTTP responder public let build: @Sendable (@escaping HTTPChannelHandler.Responder) throws -> ChildChannel - /// Initialize HBHTTPChannelBuilder + /// Initialize HTTPChannelBuilder /// - Parameter build: closure building child channel from HTTP responder public init(_ build: @escaping @Sendable (@escaping HTTPChannelHandler.Responder) throws -> ChildChannel) { self.build = build } } -extension HBHTTPChannelBuilder { +extension HTTPChannelBuilder { /// Build HTTP1 channel /// - /// Use in ``Hummingbird/HBApplication`` initialization. + /// Use in ``Hummingbird/Application`` initialization. /// ``` - /// let app = HBApplication( + /// let app = Application( /// router: router, /// server: .http1() /// ) @@ -43,7 +43,7 @@ extension HBHTTPChannelBuilder { /// - Returns: HTTPChannelHandler builder public static func http1( additionalChannelHandlers: @autoclosure @escaping @Sendable () -> [any RemovableChannelHandler] = [] - ) -> HBHTTPChannelBuilder { + ) -> HTTPChannelBuilder { return .init { responder in return HTTP1Channel(responder: responder, additionalChannelHandlers: additionalChannelHandlers) } diff --git a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift index 11759b3a8..0418b5e70 100644 --- a/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift +++ b/Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift @@ -20,8 +20,8 @@ import NIOHTTPTypes import ServiceLifecycle /// Protocol for HTTP channels -public protocol HTTPChannelHandler: HBServerChildChannel { - typealias Responder = @Sendable (HBRequest, Channel) async throws -> HBResponse +public protocol HTTPChannelHandler: ServerChildChannel { + typealias Responder = @Sendable (Request, Channel) async throws -> Response var responder: Responder { get } } @@ -46,7 +46,7 @@ extension HTTPChannelHandler { try await withTaskCancellationHandler { try await withGracefulShutdownHandler { try await asyncChannel.executeThenClose { inbound, outbound in - let responseWriter = HBHTTPServerBodyWriter(outbound: outbound) + let responseWriter = HTTPServerBodyWriter(outbound: outbound) var iterator = inbound.makeAsyncIterator() // read first part, verify it is a head @@ -60,8 +60,8 @@ extension HTTPChannelHandler { guard processingRequest.exchange(.processing) == .idle else { break } let bodyStream = NIOAsyncChannelRequestBody(iterator: iterator) - let request = HBRequest(head: head, body: .init(asyncSequence: bodyStream)) - let response: HBResponse + let request = Request(head: head, body: .init(asyncSequence: bodyStream)) + let response: Response do { response = try await self.responder(request, asyncChannel.channel) } catch { @@ -120,14 +120,14 @@ extension HTTPChannelHandler { } } - func getErrorResponse(from error: Error, allocator: ByteBufferAllocator) -> HBResponse { + func getErrorResponse(from error: Error, allocator: ByteBufferAllocator) -> Response { switch error { - case let httpError as HBHTTPResponseError: + case let httpError as HTTPResponseError: // this is a processed error so don't log as Error return httpError.response(allocator: allocator) default: // this error has not been recognised - return HBResponse( + return Response( status: .internalServerError, body: .init() ) @@ -136,7 +136,7 @@ extension HTTPChannelHandler { } /// Writes ByteBuffers to AsyncChannel outbound writer -struct HBHTTPServerBodyWriter: Sendable, HBResponseBodyWriter { +struct HTTPServerBodyWriter: Sendable, ResponseBodyWriter { typealias Out = HTTPResponsePart /// The components of a HTTP response from the view of a HTTP server. public typealias OutboundWriter = NIOAsyncChannelOutboundWriter @@ -149,7 +149,7 @@ struct HBHTTPServerBodyWriter: Sendable, HBResponseBodyWriter { } // If we catch a too many bytes error report that as payload too large -extension NIOTooManyBytesError: HBHTTPResponseError { +extension NIOTooManyBytesError: HTTPResponseError { public var status: HTTPResponse.Status { .contentTooLarge } public var headers: HTTPFields { [:] } public func body(allocator: ByteBufferAllocator) -> ByteBuffer? { nil } diff --git a/Sources/HummingbirdCore/Server/HTTPUserEventHandler.swift b/Sources/HummingbirdCore/Server/HTTPUserEventHandler.swift index 7aac8e100..2bf22b5a6 100644 --- a/Sources/HummingbirdCore/Server/HTTPUserEventHandler.swift +++ b/Sources/HummingbirdCore/Server/HTTPUserEventHandler.swift @@ -16,7 +16,7 @@ import Logging import NIOCore import NIOHTTPTypes -public class HBHTTPUserEventHandler: ChannelDuplexHandler, RemovableChannelHandler { +public class HTTPUserEventHandler: ChannelDuplexHandler, RemovableChannelHandler { public typealias InboundIn = HTTPRequestPart public typealias InboundOut = HTTPRequestPart public typealias OutboundIn = HTTPResponsePart diff --git a/Sources/HummingbirdCore/Server/Server.swift b/Sources/HummingbirdCore/Server/Server.swift index 00d5cf703..aa4de6bac 100644 --- a/Sources/HummingbirdCore/Server/Server.swift +++ b/Sources/HummingbirdCore/Server/Server.swift @@ -23,13 +23,13 @@ import NIOTransportServices import ServiceLifecycle /// HTTP server class -public actor HBServer: Service { +public actor Server: Service { public typealias AsyncChildChannel = ChildChannel.Value public typealias AsyncServerChannel = NIOAsyncChannel enum State: CustomStringConvertible { case initial( childChannelSetup: ChildChannel, - configuration: HBServerConfiguration, + configuration: ServerConfiguration, onServerRunning: (@Sendable (Channel) async -> Void)? ) case starting @@ -73,7 +73,7 @@ public actor HBServer: Service { /// - configuration: Configuration for server public init( childChannelSetup: ChildChannel, - configuration: HBServerConfiguration, + configuration: ServerConfiguration, onServerRunning: (@Sendable (Channel) async -> Void)? = { _ in }, eventLoopGroup: EventLoopGroup, logger: Logger @@ -176,7 +176,7 @@ public actor HBServer: Service { /// Start server /// - Parameter responder: Object that provides responses to requests sent to the server /// - Returns: EventLoopFuture that is fulfilled when server has started - nonisolated func makeServer(childChannelSetup: ChildChannel, configuration: HBServerConfiguration) async throws -> AsyncServerChannel { + nonisolated func makeServer(childChannelSetup: ChildChannel, configuration: ServerConfiguration) async throws -> AsyncServerChannel { let bootstrap: ServerBootstrapProtocol #if canImport(Network) if let tsBootstrap = self.createTSBootstrap(configuration: configuration) { @@ -234,7 +234,7 @@ public actor HBServer: Service { /// create a BSD sockets based bootstrap private nonisolated func createSocketsBootstrap( - configuration: HBServerConfiguration + configuration: ServerConfiguration ) -> ServerBootstrap { return ServerBootstrap(group: self.eventLoopGroup) // Specify backlog and enable SO_REUSEADDR for the server itself @@ -249,7 +249,7 @@ public actor HBServer: Service { /// create a NIOTransportServices bootstrap using Network.framework @available(macOS 10.14, iOS 12, tvOS 12, *) private nonisolated func createTSBootstrap( - configuration: HBServerConfiguration + configuration: ServerConfiguration ) -> NIOTSListenerBootstrap? { guard let bootstrap = NIOTSListenerBootstrap(validatingGroup: self.eventLoopGroup)? .serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: configuration.reuseAddress ? 1 : 0) @@ -304,7 +304,7 @@ extension NIOTSListenerBootstrap: ServerBootstrapProtocol { } #endif -extension HBServer: CustomStringConvertible { +extension Server: CustomStringConvertible { public nonisolated var description: String { "Hummingbird" } diff --git a/Sources/HummingbirdCore/Server/ServerChildChannel.swift b/Sources/HummingbirdCore/Server/ServerChildChannel.swift index 21471f94e..320f6e142 100644 --- a/Sources/HummingbirdCore/Server/ServerChildChannel.swift +++ b/Sources/HummingbirdCore/Server/ServerChildChannel.swift @@ -16,7 +16,7 @@ import Logging import NIOCore /// HTTPServer child channel setup protocol -public protocol HBServerChildChannel: Sendable { +public protocol ServerChildChannel: Sendable { associatedtype Value: Sendable /// Setup child channel diff --git a/Sources/HummingbirdCore/Server/ServerConfiguration.swift b/Sources/HummingbirdCore/Server/ServerConfiguration.swift index b8f27c126..ae93a59fe 100644 --- a/Sources/HummingbirdCore/Server/ServerConfiguration.swift +++ b/Sources/HummingbirdCore/Server/ServerConfiguration.swift @@ -15,9 +15,9 @@ import NIOCore /// HTTP server configuration -public struct HBServerConfiguration: Sendable { +public struct ServerConfiguration: Sendable { /// Bind address for server - public let address: HBAddress + public let address: Address /// Server name to return in "server" header public let serverName: String? /// Defines the maximum length for the queue of pending connections @@ -37,7 +37,7 @@ public struct HBServerConfiguration: Sendable { /// the client may receive an error with an indication of ECONNREFUSE /// - reuseAddress: Allows socket to be bound to an address that is already in use. public init( - address: HBAddress = .hostname(), + address: Address = .hostname(), serverName: String? = nil, backlog: Int = 256, reuseAddress: Bool = true @@ -61,7 +61,7 @@ public struct HBServerConfiguration: Sendable { /// - tlsOptions: TLS options for when you are using NIOTransportServices #if canImport(Network) public init( - address: HBAddress = .hostname(), + address: Address = .hostname(), serverName: String? = nil, backlog: Int = 256, reuseAddress: Bool = true, diff --git a/Sources/HummingbirdCore/Utils/HBParser.swift b/Sources/HummingbirdCore/Utils/HBParser.swift index 832298410..fdf6b67aa 100644 --- a/Sources/HummingbirdCore/Utils/HBParser.swift +++ b/Sources/HummingbirdCore/Utils/HBParser.swift @@ -18,7 +18,7 @@ // https://github.com/fabianfett/pure-swift-json/blob/master/Sources/PureSwiftJSONParsing/DocumentReader.swift /// Reader object for parsing String buffers -package struct HBParser: Sendable { +package struct Parser: Sendable { package enum Error: Swift.Error { case overflow case unexpected @@ -66,9 +66,9 @@ package struct HBParser: Sendable { // MARK: sub-parsers -extension HBParser { +extension Parser { /// initialise a parser that parses a section of the buffer attached to another parser - private init(_ parser: HBParser, range: Range) { + private init(_ parser: Parser, range: Range) { self.buffer = parser.buffer self.index = range.startIndex self.range = range @@ -78,12 +78,12 @@ extension HBParser { } /// initialise a parser that parses a section of the buffer attached to this parser - func subParser(_ range: Range) -> HBParser { - return HBParser(self, range: range) + func subParser(_ range: Range) -> Parser { + return Parser(self, range: range) } } -package extension HBParser { +package extension Parser { /// Return current character /// - Throws: .overflow /// - Returns: Current character @@ -130,7 +130,7 @@ package extension HBParser { /// - Parameter count: Number of characters to read /// - Throws: .overflow /// - Returns: The string read from the buffer - mutating func read(count: Int) throws -> HBParser { + mutating func read(count: Int) throws -> Parser { var count = count var readEndIndex = self.index while count > 0 { @@ -147,7 +147,7 @@ package extension HBParser { /// - Parameter until: Unicode.Scalar to read until /// - Throws: .overflow if we hit the end of the buffer before reading character /// - Returns: String read from buffer - @discardableResult mutating func read(until: Unicode.Scalar, throwOnOverflow: Bool = true) throws -> HBParser { + @discardableResult mutating func read(until: Unicode.Scalar, throwOnOverflow: Bool = true) throws -> Parser { let startIndex = self.index while !self.reachedEnd() { if unsafeCurrent() == until { @@ -166,7 +166,7 @@ package extension HBParser { /// - Parameter characterSet: Unicode.Scalar set to check against /// - Throws: .overflow /// - Returns: String read from buffer - @discardableResult mutating func read(until characterSet: Set, throwOnOverflow: Bool = true) throws -> HBParser { + @discardableResult mutating func read(until characterSet: Set, throwOnOverflow: Bool = true) throws -> Parser { let startIndex = self.index while !self.reachedEnd() { if characterSet.contains(unsafeCurrent()) { @@ -185,7 +185,7 @@ package extension HBParser { /// - Parameter until: Function to test /// - Throws: .overflow /// - Returns: String read from buffer - @discardableResult mutating func read(until: (Unicode.Scalar) -> Bool, throwOnOverflow: Bool = true) throws -> HBParser { + @discardableResult mutating func read(until: (Unicode.Scalar) -> Bool, throwOnOverflow: Bool = true) throws -> Parser { let startIndex = self.index while !self.reachedEnd() { if until(unsafeCurrent()) { @@ -204,7 +204,7 @@ package extension HBParser { /// - Parameter characterSet: Unicode.Scalar set to check against /// - Throws: .overflow /// - Returns: String read from buffer - @discardableResult mutating func read(until keyPath: KeyPath, throwOnOverflow: Bool = true) throws -> HBParser { + @discardableResult mutating func read(until keyPath: KeyPath, throwOnOverflow: Bool = true) throws -> Parser { let startIndex = self.index while !self.reachedEnd() { if unsafeCurrent()[keyPath: keyPath] { @@ -225,7 +225,7 @@ package extension HBParser { /// - Parameter skipToEnd: Should we set the position to after the found string /// - Throws: .overflow, .emptyString /// - Returns: String read from buffer - @discardableResult mutating func read(untilString: String, throwOnOverflow: Bool = true, skipToEnd: Bool = false) throws -> HBParser { + @discardableResult mutating func read(untilString: String, throwOnOverflow: Bool = true, skipToEnd: Bool = false) throws -> Parser { var untilString = untilString return try untilString.withUTF8 { utf8 in guard utf8.count > 0 else { throw Error.emptyString } @@ -261,7 +261,7 @@ package extension HBParser { /// Read from buffer from current position until the end of the buffer /// - Returns: String read from buffer - @discardableResult mutating func readUntilTheEnd() -> HBParser { + @discardableResult mutating func readUntilTheEnd() -> Parser { let startIndex = self.index self.index = self.range.endIndex return self.subParser(startIndex..) -> HBParser { + @discardableResult mutating func read(while characterSet: Set) -> Parser { let startIndex = self.index while !self.reachedEnd(), characterSet.contains(unsafeCurrent()) @@ -297,7 +297,7 @@ package extension HBParser { /// Read while character returns true for supplied closure /// - Parameter while: character set to check /// - Returns: String read from buffer - @discardableResult mutating func read(while: (Unicode.Scalar) -> Bool) -> HBParser { + @discardableResult mutating func read(while: (Unicode.Scalar) -> Bool) -> Parser { let startIndex = self.index while !self.reachedEnd(), `while`(unsafeCurrent()) @@ -310,7 +310,7 @@ package extension HBParser { /// Read while character returns true for supplied KeyPath /// - Parameter while: character set to check /// - Returns: String read from buffer - @discardableResult mutating func read(while keyPath: KeyPath) -> HBParser { + @discardableResult mutating func read(while keyPath: KeyPath) -> Parser { let startIndex = self.index while !self.reachedEnd(), unsafeCurrent()[keyPath: keyPath] @@ -323,8 +323,8 @@ package extension HBParser { /// Split parser into sections separated by character /// - Parameter separator: Separator character /// - Returns: arrays of sub parsers - mutating func split(separator: Unicode.Scalar) -> [HBParser] { - var subParsers: [HBParser] = [] + mutating func split(separator: Unicode.Scalar) -> [Parser] { + var subParsers: [Parser] = [] while !self.reachedEnd() { do { let section = try read(until: separator) @@ -347,7 +347,7 @@ package extension HBParser { } /// Public versions of internal functions which include tests for overflow -package extension HBParser { +package extension Parser { /// Return the character at the current position /// - Throws: .overflow /// - Returns: Unicode.Scalar @@ -418,7 +418,7 @@ package extension HBParser { } /// extend Parser to conform to Sequence -extension HBParser: Sequence { +extension Parser: Sequence { public typealias Element = Unicode.Scalar public func makeIterator() -> Iterator { @@ -428,9 +428,9 @@ extension HBParser: Sequence { public struct Iterator: IteratorProtocol { public typealias Element = Unicode.Scalar - var parser: HBParser + var parser: Parser - init(_ parser: HBParser) { + init(_ parser: Parser) { self.parser = parser } @@ -442,7 +442,7 @@ extension HBParser: Sequence { } // internal versions without checks -private extension HBParser { +private extension Parser { func unsafeCurrent() -> Unicode.Scalar { return decodeUTF8Character(at: self.index).0 } @@ -467,7 +467,7 @@ private extension HBParser { } // UTF8 parsing -extension HBParser { +extension Parser { func decodeUTF8Character(at index: Int) -> (Unicode.Scalar, Int) { var index = index let byte1 = UInt32(buffer[index]) diff --git a/Sources/HummingbirdHTTP2/HTTP2Channel.swift b/Sources/HummingbirdHTTP2/HTTP2Channel.swift index b6ee53b67..355d007e6 100644 --- a/Sources/HummingbirdHTTP2/HTTP2Channel.swift +++ b/Sources/HummingbirdHTTP2/HTTP2Channel.swift @@ -30,7 +30,7 @@ public struct HTTP2UpgradeChannel: HTTPChannelHandler { private let sslContext: NIOSSLContext private let http1: HTTP1Channel private let additionalChannelHandlers: @Sendable () -> [any RemovableChannelHandler] - public var responder: @Sendable (HBRequest, Channel) async throws -> HBResponse { http1.responder } + public var responder: @Sendable (Request, Channel) async throws -> Response { http1.responder } /// Initialize HTTP1Channel /// - Parameters: @@ -40,7 +40,7 @@ public struct HTTP2UpgradeChannel: HTTPChannelHandler { public init( tlsConfiguration: TLSConfiguration, additionalChannelHandlers: @escaping @Sendable () -> [any RemovableChannelHandler] = { [] }, - responder: @escaping @Sendable (HBRequest, Channel) async throws -> HBResponse = { _, _ in throw HBHTTPError(.notImplemented) } + responder: @escaping @Sendable (Request, Channel) async throws -> Response = { _, _ in throw HTTPError(.notImplemented) } ) throws { var tlsConfiguration = tlsConfiguration tlsConfiguration.applicationProtocols = NIOHTTP2SupportedALPNProtocols @@ -65,7 +65,7 @@ public struct HTTP2UpgradeChannel: HTTPChannelHandler { let childChannelHandlers: [ChannelHandler] = [HTTP1ToHTTPServerCodec(secure: false)] + self.additionalChannelHandlers() + - [HBHTTPUserEventHandler(logger: logger)] + [HTTPUserEventHandler(logger: logger)] return http1Channel .pipeline @@ -80,7 +80,7 @@ public struct HTTP2UpgradeChannel: HTTPChannelHandler { } http2StreamInitializer: { http2ChildChannel -> EventLoopFuture in let childChannelHandlers: [ChannelHandler] = self.additionalChannelHandlers() + [ - HBHTTPUserEventHandler(logger: logger), + HTTPUserEventHandler(logger: logger), ] return http2ChildChannel diff --git a/Sources/HummingbirdHTTP2/HTTP2ChannelBuilder.swift b/Sources/HummingbirdHTTP2/HTTP2ChannelBuilder.swift index f27448bb2..b0beb5f3e 100644 --- a/Sources/HummingbirdHTTP2/HTTP2ChannelBuilder.swift +++ b/Sources/HummingbirdHTTP2/HTTP2ChannelBuilder.swift @@ -16,12 +16,12 @@ import HummingbirdCore import NIOCore import NIOSSL -extension HBHTTPChannelBuilder { +extension HTTPChannelBuilder { /// Build HTTP channel with HTTP2 upgrade /// - /// Use in ``Hummingbird/HBApplication`` initialization. + /// Use in ``Hummingbird/Application`` initialization. /// ``` - /// let app = HBApplication( + /// let app = Application( /// router: router, /// server: .http2Upgrade(tlsConfiguration: tlsConfiguration) /// ) @@ -33,7 +33,7 @@ extension HBHTTPChannelBuilder { public static func http2Upgrade( tlsConfiguration: TLSConfiguration, additionalChannelHandlers: @autoclosure @escaping @Sendable () -> [any RemovableChannelHandler] = [] - ) throws -> HBHTTPChannelBuilder { + ) throws -> HTTPChannelBuilder { return .init { responder in return try HTTP2UpgradeChannel( tlsConfiguration: tlsConfiguration, diff --git a/Sources/HummingbirdJobs/Job.swift b/Sources/HummingbirdJobs/Job.swift index eb1197cad..a992cc178 100644 --- a/Sources/HummingbirdJobs/Job.swift +++ b/Sources/HummingbirdJobs/Job.swift @@ -13,18 +13,18 @@ //===----------------------------------------------------------------------===// /// Protocol for a Job -public protocol HBJob: Sendable { +public protocol Job: Sendable { /// Parameters job requries associatedtype Parameters: Codable & Sendable /// Job Type identifier - var id: HBJobIdentifier { get } + var id: JobIdentifier { get } /// Maximum number of times a job will be retried before being classed as failed var maxRetryCount: Int { get } /// Function to execute the job - func execute(context: HBJobContext) async throws + func execute(context: JobContext) async throws } -extension HBJob { +extension Job { /// name of job type public var name: String { id.name diff --git a/Sources/HummingbirdJobs/JobContext.swift b/Sources/HummingbirdJobs/JobContext.swift index a49b807c3..35fc12c1a 100644 --- a/Sources/HummingbirdJobs/JobContext.swift +++ b/Sources/HummingbirdJobs/JobContext.swift @@ -14,6 +14,6 @@ import Logging -public struct HBJobContext { +public struct JobContext { public let logger: Logger } diff --git a/Sources/HummingbirdJobs/JobDefinition.swift b/Sources/HummingbirdJobs/JobDefinition.swift index 8ce468e6a..4a75bc873 100644 --- a/Sources/HummingbirdJobs/JobDefinition.swift +++ b/Sources/HummingbirdJobs/JobDefinition.swift @@ -13,18 +13,18 @@ //===----------------------------------------------------------------------===// /// Job definition type -public struct HBJobDefinition: Sendable { - public let id: HBJobIdentifier +public struct JobDefinition: Sendable { + public let id: JobIdentifier let maxRetryCount: Int - let _execute: @Sendable (Parameters, HBJobContext) async throws -> Void + let _execute: @Sendable (Parameters, JobContext) async throws -> Void - public init(id: HBJobIdentifier, maxRetryCount: Int = 0, execute: @escaping @Sendable (Parameters, HBJobContext) async throws -> Void) { + public init(id: JobIdentifier, maxRetryCount: Int = 0, execute: @escaping @Sendable (Parameters, JobContext) async throws -> Void) { self.id = id self.maxRetryCount = maxRetryCount self._execute = execute } - func execute(_ parameters: Parameters, context: HBJobContext) async throws { + func execute(_ parameters: Parameters, context: JobContext) async throws { try await self._execute(parameters, context) } } diff --git a/Sources/HummingbirdJobs/JobIdentifier.swift b/Sources/HummingbirdJobs/JobIdentifier.swift index ec7dc0f45..315dba954 100644 --- a/Sources/HummingbirdJobs/JobIdentifier.swift +++ b/Sources/HummingbirdJobs/JobIdentifier.swift @@ -19,20 +19,20 @@ /// /// Extend this type to include your own job identifiers /// ``` -/// extension HBJobIdentifier { +/// extension JobIdentifier { /// static var myJob: Self { .init("my-job") } /// } /// ``` -public struct HBJobIdentifier: Sendable, Hashable, ExpressibleByStringLiteral { +public struct JobIdentifier: Sendable, Hashable, ExpressibleByStringLiteral { let name: String - /// Initialize a HBJobIdentifier + /// Initialize a JobIdentifier /// /// - Parameters: /// - name: Unique name for identifier /// - parameters: Parameter type associated with Job public init(_ name: String, parameters: Parameters.Type = Parameters.self) { self.name = name } - /// Initialize a HBJobIdentifier from a string literal + /// Initialize a JobIdentifier from a string literal /// /// This can only be used in a situation where the Parameter type is defined elsewhere /// - Parameter string: diff --git a/Sources/HummingbirdJobs/JobQueue.swift b/Sources/HummingbirdJobs/JobQueue.swift index 31d47a83d..f67356824 100644 --- a/Sources/HummingbirdJobs/JobQueue.swift +++ b/Sources/HummingbirdJobs/JobQueue.swift @@ -22,12 +22,12 @@ import ServiceLifecycle /// /// Wrapper type to bring together a job queue implementation and a job queue /// handler. Before you can push jobs onto a queue you should register it -/// with the queue via either ``HBJobQueue.registerJob(id:maxRetryCount:execute:)`` or -/// ``HBJobQueue.registerJob(_:)``. -public struct HBJobQueue: Service { +/// with the queue via either ``JobQueue.registerJob(id:maxRetryCount:execute:)`` or +/// ``JobQueue.registerJob(_:)``. +public struct JobQueue: Service { /// underlying driver for queue public let queue: Queue - let handler: HBJobQueueHandler + let handler: JobQueueHandler let allocator: ByteBufferAllocator public init(_ queue: Queue, numWorkers: Int = 1, logger: Logger) { @@ -41,11 +41,11 @@ public struct HBJobQueue: Service { /// - id: Job identifier /// - parameters: parameters for the job /// - Returns: Identifier of queued job - @discardableResult public func push(id: HBJobIdentifier, parameters: Parameters) async throws -> Queue.JobID { - let jobRequest = HBJobRequest(id: id, parameters: parameters) + @discardableResult public func push(id: JobIdentifier, parameters: Parameters) async throws -> Queue.JobID { + let jobRequest = JobRequest(id: id, parameters: parameters) let buffer = try JSONEncoder().encodeAsByteBuffer(jobRequest, allocator: self.allocator) let id = try await self.queue.push(buffer) - self.handler.logger.debug("Pushed Job", metadata: ["hb_job_id": .stringConvertible(id), "hb_job_type": .string(jobRequest.id.name)]) + self.handler.logger.debug("Pushed Job", metadata: ["_job_id": .stringConvertible(id), "_job_type": .string(jobRequest.id.name)]) return id } @@ -55,22 +55,22 @@ public struct HBJobQueue: Service { /// - maxRetryCount: Maximum number of times job is retried before being flagged as failed /// - execute: Job code public func registerJob( - _ id: HBJobIdentifier, + _ id: JobIdentifier, maxRetryCount: Int = 0, execute: @escaping @Sendable ( Parameters, - HBJobContext + JobContext ) async throws -> Void ) { - self.handler.logger.info("Registered Job", metadata: ["hb_job_type": .string(id.name)]) - let job = HBJobDefinition(id: id, maxRetryCount: maxRetryCount, execute: execute) + self.handler.logger.info("Registered Job", metadata: ["_job_type": .string(id.name)]) + let job = JobDefinition(id: id, maxRetryCount: maxRetryCount, execute: execute) self.registerJob(job) } /// Register job type /// - Parameters: /// - job: Job definition - public func registerJob(_ job: HBJobDefinition) { + public func registerJob(_ job: JobDefinition) { self.handler.registerJob(job) } @@ -80,22 +80,22 @@ public struct HBJobQueue: Service { } } -extension HBJobQueue: CustomStringConvertible { - public var description: String { "HBJobQueue<\(String(describing: Queue.self))>" } +extension JobQueue: CustomStringConvertible { + public var description: String { "JobQueue<\(String(describing: Queue.self))>" } } /// Type used internally to encode a request -struct HBJobRequest: Encodable, Sendable { - let id: HBJobIdentifier +struct JobRequest: Encodable, Sendable { + let id: JobIdentifier let parameters: Parameters - public init(id: HBJobIdentifier, parameters: Parameters) { + public init(id: JobIdentifier, parameters: Parameters) { self.id = id self.parameters = parameters } public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: _HBJobCodingKey.self) + var container = encoder.container(keyedBy: _JobCodingKey.self) let childEncoder = container.superEncoder(forKey: .init(stringValue: self.id.name, intValue: nil)) try self.parameters.encode(to: childEncoder) } diff --git a/Sources/HummingbirdJobs/JobQueueDriver.swift b/Sources/HummingbirdJobs/JobQueueDriver.swift index cb7a13e19..9c8657822 100644 --- a/Sources/HummingbirdJobs/JobQueueDriver.swift +++ b/Sources/HummingbirdJobs/JobQueueDriver.swift @@ -19,7 +19,7 @@ import NIOCore /// Job queue protocol. /// /// Defines how to push and pop job data off a queue -public protocol HBJobQueueDriver: AsyncSequence, Sendable where Element == HBQueuedJob { +public protocol JobQueueDriver: AsyncSequence, Sendable where Element == QueuedJob { associatedtype JobID: CustomStringConvertible & Sendable /// Called when JobQueueHandler is initialised with this queue @@ -37,7 +37,7 @@ public protocol HBJobQueueDriver: AsyncSequence, Sendable where Element == HBQue func shutdownGracefully() async } -extension HBJobQueueDriver { +extension JobQueueDriver { // default version of onInit doing nothing public func onInit() async throws {} } diff --git a/Sources/HummingbirdJobs/JobQueueHandler.swift b/Sources/HummingbirdJobs/JobQueueHandler.swift index 5f195c2e8..30d8e52b6 100644 --- a/Sources/HummingbirdJobs/JobQueueHandler.swift +++ b/Sources/HummingbirdJobs/JobQueueHandler.swift @@ -16,7 +16,7 @@ import Logging import ServiceLifecycle /// Object handling a single job queue -final class HBJobQueueHandler: Service { +final class JobQueueHandler: Service { init(queue: Queue, numWorkers: Int, logger: Logger) { self.queue = queue self.numWorkers = numWorkers @@ -29,7 +29,7 @@ final class HBJobQueueHandler: Service { /// - id: Job Identifier /// - maxRetryCount: Maximum number of times job is retried before being flagged as failed /// - execute: Job code - func registerJob(_ job: HBJobDefinition) { + func registerJob(_ job: JobDefinition) { self.jobRegistry.registerJob(job: job) } @@ -61,10 +61,10 @@ final class HBJobQueueHandler: Service { } } - func runJob(_ queuedJob: HBQueuedJob) async throws { + func runJob(_ queuedJob: QueuedJob) async throws { var logger = logger - logger[metadataKey: "hb_job_id"] = .stringConvertible(queuedJob.id) - let job: any HBJob + logger[metadataKey: "_job_id"] = .stringConvertible(queuedJob.id) + let job: any Job do { job = try self.jobRegistry.decode(queuedJob.jobBuffer) } catch let error as JobQueueError where error == .unrecognisedJobId { @@ -76,7 +76,7 @@ final class HBJobQueueHandler: Service { try await self.queue.failed(jobId: queuedJob.id, error: JobQueueError.decodeJobFailed) return } - logger[metadataKey: "hb_job_type"] = .string(job.name) + logger[metadataKey: "_job_type"] = .string(job.name) var count = job.maxRetryCount logger.debug("Starting Job") @@ -110,12 +110,12 @@ final class HBJobQueueHandler: Service { } } - private let jobRegistry: HBJobRegistry + private let jobRegistry: JobRegistry private let queue: Queue private let numWorkers: Int let logger: Logger } -extension HBJobQueueHandler: CustomStringConvertible { - public var description: String { "HBJobQueueHandler<\(String(describing: Queue.self))>" } +extension JobQueueHandler: CustomStringConvertible { + public var description: String { "JobQueueHandler<\(String(describing: Queue.self))>" } } diff --git a/Sources/HummingbirdJobs/JobRegistry.swift b/Sources/HummingbirdJobs/JobRegistry.swift index 455749b2f..fd5b96f19 100644 --- a/Sources/HummingbirdJobs/JobRegistry.swift +++ b/Sources/HummingbirdJobs/JobRegistry.swift @@ -17,18 +17,18 @@ import NIOConcurrencyHelpers import NIOCore /// Registry for job types -struct HBJobRegistry: Sendable { +struct JobRegistry: Sendable { /// Register job /// - Parameters: /// - id: Job Identifier /// - maxRetryCount: Maximum number of times job is retried before being flagged as failed /// - execute: Job code public func registerJob( - job: HBJobDefinition + job: JobDefinition ) { - let builder: @Sendable (Decoder) throws -> any HBJob = { decoder in + let builder: @Sendable (Decoder) throws -> any Job = { decoder in let parameters = try Parameters(from: decoder) - return try HBJobInstance(job: job, parameters: parameters) + return try JobInstance(job: job, parameters: parameters) } self.builderTypeMap.withLockedValue { precondition($0[job.id.name] == nil, "There is a job already registered under id \"\(job.id.name)\"") @@ -36,12 +36,12 @@ struct HBJobRegistry: Sendable { } } - func decode(_ buffer: ByteBuffer) throws -> any HBJob { - return try JSONDecoder().decode(HBAnyCodableJob.self, from: buffer, userInfoConfiguration: self).job + func decode(_ buffer: ByteBuffer) throws -> any Job { + return try JSONDecoder().decode(AnyCodableJob.self, from: buffer, userInfoConfiguration: self).job } - func decode(from decoder: Decoder) throws -> any HBJob { - let container = try decoder.container(keyedBy: _HBJobCodingKey.self) + func decode(from decoder: Decoder) throws -> any Job { + let container = try decoder.container(keyedBy: _JobCodingKey.self) let key = container.allKeys.first! let childDecoder = try container.superDecoder(forKey: key) let jobDefinitionBuilder = try self.builderTypeMap.withLockedValue { @@ -51,43 +51,43 @@ struct HBJobRegistry: Sendable { return try jobDefinitionBuilder(childDecoder) } - let builderTypeMap: NIOLockedValueBox < [String: @Sendable (Decoder) throws -> any HBJob]> = .init([:]) + let builderTypeMap: NIOLockedValueBox < [String: @Sendable (Decoder) throws -> any Job]> = .init([:]) } /// Internal job instance type -internal struct HBJobInstance: HBJob { +internal struct JobInstance: Job { /// job definition - let job: HBJobDefinition + let job: JobDefinition /// job parameters let parameters: Parameters /// get i - var id: HBJobIdentifier { self.job.id } + var id: JobIdentifier { self.job.id } var maxRetryCount: Int { self.job.maxRetryCount } - func execute(context: HBJobContext) async throws { + func execute(context: JobContext) async throws { try await self.job.execute(self.parameters, context: context) } - init(job: HBJobDefinition, parameters: Parameters) throws { + init(job: JobDefinition, parameters: Parameters) throws { self.job = job self.parameters = parameters } } -/// Add codable support for decoding/encoding any HBJob -internal struct HBAnyCodableJob: DecodableWithUserInfoConfiguration, Sendable { - typealias DecodingConfiguration = HBJobRegistry +/// Add codable support for decoding/encoding any Job +internal struct AnyCodableJob: DecodableWithUserInfoConfiguration, Sendable { + typealias DecodingConfiguration = JobRegistry init(from decoder: Decoder, configuration register: DecodingConfiguration) throws { self.job = try register.decode(from: decoder) } /// Job data - let job: any HBJob + let job: any Job /// Initialize a queue job - init(_ job: any HBJob) { + init(_ job: any Job) { self.job = job } @@ -96,7 +96,7 @@ internal struct HBAnyCodableJob: DecodableWithUserInfoConfiguration, Sendable { } } -internal struct _HBJobCodingKey: CodingKey { +internal struct _JobCodingKey: CodingKey { public var stringValue: String public var intValue: Int? diff --git a/Sources/HummingbirdJobs/MemoryJobQueue.swift b/Sources/HummingbirdJobs/MemoryJobQueue.swift index e17d86eb4..113d36350 100644 --- a/Sources/HummingbirdJobs/MemoryJobQueue.swift +++ b/Sources/HummingbirdJobs/MemoryJobQueue.swift @@ -17,16 +17,16 @@ import Foundation import NIOCore /// In memory implementation of job queue driver. Stores job data in a circular buffer -public final class HBMemoryQueue: HBJobQueueDriver { - public typealias Element = HBQueuedJob +public final class MemoryQueue: JobQueueDriver { + public typealias Element = QueuedJob public typealias JobID = UUID /// queue of jobs fileprivate let queue: Internal - private let onFailedJob: @Sendable (HBQueuedJob, any Error) -> Void + private let onFailedJob: @Sendable (QueuedJob, any Error) -> Void /// Initialise In memory job queue - public init(onFailedJob: @escaping @Sendable (HBQueuedJob, any Error) -> Void = { _, _ in }) { + public init(onFailedJob: @escaping @Sendable (QueuedJob, any Error) -> Void = { _, _ in }) { self.queue = .init() self.onFailedJob = onFailedJob } @@ -62,7 +62,7 @@ public final class HBMemoryQueue: HBJobQueueDriver { /// Internal actor managing the job queue fileprivate actor Internal { - var queue: Deque> + var queue: Deque> var pendingJobs: [JobID: ByteBuffer] var isStopped: Bool @@ -74,7 +74,7 @@ public final class HBMemoryQueue: HBJobQueueDriver { func push(_ jobBuffer: ByteBuffer) throws -> JobID { let id = JobID() - self.queue.append(HBQueuedJob(id: id, jobBuffer: jobBuffer)) + self.queue.append(QueuedJob(id: id, jobBuffer: jobBuffer)) return id } @@ -88,7 +88,7 @@ public final class HBMemoryQueue: HBJobQueueDriver { return instance } - func next() async throws -> HBQueuedJob? { + func next() async throws -> QueuedJob? { while true { if self.isStopped { return nil @@ -112,7 +112,7 @@ public final class HBMemoryQueue: HBJobQueueDriver { } } -extension HBMemoryQueue { +extension MemoryQueue { public struct AsyncIterator: AsyncIteratorProtocol { fileprivate let queue: Internal @@ -126,11 +126,11 @@ extension HBMemoryQueue { } } -extension HBJobQueueDriver where Self == HBMemoryQueue { +extension JobQueueDriver where Self == MemoryQueue { /// Return In memory driver for Job Queue /// - Parameters: /// - onFailedJob: Closure called when a job fails - public static var memory: HBMemoryQueue { + public static var memory: MemoryQueue { .init() } } diff --git a/Sources/HummingbirdJobs/QueuedJob.swift b/Sources/HummingbirdJobs/QueuedJob.swift index 62e59d86c..507c382af 100644 --- a/Sources/HummingbirdJobs/QueuedJob.swift +++ b/Sources/HummingbirdJobs/QueuedJob.swift @@ -16,7 +16,7 @@ import Foundation import NIOCore /// Queued job. Includes job data, plus the id for the job -public struct HBQueuedJob: Sendable { +public struct QueuedJob: Sendable { /// Job instance id public let id: JobID /// Job data diff --git a/Sources/HummingbirdRouter/MiddlewareModule/MiddlewareStack.swift b/Sources/HummingbirdRouter/MiddlewareModule/MiddlewareStack.swift index d2f6f48d9..2dfb23261 100644 --- a/Sources/HummingbirdRouter/MiddlewareModule/MiddlewareStack.swift +++ b/Sources/HummingbirdRouter/MiddlewareModule/MiddlewareStack.swift @@ -35,7 +35,7 @@ public struct _Middleware2: Midd } } -/// Result builder used by ``HBRouterBuilder`` +/// Result builder used by ``RouterBuilder`` /// /// Generates a middleware stack from the elements inside the result builder. The input, /// context and output types passed through the middleware stack are fixed and cannot be changed. diff --git a/Sources/HummingbirdRouter/Route.swift b/Sources/HummingbirdRouter/Route.swift index 7faef7e10..c3ad8fd31 100644 --- a/Sources/HummingbirdRouter/Route.swift +++ b/Sources/HummingbirdRouter/Route.swift @@ -17,7 +17,7 @@ import Hummingbird import ServiceContextModule /// Route definition -public struct Route: HBRouterMiddleware where Handler.Context == Context { +public struct Route: RouterMiddleware where Handler.Context == Context { /// Full URI path to route public let fullPath: String /// Route path local to group route is defined in. @@ -44,7 +44,7 @@ public struct Route( + public init( _ method: HTTPRequest.Method, _ routerPath: RouterPath = "", handler: @escaping @Sendable (Input, Context) async throws -> RouteOutput @@ -65,7 +65,7 @@ public struct Route builder: () -> M0 - ) where Handler == _RouteHandlerMiddleware, M0.Input == HBRequest, M0.Output == HBResponse, M0.Context == Context { + ) where Handler == _RouteHandlerMiddleware, M0.Input == Request, M0.Output == Response, M0.Context == Context { self.init( method, routerPath, @@ -79,7 +79,7 @@ public struct Route HBResponse) async throws -> HBResponse { + public func handle(_ input: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { if input.method == self.method, let context = self.routerPath.matchAll(context) { context.coreContext.endpointPath.value = self.fullPath return try await self.handler.handle(input, context: context) @@ -102,9 +102,9 @@ public struct Route( +public func Get( _ routerPath: RouterPath = "", - handler: @escaping @Sendable (HBRequest, Context) async throws -> RouteOutput + handler: @escaping @Sendable (Request, Context) async throws -> RouteOutput ) -> Route<_RouteHandlerClosure, Context> { .init(.get, routerPath, handler: handler) } @@ -113,10 +113,10 @@ public func Get( +public func Get( _ routerPath: RouterPath = "", @RouteBuilder builder: () -> M0 -) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == HBRequest, M0.Output == HBResponse, M0.Context == Context { +) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == Request, M0.Output == Response, M0.Context == Context { .init(.get, routerPath, builder: builder) } @@ -124,9 +124,9 @@ public func Get( /// - Parameters: /// - routerPath: Route path, relative to group route is defined in /// - handler: Router handler closure -public func Head( +public func Head( _ routerPath: RouterPath = "", - handler: @escaping @Sendable (HBRequest, Context) async throws -> RouteOutput + handler: @escaping @Sendable (Request, Context) async throws -> RouteOutput ) -> Route<_RouteHandlerClosure, Context> { .init(.head, routerPath, handler: handler) } @@ -135,10 +135,10 @@ public func Head( +public func Head( _ routerPath: RouterPath = "", @RouteBuilder builder: () -> M0 -) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == HBRequest, M0.Output == HBResponse, M0.Context == Context { +) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == Request, M0.Output == Response, M0.Context == Context { .init(.head, routerPath, builder: builder) } @@ -146,9 +146,9 @@ public func Head( /// - Parameters: /// - routerPath: Route path, relative to group route is defined in /// - handler: Router handler closure -public func Put( +public func Put( _ routerPath: RouterPath = "", - handler: @escaping @Sendable (HBRequest, Context) async throws -> RouteOutput + handler: @escaping @Sendable (Request, Context) async throws -> RouteOutput ) -> Route<_RouteHandlerClosure, Context> { .init(.put, routerPath, handler: handler) } @@ -157,10 +157,10 @@ public func Put( +public func Put( _ routerPath: RouterPath = "", @RouteBuilder builder: () -> M0 -) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == HBRequest, M0.Output == HBResponse, M0.Context == Context { +) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == Request, M0.Output == Response, M0.Context == Context { .init(.put, routerPath, builder: builder) } @@ -168,9 +168,9 @@ public func Put( /// - Parameters: /// - routerPath: Route path, relative to group route is defined in /// - handler: Router handler closure -public func Post( +public func Post( _ routerPath: RouterPath = "", - handler: @escaping @Sendable (HBRequest, Context) async throws -> RouteOutput + handler: @escaping @Sendable (Request, Context) async throws -> RouteOutput ) -> Route<_RouteHandlerClosure, Context> { .init(.post, routerPath, handler: handler) } @@ -179,10 +179,10 @@ public func Post( +public func Post( _ routerPath: RouterPath = "", @RouteBuilder builder: () -> M0 -) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == HBRequest, M0.Output == HBResponse, M0.Context == Context { +) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == Request, M0.Output == Response, M0.Context == Context { .init(.post, routerPath, builder: builder) } @@ -190,9 +190,9 @@ public func Post( /// - Parameters: /// - routerPath: Route path, relative to group route is defined in /// - handler: Router handler closure -public func Patch( +public func Patch( _ routerPath: RouterPath = "", - handler: @escaping @Sendable (HBRequest, Context) async throws -> RouteOutput + handler: @escaping @Sendable (Request, Context) async throws -> RouteOutput ) -> Route<_RouteHandlerClosure, Context> { .init(.patch, routerPath, handler: handler) } @@ -201,10 +201,10 @@ public func Patch( +public func Patch( _ routerPath: RouterPath = "", @RouteBuilder builder: () -> M0 -) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == HBRequest, M0.Output == HBResponse, M0.Context == Context { +) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == Request, M0.Output == Response, M0.Context == Context { .init(.patch, routerPath, builder: builder) } @@ -212,9 +212,9 @@ public func Patch( /// - Parameters: /// - routerPath: Route path, relative to group route is defined in /// - handler: Router handler closure -public func Delete( +public func Delete( _ routerPath: RouterPath = "", - handler: @escaping @Sendable (HBRequest, Context) async throws -> RouteOutput + handler: @escaping @Sendable (Request, Context) async throws -> RouteOutput ) -> Route<_RouteHandlerClosure, Context> { .init(.delete, routerPath, handler: handler) } @@ -223,9 +223,9 @@ public func Delete( +public func Delete( _ routerPath: RouterPath = "", @RouteBuilder builder: () -> M0 -) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == HBRequest, M0.Output == HBResponse, M0.Context == Context { +) -> Route<_RouteHandlerMiddleware, Context> where M0.Input == Request, M0.Output == Response, M0.Context == Context { .init(.delete, routerPath, builder: builder) } diff --git a/Sources/HummingbirdRouter/RouteBuilder.swift b/Sources/HummingbirdRouter/RouteBuilder.swift index 2ae5f1235..deccf6795 100644 --- a/Sources/HummingbirdRouter/RouteBuilder.swift +++ b/Sources/HummingbirdRouter/RouteBuilder.swift @@ -16,11 +16,11 @@ import Hummingbird /// Route Handler Middleware. /// -/// Requires that the return value of handler conforms to ``Hummingbird/HBResponseGenerator`` so -/// that the `handle` function can return an ``HummingbirdCore/HBResponse`` -public struct Handle: Sendable, MiddlewareProtocol { - public typealias Input = HBRequest - public typealias Output = HBResponse +/// Requires that the return value of handler conforms to ``Hummingbird/ResponseGenerator`` so +/// that the `handle` function can return an ``HummingbirdCore/Response`` +public struct Handle: Sendable, MiddlewareProtocol { + public typealias Input = Request + public typealias Output = Response public typealias Handler = @Sendable (Input, Context) async throws -> HandlerOutput let handler: Handler @@ -48,18 +48,18 @@ public struct Handle { +public enum RouteBuilder { /// Provide generic requirements for MiddlewareProtocol - public static func buildExpression(_ m0: M0) -> M0 where M0.Input == HBRequest, M0.Output == HBResponse, M0.Context == Context { + public static func buildExpression(_ m0: M0) -> M0 where M0.Input == Request, M0.Output == Response, M0.Context == Context { return m0 } /// Build a ``Handle`` from a closure - public static func buildExpression(_ handler: @escaping @Sendable (HBRequest, Context) async throws -> HandlerOutput) -> Handle { + public static func buildExpression(_ handler: @escaping @Sendable (Request, Context) async throws -> HandlerOutput) -> Handle { return .init(handler) } - public static func buildBlock(_ m0: Handle) -> Handle { + public static func buildBlock(_ m0: Handle) -> Handle { m0 } @@ -75,12 +75,12 @@ public enum RouteBuilder { } /// Build the final result where the input is a single ``Handle`` middleware - public static func buildFinalResult(_ m0: Handle) -> Handle { + public static func buildFinalResult(_ m0: Handle) -> Handle { m0 } /// Build the final result where input is multiple middleware with the final middleware being a ``Handle`` middleware. - public static func buildFinalResult(_ m0: _Middleware2>) -> _Middleware2> { + public static func buildFinalResult(_ m0: _Middleware2>) -> _Middleware2> { m0 } } diff --git a/Sources/HummingbirdRouter/RouteGroup.swift b/Sources/HummingbirdRouter/RouteGroup.swift index 774a53531..af8b2d94f 100644 --- a/Sources/HummingbirdRouter/RouteGroup.swift +++ b/Sources/HummingbirdRouter/RouteGroup.swift @@ -33,9 +33,9 @@ extension ServiceContext { } /// Router middleware that applies a middleware chain to URIs with a specified prefix -public struct RouteGroup: HBRouterMiddleware where Handler.Input == HBRequest, Handler.Output == HBResponse, Handler.Context == Context { - public typealias Input = HBRequest - public typealias Output = HBResponse +public struct RouteGroup: RouterMiddleware where Handler.Input == Request, Handler.Output == Response, Handler.Context == Context { + public typealias Input = Request + public typealias Output = Response /// Path local to group route this group is defined in. @usableFromInline @@ -50,7 +50,7 @@ public struct RouteGroup builder: () -> Handler + @MiddlewareFixedTypeBuilder builder: () -> Handler ) { self.routerPath = routerPath var serviceContext = ServiceContext.current ?? ServiceContext.topLevel diff --git a/Sources/HummingbirdRouter/RouteHandler.swift b/Sources/HummingbirdRouter/RouteHandler.swift index 61d31b880..eed972360 100644 --- a/Sources/HummingbirdRouter/RouteHandler.swift +++ b/Sources/HummingbirdRouter/RouteHandler.swift @@ -19,20 +19,20 @@ import Hummingbird /// Requires a function that returns a HTTP response from a HTTP request and context. @_documentation(visibility: internal) public protocol _RouteHandlerProtocol: Sendable { - associatedtype Context: HBRouterRequestContext - func handle(_ request: HBRequest, context: Context) async throws -> HBResponse + associatedtype Context: RouterRequestContext + func handle(_ request: Request, context: Context) async throws -> Response } /// Implementatinon of ``_RouteHandlerProtocol`` that uses a closure to produce a response. /// /// This is used internally to implement `Route` when it is initialized with a closure. @_documentation(visibility: internal) -public struct _RouteHandlerClosure: _RouteHandlerProtocol { +public struct _RouteHandlerClosure: _RouteHandlerProtocol { @usableFromInline - let closure: @Sendable (HBRequest, Context) async throws -> RouteOutput + let closure: @Sendable (Request, Context) async throws -> RouteOutput @inlinable - public func handle(_ request: HBRequest, context: Context) async throws -> HBResponse { + public func handle(_ request: Request, context: Context) async throws -> Response { try await self.closure(request, context).response(from: request, context: context) } } @@ -42,12 +42,12 @@ public struct _RouteHandlerClosure: _RouteHandlerProtocol where M0.Input == HBRequest, M0.Output == HBResponse, M0.Context: HBRouterRequestContext { +public struct _RouteHandlerMiddleware: _RouteHandlerProtocol where M0.Input == Request, M0.Output == Response, M0.Context: RouterRequestContext { public typealias Context = M0.Context /// Dummy function passed to middleware handle @usableFromInline - static func notFound(_: HBRequest, _: Context) -> HBResponse { + static func notFound(_: Request, _: Context) -> Response { .init(status: .notFound) } @@ -55,7 +55,7 @@ public struct _RouteHandlerMiddleware: _RouteHandlerProt let middleware: M0 @inlinable - public func handle(_ request: HBRequest, context: Context) async throws -> HBResponse { + public func handle(_ request: Request, context: Context) async throws -> Response { try await self.middleware.handle(request, context: context, next: Self.notFound) } } diff --git a/Sources/HummingbirdRouter/RouterBuilder.swift b/Sources/HummingbirdRouter/RouterBuilder.swift index f2b5ad91b..f21f30f1c 100644 --- a/Sources/HummingbirdRouter/RouterBuilder.swift +++ b/Sources/HummingbirdRouter/RouterBuilder.swift @@ -15,14 +15,14 @@ import Hummingbird /// Router built using a result builder -public struct HBRouterBuilder: MiddlewareProtocol where Handler.Input == HBRequest, Handler.Output == HBResponse, Handler.Context == Context +public struct RouterBuilder: MiddlewareProtocol where Handler.Input == Request, Handler.Output == Response, Handler.Context == Context { - public typealias Input = HBRequest - public typealias Output = HBResponse + public typealias Input = Request + public typealias Output = Response let handler: Handler - /// Initialize HBRouterBuilder with contents of result builder + /// Initialize RouterBuilder with contents of result builder /// - Parameters: /// - context: Request context used by router /// - builder: Result builder for router @@ -43,11 +43,11 @@ public struct HBRouterBuilder Output { try await self.handle(request, context: context) { _, _ in - throw HBHTTPError(.notFound) + throw HTTPError(.notFound) } } diff --git a/Sources/HummingbirdRouter/RouterBuilderContext.swift b/Sources/HummingbirdRouter/RouterBuilderContext.swift index c2df63032..1a01b4027 100644 --- a/Sources/HummingbirdRouter/RouterBuilderContext.swift +++ b/Sources/HummingbirdRouter/RouterBuilderContext.swift @@ -16,8 +16,8 @@ import Hummingbird import Logging import NIOCore -/// Context data required by `HBRouterBuilder` -public struct HBRouterBuilderContext: Sendable { +/// Context data required by `RouterBuilder` +public struct RouterBuilderContext: Sendable { /// remaining path components to match @usableFromInline var remainingPathComponents: ArraySlice @@ -27,15 +27,15 @@ public struct HBRouterBuilderContext: Sendable { } } -/// Protocol that all request contexts used with HBRouterBuilder should conform to. -public protocol HBRouterRequestContext: HBBaseRequestContext { - var routerContext: HBRouterBuilderContext { get set } +/// Protocol that all request contexts used with RouterBuilder should conform to. +public protocol RouterRequestContext: BaseRequestContext { + var routerContext: RouterBuilderContext { get set } } -/// Basic implementation of a context that can be used with `HBRouterBuilder`` -public struct HBBasicRouterRequestContext: HBRequestContext, HBRouterRequestContext { - public var routerContext: HBRouterBuilderContext - public var coreContext: HBCoreRequestContext +/// Basic implementation of a context that can be used with `RouterBuilder`` +public struct BasicRouterRequestContext: RequestContext, RouterRequestContext { + public var routerContext: RouterBuilderContext + public var coreContext: CoreRequestContext public init(channel: Channel, logger: Logger) { self.coreContext = .init(allocator: channel.allocator, logger: logger) diff --git a/Sources/HummingbirdRouter/RouterPath.swift b/Sources/HummingbirdRouter/RouterPath.swift index 06e336553..e02b226e9 100644 --- a/Sources/HummingbirdRouter/RouterPath.swift +++ b/Sources/HummingbirdRouter/RouterPath.swift @@ -12,10 +12,10 @@ // //===----------------------------------------------------------------------===// -@_spi(HBInternal) import Hummingbird +@_spi(Internal) import Hummingbird extension RouterPath { - func matchAll(_ context: Context) -> Context? { + func matchAll(_ context: Context) -> Context? { if self.components.count != context.routerContext.remainingPathComponents.count { if case .recursiveWildcard = self.components.last { if self.components.count > context.routerContext.remainingPathComponents.count + 1 { @@ -29,14 +29,14 @@ extension RouterPath { } @usableFromInline - func matchPrefix(_ context: Context) -> Context? { + func matchPrefix(_ context: Context) -> Context? { if self.components.count > context.routerContext.remainingPathComponents.count { return nil } return self.match(context) } - private func match(_ context: Context) -> Context? { + private func match(_ context: Context) -> Context? { var pathIterator = context.routerContext.remainingPathComponents.makeIterator() var context = context for component in self.components { diff --git a/Sources/HummingbirdTLS/TLSChannel.swift b/Sources/HummingbirdTLS/TLSChannel.swift index cec4c252e..ba2e81baf 100644 --- a/Sources/HummingbirdTLS/TLSChannel.swift +++ b/Sources/HummingbirdTLS/TLSChannel.swift @@ -18,7 +18,7 @@ import NIOCore import NIOSSL /// Sets up child channel to use TLS before accessing base channel setup -public struct TLSChannel: HBServerChildChannel { +public struct TLSChannel: ServerChildChannel { public typealias Value = BaseChannel.Value /// Initialize TLSChannel @@ -58,7 +58,7 @@ public struct TLSChannel: HBServerChildChanne } extension TLSChannel: HTTPChannelHandler where BaseChannel: HTTPChannelHandler { - public var responder: @Sendable (HBRequest, Channel) async throws -> HBResponse { + public var responder: @Sendable (Request, Channel) async throws -> Response { baseChannel.responder } } diff --git a/Sources/HummingbirdTLS/TLSChannelBuilder.swift b/Sources/HummingbirdTLS/TLSChannelBuilder.swift index 6567ec087..a86ec6239 100644 --- a/Sources/HummingbirdTLS/TLSChannelBuilder.swift +++ b/Sources/HummingbirdTLS/TLSChannelBuilder.swift @@ -15,12 +15,12 @@ import HummingbirdCore import NIOSSL -extension HBHTTPChannelBuilder { +extension HTTPChannelBuilder { /// Build child channel supporting HTTP with TLS /// - /// Use in ``Hummingbird/HBApplication`` initialization. + /// Use in ``Hummingbird/Application`` initialization. /// ``` - /// let app = HBApplication( + /// let app = Application( /// router: router, /// server: .tls(.http1(), tlsConfiguration: tlsConfiguration) /// ) @@ -29,10 +29,10 @@ extension HBHTTPChannelBuilder { /// - base: Base child channel to wrap with TLS /// - tlsConfiguration: TLS configuration /// - Returns: HTTPChannelHandler builder - public static func tls( - _ base: HBHTTPChannelBuilder = .http1(), + public static func tls( + _ base: HTTPChannelBuilder = .http1(), tlsConfiguration: TLSConfiguration - ) throws -> HBHTTPChannelBuilder> { + ) throws -> HTTPChannelBuilder> { return .init { responder in return try TLSChannel(base.build(responder), tlsConfiguration: tlsConfiguration) } diff --git a/Sources/HummingbirdTLS/TLSClientChannel.swift b/Sources/HummingbirdTLS/TLSClientChannel.swift index 52923c276..235c52c46 100644 --- a/Sources/HummingbirdTLS/TLSClientChannel.swift +++ b/Sources/HummingbirdTLS/TLSClientChannel.swift @@ -18,7 +18,7 @@ import NIOCore import NIOSSL /// Sets up client channel to use TLS before accessing base channel setup -public struct TLSClientChannel: HBClientConnectionChannel { +public struct TLSClientChannel: ClientConnectionChannel { public typealias Value = BaseChannel.Value /// Initialize TLSChannel diff --git a/Sources/HummingbirdTesting/Application+Test.swift b/Sources/HummingbirdTesting/Application+Test.swift index f39e4cc09..472276cf1 100644 --- a/Sources/HummingbirdTesting/Application+Test.swift +++ b/Sources/HummingbirdTesting/Application+Test.swift @@ -17,34 +17,34 @@ import HummingbirdCore import NIOCore /// HTTP Scheme to use with AsyncHTTPClient test framework -public enum HBTestHTTPScheme: String { +public enum TestHTTPScheme: String { case http case https } /// Type of test framework -public struct HBTestingSetup { +public struct TestingSetup { enum Internal { case router case live - case ahc(HBTestHTTPScheme) + case ahc(TestHTTPScheme) } let value: Internal /// Test writing requests directly to router. - public static var router: HBTestingSetup { .init(value: .router) } + public static var router: TestingSetup { .init(value: .router) } /// Sets up a live server and execute tests using a HTTP client. Only supports HTTP1 - public static var live: HBTestingSetup { .init(value: .live) } + public static var live: TestingSetup { .init(value: .live) } /// Sets up a live server and execute tests using a HTTP client. Does not support trailer headers - public static func ahc(_ scheme: HBTestHTTPScheme) -> HBTestingSetup { .init(value: .ahc(scheme)) } + public static func ahc(_ scheme: TestHTTPScheme) -> TestingSetup { .init(value: .ahc(scheme)) } } -/// Extends `HBApplicationProtocol` to support testing of applications -extension HBApplicationProtocol where Responder.Context: HBRequestContext { +/// Extends `ApplicationProtocol` to support testing of applications +extension ApplicationProtocol where Responder.Context: RequestContext { // MARK: Initialization - /// Test `HBApplication` + /// Test `Application` /// /// You use `test` and `execute` to test applications. You can either test using /// the `.router` test framework which sends requests directly to the router for testing your code or @@ -55,11 +55,11 @@ extension HBApplicationProtocol where Responder.Context: HBRequestContext { /// /// The example below is using the `.router` framework to test /// ```swift - /// let router = HBRouter() + /// let router = Router() /// router.get("/hello") { _ in /// return "hello" /// } - /// let app = HBApplication(router: router) + /// let app = Application(router: router) /// app.test(.router) { client in /// // does my app return "hello" in the body for this route /// client.execute(uri: "/hello", method: .GET) { response in @@ -72,13 +72,13 @@ extension HBApplicationProtocol where Responder.Context: HBRequestContext { /// - testing: indicates which type of testing framework we want /// - configuration: configuration of application public func test( - _ testingSetup: HBTestingSetup, - _ test: @escaping @Sendable (any HBTestClientProtocol) async throws -> Value + _ testingSetup: TestingSetup, + _ test: @escaping @Sendable (any TestClientProtocol) async throws -> Value ) async throws -> Value { - let app: any HBApplicationTestFramework = switch testingSetup.value { - case .router: try await HBRouterTestFramework(app: self) - case .live: HBLiveTestFramework(app: self) - case .ahc(let scheme): HBAsyncHTTPClientTestFramework(app: self, scheme: scheme) + let app: any ApplicationTestFramework = switch testingSetup.value { + case .router: try await RouterTestFramework(app: self) + case .live: LiveTestFramework(app: self) + case .ahc(let scheme): AsyncHTTPClientTestFramework(app: self, scheme: scheme) } return try await app.run(test) } diff --git a/Sources/HummingbirdTesting/ApplicationTester.swift b/Sources/HummingbirdTesting/ApplicationTester.swift index becf94890..2abc2cd6e 100644 --- a/Sources/HummingbirdTesting/ApplicationTester.swift +++ b/Sources/HummingbirdTesting/ApplicationTester.swift @@ -18,7 +18,7 @@ import NIOCore import ServiceLifecycle /// Response structure returned by testing framework -public struct HBTestResponse: Sendable { +public struct TestResponse: Sendable { public let head: HTTPResponse /// response status public var status: HTTPResponse.Status { self.head.status } @@ -31,7 +31,7 @@ public struct HBTestResponse: Sendable { } /// Errors thrown by testing framework. -struct HBTestError: Error, Equatable { +struct TestError: Error, Equatable { private enum _Internal { case notStarted case noHead @@ -53,17 +53,17 @@ struct HBTestError: Error, Equatable { } /// Protocol for client used by HummingbirdTesting -public protocol HBTestClientProtocol: Sendable { +public protocol TestClientProtocol: Sendable { /// Execute URL request and provide response func executeRequest( uri: String, method: HTTPRequest.Method, headers: HTTPFields, body: ByteBuffer? - ) async throws -> HBTestResponse + ) async throws -> TestResponse } -extension HBTestClientProtocol { +extension TestClientProtocol { /// Send request to associated test framework and call test callback on the response returned /// /// - Parameters: @@ -78,7 +78,7 @@ extension HBTestClientProtocol { method: HTTPRequest.Method, headers: HTTPFields = [:], body: ByteBuffer? = nil, - testCallback: @escaping (HBTestResponse) async throws -> Return = { $0 } + testCallback: @escaping (TestResponse) async throws -> Return = { $0 } ) async throws -> Return { let response = try await executeRequest(uri: uri, method: method, headers: headers, body: body) return try await testCallback(response) @@ -86,10 +86,10 @@ extension HBTestClientProtocol { } /// Protocol for application test framework -protocol HBApplicationTestFramework { +protocol ApplicationTestFramework { /// Associated client for application test - associatedtype Client: HBTestClientProtocol + associatedtype Client: TestClientProtocol /// Run test server - func run(_ test: @escaping @Sendable (any HBTestClientProtocol) async throws -> Value) async throws -> Value + func run(_ test: @escaping @Sendable (any TestClientProtocol) async throws -> Value) async throws -> Value } diff --git a/Sources/HummingbirdTesting/AsyncHTTPClientTestFramework.swift b/Sources/HummingbirdTesting/AsyncHTTPClientTestFramework.swift index 6c92aefda..2c891edb8 100644 --- a/Sources/HummingbirdTesting/AsyncHTTPClientTestFramework.swift +++ b/Sources/HummingbirdTesting/AsyncHTTPClientTestFramework.swift @@ -25,8 +25,8 @@ import ServiceLifecycle import XCTest /// Test using a live server and AsyncHTTPClient as a client -final class HBAsyncHTTPClientTestFramework: HBApplicationTestFramework { - struct Client: HBTestClientProtocol { +final class AsyncHTTPClientTestFramework: ApplicationTestFramework { + struct Client: TestClientProtocol { let client: HTTPClient let urlPrefix: String let timeout: TimeAmount @@ -37,7 +37,7 @@ final class HBAsyncHTTPClientTestFramework: HBApplic method: HTTPRequest.Method, headers: HTTPFields = [:], body: ByteBuffer? = nil - ) async throws -> HBTestResponse { + ) async throws -> TestResponse { let url = "\(self.urlPrefix)\(uri.first == "/" ? "" : "/")\(uri)" var request = HTTPClientRequest(url: url) request.method = .init(method) @@ -49,14 +49,14 @@ final class HBAsyncHTTPClientTestFramework: HBApplic } } - init(app: App, scheme: HBTestHTTPScheme) { + init(app: App, scheme: TestHTTPScheme) { self.timeout = .seconds(15) self.application = TestApplication(base: app) self.scheme = scheme } /// Start tests - func run(_ test: @escaping @Sendable (HBTestClientProtocol) async throws -> Value) async throws -> Value { + func run(_ test: @escaping @Sendable (TestClientProtocol) async throws -> Value) async throws -> Value { try await withThrowingTaskGroup(of: Void.self) { group in let serviceGroup = ServiceGroup( configuration: .init( @@ -90,7 +90,7 @@ final class HBAsyncHTTPClientTestFramework: HBApplic } let application: TestApplication - let scheme: HBTestHTTPScheme + let scheme: TestHTTPScheme let timeout: TimeAmount } diff --git a/Sources/HummingbirdTesting/LiveTestFramework.swift b/Sources/HummingbirdTesting/LiveTestFramework.swift index 22e87768a..b21aa2462 100644 --- a/Sources/HummingbirdTesting/LiveTestFramework.swift +++ b/Sources/HummingbirdTesting/LiveTestFramework.swift @@ -23,9 +23,9 @@ import ServiceLifecycle import XCTest /// Test using a live server -final class HBLiveTestFramework: HBApplicationTestFramework { - struct Client: HBTestClientProtocol { - let client: HBTestClient +final class LiveTestFramework: ApplicationTestFramework { + struct Client: TestClientProtocol { + let client: TestClient /// Send request and call test callback on the response returned func executeRequest( @@ -33,10 +33,10 @@ final class HBLiveTestFramework: HBApplicationTestFr method: HTTPRequest.Method, headers: HTTPFields = [:], body: ByteBuffer? = nil - ) async throws -> HBTestResponse { + ) async throws -> TestResponse { var headers = headers headers[.connection] = "keep-alive" - let request = HBTestClient.Request(uri, method: method, authority: "localhost", headers: headers, body: body) + let request = TestClient.Request(uri, method: method, authority: "localhost", headers: headers, body: body) let response = try await client.execute(request) return .init(head: response.head, body: response.body ?? ByteBuffer(), trailerHeaders: response.trailerHeaders) } @@ -48,7 +48,7 @@ final class HBLiveTestFramework: HBApplicationTestFr } /// Start tests - func run(_ test: @escaping @Sendable (HBTestClientProtocol) async throws -> Value) async throws -> Value { + func run(_ test: @escaping @Sendable (TestClientProtocol) async throws -> Value) async throws -> Value { try await withThrowingTaskGroup(of: Void.self) { group in let serviceGroup = ServiceGroup( configuration: .init( @@ -61,7 +61,7 @@ final class HBLiveTestFramework: HBApplicationTestFr try await serviceGroup.run() } let port = await self.application.portPromise.wait() - let client = HBTestClient( + let client = TestClient( host: "localhost", port: port, configuration: .init(timeout: self.timeout), diff --git a/Sources/HummingbirdTesting/RouterTestFramework.swift b/Sources/HummingbirdTesting/RouterTestFramework.swift index 50a6916d4..67cdd7de8 100644 --- a/Sources/HummingbirdTesting/RouterTestFramework.swift +++ b/Sources/HummingbirdTesting/RouterTestFramework.swift @@ -15,8 +15,8 @@ import Atomics import HTTPTypes import NIOEmbedded -@_spi(HBInternal) import Hummingbird -@_spi(HBInternal) import HummingbirdCore +@_spi(Internal) import Hummingbird +@_spi(Internal) import HummingbirdCore import Logging import NIOConcurrencyHelpers import NIOCore @@ -25,14 +25,14 @@ import NIOPosix import ServiceLifecycle /// Test sending requests directly to router. This does not setup a live server -struct HBRouterTestFramework: HBApplicationTestFramework where Responder.Context: HBBaseRequestContext { +struct RouterTestFramework: ApplicationTestFramework where Responder.Context: BaseRequestContext { let responder: Responder let makeContext: @Sendable (Logger) -> Responder.Context let services: [any Service] let logger: Logger let processesRunBeforeServerStart: [@Sendable () async throws -> Void] - init(app: App) async throws where App.Responder == Responder, Responder.Context: HBRequestContext { + init(app: App) async throws where App.Responder == Responder, Responder.Context: RequestContext { self.responder = try await app.responder self.processesRunBeforeServerStart = app.processesRunBeforeServerStart self.services = app.services @@ -46,7 +46,7 @@ struct HBRouterTestFramework: HBApplicationTestFr } /// Run test - func run(_ test: @escaping @Sendable (HBTestClientProtocol) async throws -> Value) async throws -> Value { + func run(_ test: @escaping @Sendable (TestClientProtocol) async throws -> Value) async throws -> Value { let client = Client( responder: self.responder, logger: self.logger, @@ -88,37 +88,37 @@ struct HBRouterTestFramework: HBApplicationTestFr } } - /// HBRouterTestFramework client. Constructs an `HBRequest` sends it to the router and then converts + /// RouterTestFramework client. Constructs an `Request` sends it to the router and then converts /// resulting response back to test response type - struct Client: HBTestClientProtocol { + struct Client: TestClientProtocol { let responder: Responder let logger: Logger let makeContext: @Sendable (Logger) -> Responder.Context - func executeRequest(uri: String, method: HTTPRequest.Method, headers: HTTPFields, body: ByteBuffer?) async throws -> HBTestResponse { - return try await withThrowingTaskGroup(of: HBTestResponse.self) { group in - let (stream, source) = HBRequestBody.makeStream() - let request = HBRequest( + func executeRequest(uri: String, method: HTTPRequest.Method, headers: HTTPFields, body: ByteBuffer?) async throws -> TestResponse { + return try await withThrowingTaskGroup(of: TestResponse.self) { group in + let (stream, source) = RequestBody.makeStream() + let request = Request( head: .init(method: method, scheme: "http", authority: "localhost", path: uri, headerFields: headers), body: stream ) - let logger = self.logger.with(metadataKey: "hb_id", value: .stringConvertible(RequestID())) + let logger = self.logger.with(metadataKey: "_id", value: .stringConvertible(RequestID())) let context = self.makeContext(logger) group.addTask { - let response: HBResponse + let response: Response do { response = try await self.responder.respond(to: request, context: context) - } catch let error as HBHTTPResponseError { + } catch let error as HTTPResponseError { let httpResponse = error.response(allocator: ByteBufferAllocator()) - response = HBResponse(status: httpResponse.status, headers: httpResponse.headers, body: httpResponse.body) + response = Response(status: httpResponse.status, headers: httpResponse.headers, body: httpResponse.body) } catch { - response = HBResponse(status: .internalServerError) + response = Response(status: .internalServerError) } let responseWriter = RouterResponseWriter() let trailerHeaders = try await response.body.write(responseWriter) return responseWriter.collated.withLockedValue { collated in - HBTestResponse(head: response.head, body: collated, trailerHeaders: trailerHeaders) + TestResponse(head: response.head, body: collated, trailerHeaders: trailerHeaders) } } @@ -135,7 +135,7 @@ struct HBRouterTestFramework: HBApplicationTestFr } } - final class RouterResponseWriter: HBResponseBodyWriter { + final class RouterResponseWriter: ResponseBodyWriter { let collated: NIOLockedValueBox init() { diff --git a/Sources/HummingbirdTesting/TestApplication.swift b/Sources/HummingbirdTesting/TestApplication.swift index eecccde65..82ac6e3d9 100644 --- a/Sources/HummingbirdTesting/TestApplication.swift +++ b/Sources/HummingbirdTesting/TestApplication.swift @@ -18,10 +18,10 @@ import Logging import NIOCore import ServiceLifecycle -/// TestApplication used to wrap HBApplication being tested. +/// TestApplication used to wrap Application being tested. /// /// This is needed to override the `onServerRunning` function -internal struct TestApplication: HBApplicationProtocol, Service { +internal struct TestApplication: ApplicationProtocol, Service { typealias Responder = BaseApp.Responder typealias ChildChannel = BaseApp.ChildChannel @@ -31,14 +31,14 @@ internal struct TestApplication: HBApplicationPr get async throws { try await self.base.responder } } - var server: HBHTTPChannelBuilder { + var server: HTTPChannelBuilder { self.base.server } /// Event loop group used by application var eventLoopGroup: EventLoopGroup { self.base.eventLoopGroup } /// Configuration - var configuration: HBApplicationConfiguration { self.base.configuration.with(address: .hostname("localhost", port: 0)) } + var configuration: ApplicationConfiguration { self.base.configuration.with(address: .hostname("localhost", port: 0)) } /// Logger var logger: Logger { self.base.logger } /// On server running diff --git a/Sources/HummingbirdTesting/TestClient+types.swift b/Sources/HummingbirdTesting/TestClient+types.swift index 968ff0fc0..43568e44a 100644 --- a/Sources/HummingbirdTesting/TestClient+types.swift +++ b/Sources/HummingbirdTesting/TestClient+types.swift @@ -17,7 +17,7 @@ import HTTPTypes import NIOCore /// HTTP client types -extension HBTestClient { +extension TestClient { public enum Error: Swift.Error { case invalidURL case malformedResponse diff --git a/Sources/HummingbirdTesting/TestClient.swift b/Sources/HummingbirdTesting/TestClient.swift index 1ac6ca630..5f1359a79 100644 --- a/Sources/HummingbirdTesting/TestClient.swift +++ b/Sources/HummingbirdTesting/TestClient.swift @@ -23,7 +23,7 @@ import NIOSSL /// /// This HTTP client is used for internal testing of Hummingbird and is also /// the client used by `.live` testing framework. -public struct HBTestClient: Sendable { +public struct TestClient: Sendable { public let channelPromise: EventLoopPromise let eventLoopGroup: EventLoopGroup let eventLoopGroupProvider: NIOEventLoopGroupProvider @@ -31,7 +31,7 @@ public struct HBTestClient: Sendable { let port: Int let configuration: Configuration - /// HBTestClient configuration + /// TestClient configuration public struct Configuration: Sendable { public init( tlsConfiguration: TLSConfiguration? = nil, @@ -51,7 +51,7 @@ public struct HBTestClient: Sendable { public let serverName: String? } - /// Initialize HBTestClient + /// Initialize TestClient /// - Parameters: /// - host: host to connect /// - port: port to connect to @@ -97,7 +97,7 @@ public struct HBTestClient: Sendable { .connect(host: self.host, port: self.port) .cascade(to: self.channelPromise) } catch { - self.channelPromise.fail(HBTestClient.Error.tlsSetupFailed) + self.channelPromise.fail(TestClient.Error.tlsSetupFailed) } } @@ -105,7 +105,7 @@ public struct HBTestClient: Sendable { public func shutdown() async throws { do { try await self.close() - } catch HBTestClient.Error.connectionNotOpen { + } catch TestClient.Error.connectionNotOpen { } catch ChannelError.alreadyClosed {} if case .createNew = self.eventLoopGroupProvider { try await self.eventLoopGroup.shutdownGracefully() @@ -113,45 +113,45 @@ public struct HBTestClient: Sendable { } /// GET request - public func get(_ uri: String, headers: HTTPFields = [:]) async throws -> HBTestClient.Response { - let request = HBTestClient.Request(uri, method: .get, headers: headers) + public func get(_ uri: String, headers: HTTPFields = [:]) async throws -> TestClient.Response { + let request = TestClient.Request(uri, method: .get, headers: headers) return try await self.execute(request) } /// HEAD request - public func head(_ uri: String, headers: HTTPFields = [:]) async throws -> HBTestClient.Response { - let request = HBTestClient.Request(uri, method: .head, headers: headers) + public func head(_ uri: String, headers: HTTPFields = [:]) async throws -> TestClient.Response { + let request = TestClient.Request(uri, method: .head, headers: headers) return try await self.execute(request) } /// PUT request - public func put(_ uri: String, headers: HTTPFields = [:], body: ByteBuffer) async throws -> HBTestClient.Response { - let request = HBTestClient.Request(uri, method: .put, headers: headers, body: body) + public func put(_ uri: String, headers: HTTPFields = [:], body: ByteBuffer) async throws -> TestClient.Response { + let request = TestClient.Request(uri, method: .put, headers: headers, body: body) return try await self.execute(request) } /// POST request - public func post(_ uri: String, headers: HTTPFields = [:], body: ByteBuffer) async throws -> HBTestClient.Response { - let request = HBTestClient.Request(uri, method: .post, headers: headers, body: body) + public func post(_ uri: String, headers: HTTPFields = [:], body: ByteBuffer) async throws -> TestClient.Response { + let request = TestClient.Request(uri, method: .post, headers: headers, body: body) return try await self.execute(request) } /// DELETE request - public func delete(_ uri: String, headers: HTTPFields = [:], body: ByteBuffer) async throws -> HBTestClient.Response { - let request = HBTestClient.Request(uri, method: .delete, headers: headers, body: body) + public func delete(_ uri: String, headers: HTTPFields = [:], body: ByteBuffer) async throws -> TestClient.Response { + let request = TestClient.Request(uri, method: .delete, headers: headers, body: body) return try await self.execute(request) } /// Execute request to server. Return `EventLoopFuture` that will be fulfilled with HTTP response - public func execute(_ request: HBTestClient.Request) async throws -> HBTestClient.Response { + public func execute(_ request: TestClient.Request) async throws -> TestClient.Response { let channel = try await getChannel() - let response = try await withThrowingTaskGroup(of: HBTestClient.Response.self) { group in + let response = try await withThrowingTaskGroup(of: TestClient.Response.self) { group in group.addTask { try await Task.sleep(for: self.configuration.timeout) throw Error.readTimeout } group.addTask { - let promise = self.eventLoopGroup.any().makePromise(of: HBTestClient.Response.self) + let promise = self.eventLoopGroup.any().makePromise(of: TestClient.Response.self) let task = HTTPTask(request: self.cleanupRequest(request), responsePromise: promise) channel.writeAndFlush(task, promise: nil) return try await promise.futureResult.get() @@ -164,7 +164,7 @@ public struct HBTestClient: Sendable { } public func close() async throws { - self.channelPromise.completeWith(.failure(HBTestClient.Error.connectionNotOpen)) + self.channelPromise.completeWith(.failure(TestClient.Error.connectionNotOpen)) let channel = try await getChannel() return try await channel.close() } @@ -173,7 +173,7 @@ public struct HBTestClient: Sendable { try await self.channelPromise.futureResult.get() } - private func cleanupRequest(_ request: HBTestClient.Request) -> HBTestClient.Request { + private func cleanupRequest(_ request: TestClient.Request) -> TestClient.Request { var request = request if let contentLength = request.body.map(\.readableBytes) { request.headers[.contentLength] = String(describing: contentLength) @@ -195,7 +195,7 @@ public struct HBTestClient: Sendable { /// Channel Handler for serializing request header and data private class HTTPClientRequestSerializer: ChannelOutboundHandler { - typealias OutboundIn = HBTestClient.Request + typealias OutboundIn = TestClient.Request typealias OutboundOut = HTTPRequestPart func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { @@ -212,7 +212,7 @@ public struct HBTestClient: Sendable { /// Channel Handler for parsing response from server private class HTTPClientResponseHandler: ChannelInboundHandler { typealias InboundIn = HTTPResponsePart - typealias InboundOut = HBTestClient.Response + typealias InboundOut = TestClient.Response private enum ResponseState { /// Waiting to parse the next response. @@ -236,7 +236,7 @@ public struct HBTestClient: Sendable { body.writeBuffer(&part) self.state = .body(head, body) case (.end(let trailerHeaders), .body(let head, let body)): - let response = HBTestClient.Response( + let response = TestClient.Response( head: head, body: body, trailerHeaders: trailerHeaders @@ -246,7 +246,7 @@ public struct HBTestClient: Sendable { } self.state = .idle case (.end(let trailerHeaders), .head(let head)): - let response = HBTestClient.Response( + let response = TestClient.Response( head: head, body: nil, trailerHeaders: trailerHeaders @@ -256,22 +256,22 @@ public struct HBTestClient: Sendable { } self.state = .idle default: - context.fireErrorCaught(HBTestClient.Error.malformedResponse) + context.fireErrorCaught(TestClient.Error.malformedResponse) } } } /// HTTP Task structure private struct HTTPTask { - let request: HBTestClient.Request - let responsePromise: EventLoopPromise + let request: TestClient.Request + let responsePromise: EventLoopPromise } /// HTTP Task handler. Kicks off HTTP Request and fulfills Response promise when response is returned private class HTTPTaskHandler: ChannelDuplexHandler { - typealias InboundIn = HBTestClient.Response + typealias InboundIn = TestClient.Response typealias OutboundIn = HTTPTask - typealias OutboundOut = HBTestClient.Request + typealias OutboundOut = TestClient.Request var queue: CircularBuffer @@ -311,7 +311,7 @@ public struct HBTestClient: Sendable { switch event { case let evt as IdleStateHandler.IdleStateEvent where evt == .read: while let task = self.queue.popFirst() { - task.responsePromise.fail(HBTestClient.Error.readTimeout) + task.responsePromise.fail(TestClient.Error.readTimeout) } default: diff --git a/Sources/PerformanceTest/main.swift b/Sources/PerformanceTest/main.swift index c95461886..598baeda8 100644 --- a/Sources/PerformanceTest/main.swift +++ b/Sources/PerformanceTest/main.swift @@ -18,13 +18,13 @@ import NIOCore import NIOPosix // get environment -let hostname = HBEnvironment.shared.get("SERVER_HOSTNAME") ?? "127.0.0.1" -let port = HBEnvironment.shared.get("SERVER_PORT", as: Int.self) ?? 8080 +let hostname = Environment.shared.get("SERVER_HOSTNAME") ?? "127.0.0.1" +let port = Environment.shared.get("SERVER_PORT", as: Int.self) ?? 8080 // create app let elg = MultiThreadedEventLoopGroup(numberOfThreads: 4) defer { try? elg.syncShutdownGracefully() } -var router = HBRouter() +var router = Router() // number of raw requests // ./wrk -c 128 -d 15s -t 8 http://localhost:8080 router.get { _, _ in @@ -34,7 +34,7 @@ router.get { _, _ in // request with a body // ./wrk -c 128 -d 15s -t 8 -s scripts/post.lua http://localhost:8080 router.post { request, _ in - return HBResponse(status: .ok, body: .init(asyncSequence: request.body)) + return Response(status: .ok, body: .init(asyncSequence: request.body)) } // return JSON @@ -50,7 +50,7 @@ router.get("wait") { _, _ in return "I waited" } -var app = HBApplication( +var app = Application( responder: router.buildResponder(), configuration: .init( address: .hostname(hostname, port: port), diff --git a/Tests/HummingbirdCoreTests/ClientTests.swift b/Tests/HummingbirdCoreTests/ClientTests.swift index eedc5b273..c5c4e9464 100644 --- a/Tests/HummingbirdCoreTests/ClientTests.swift +++ b/Tests/HummingbirdCoreTests/ClientTests.swift @@ -52,7 +52,7 @@ final class ClientTests: XCTestCase { } func testClient( - server: HBHTTPChannelBuilder, + server: HTTPChannelBuilder, clientTLSConfiguration: ClientTLSConfiguration = .none, eventLoopGroup: EventLoopGroup ) async throws { @@ -63,7 +63,7 @@ final class ClientTests: XCTestCase { }() try await testServer( responder: { request, _ in - return HBResponse(status: .ok, body: .init(asyncSequence: request.body.delayed())) + return Response(status: .ok, body: .init(asyncSequence: request.body.delayed())) }, httpChannelSetup: server, configuration: .init(address: .hostname("127.0.0.1", port: 0)), @@ -87,7 +87,7 @@ final class ClientTests: XCTestCase { } switch clientTLSConfiguration { case .niossl(let tlsConfiguration): - let client = try HBClientConnection( + let client = try ClientConnection( TLSClientChannel(clientChannel, tlsConfiguration: tlsConfiguration, serverHostname: testServerName), address: .hostname("127.0.0.1", port: port), eventLoopGroup: eventLoopGroup, @@ -97,7 +97,7 @@ final class ClientTests: XCTestCase { #if canImport(Network) case .ts(let options): - let client = try HBClientConnection( + let client = try ClientConnection( clientChannel, address: .hostname("127.0.0.1", port: port), transportServicesTLSOptions: options, @@ -107,7 +107,7 @@ final class ClientTests: XCTestCase { try await client.run() #endif case .none: - let client = HBClientConnection( + let client = ClientConnection( clientChannel, address: .hostname("127.0.0.1", port: port), eventLoopGroup: eventLoopGroup, @@ -168,7 +168,7 @@ final class ClientTests: XCTestCase { #endif } -struct HTTP1ClientChannel: HBClientConnectionChannel { +struct HTTP1ClientChannel: ClientConnectionChannel { let handler: @Sendable (NIOAsyncChannelInboundStream, NIOAsyncChannelOutboundWriter) async throws -> Void /// Setup child channel for HTTP1 @@ -201,7 +201,7 @@ struct HTTP1ClientChannel: HBClientConnectionChannel { struct InvalidHTTPPart: Error {} extension NIOAsyncChannelInboundStream.AsyncIterator { - mutating func readResponse() async throws -> HBTestClient.Response { + mutating func readResponse() async throws -> TestClient.Response { let headPart = try await self.next() guard case .head(let head) = headPart else { throw InvalidHTTPPart() } var body = ByteBuffer() @@ -220,7 +220,7 @@ extension NIOAsyncChannelInboundStream.AsyncIterator { } extension NIOAsyncChannelOutboundWriter { - func writeRequest(_ request: HBTestClient.Request) async throws { + func writeRequest(_ request: TestClient.Request) async throws { try await self.write(.head(request.head)) if let body = request.body, body.readableBytes > 0 { try await self.write(.body(body)) diff --git a/Tests/HummingbirdCoreTests/CoreTests.swift b/Tests/HummingbirdCoreTests/CoreTests.swift index 54d3bfb32..c00098929 100644 --- a/Tests/HummingbirdCoreTests/CoreTests.swift +++ b/Tests/HummingbirdCoreTests/CoreTests.swift @@ -70,7 +70,7 @@ class HummingBirdCoreTests: XCTestCase { func testError() async throws { try await testServer( - responder: { _, _ in throw HBHTTPError(.unauthorized) }, + responder: { _, _ in throw HTTPError(.unauthorized) }, httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, @@ -86,7 +86,7 @@ class HummingBirdCoreTests: XCTestCase { try await testServer( responder: { request, _ in let buffer = try await request.body.collect(upTo: .max) - return HBResponse(status: .ok, body: .init(byteBuffer: buffer)) + return Response(status: .ok, body: .init(byteBuffer: buffer)) }, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, @@ -103,7 +103,7 @@ class HummingBirdCoreTests: XCTestCase { try await testServer( responder: { _, _ in let buffer = self.randomBuffer(size: 1_140_000) - return HBResponse(status: .ok, body: .init(byteBuffer: buffer)) + return Response(status: .ok, body: .init(byteBuffer: buffer)) }, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, @@ -118,7 +118,7 @@ class HummingBirdCoreTests: XCTestCase { func testStreamBody() async throws { try await testServer( responder: { request, _ in - return HBResponse(status: .ok, body: .init(asyncSequence: request.body)) + return Response(status: .ok, body: .init(asyncSequence: request.body)) }, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, @@ -134,7 +134,7 @@ class HummingBirdCoreTests: XCTestCase { func testStreamBodyWriteSlow() async throws { try await testServer( responder: { request, _ in - return HBResponse(status: .ok, body: .init(asyncSequence: request.body.delayed())) + return Response(status: .ok, body: .init(asyncSequence: request.body.delayed())) }, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, @@ -162,7 +162,7 @@ class HummingBirdCoreTests: XCTestCase { } try await testServer( responder: { request, _ in - return HBResponse(status: .ok, body: .init(asyncSequence: request.body.delayed())) + return Response(status: .ok, body: .init(asyncSequence: request.body.delayed())) }, httpChannelSetup: .http1(additionalChannelHandlers: [SlowInputChannelHandler()]), configuration: .init(address: .hostname(port: 0)), @@ -196,7 +196,7 @@ class HummingBirdCoreTests: XCTestCase { var seen: Bool = false func channelRead(context: ChannelHandlerContext, data: NIOAny) { if case .body = self.unwrapInboundIn(data) { - context.fireErrorCaught(HBHTTPError(.unavailableForLegalReasons)) + context.fireErrorCaught(HTTPError(.unavailableForLegalReasons)) } context.fireChannelRead(data) } @@ -204,7 +204,7 @@ class HummingBirdCoreTests: XCTestCase { try await testServer( responder: { request, _ in _ = try await request.body.collect(upTo: .max) - return HBResponse(status: .ok) + return Response(status: .ok) }, httpChannelSetup: .http1(additionalChannelHandlers: [CreateErrorHandler()]), configuration: .init(address: .hostname(port: 0)), @@ -221,7 +221,7 @@ class HummingBirdCoreTests: XCTestCase { try await testServer( responder: { _, _ in // ignore request body - return HBResponse(status: .accepted) + return Response(status: .accepted) }, configuration: .init(address: .hostname(port: 0)), eventLoopGroup: Self.eventLoopGroup, @@ -281,7 +281,7 @@ class HummingBirdCoreTests: XCTestCase { do { _ = try await client.get("/", headers: [.connection: "keep-alive"]) XCTFail("Should not get here") - } catch HBTestClient.Error.connectionClosing { + } catch TestClient.Error.connectionClosing { } catch { XCTFail("Unexpected error: \(error)") } @@ -315,7 +315,7 @@ class HummingBirdCoreTests: XCTestCase { responder: { request, _ in await promise.complete(()) try await Task.sleep(for: .milliseconds(500)) - return HBResponse(status: .ok, body: .init(asyncSequence: request.body.delayed())) + return Response(status: .ok, body: .init(asyncSequence: request.body.delayed())) }, httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), @@ -344,7 +344,7 @@ class HummingBirdCoreTests: XCTestCase { try await testServer( responder: { request, _ in try await Task.sleep(for: .milliseconds(500)) - return HBResponse(status: .ok, body: .init(asyncSequence: request.body.delayed())) + return Response(status: .ok, body: .init(asyncSequence: request.body.delayed())) }, httpChannelSetup: .http1(), configuration: .init(address: .hostname(port: 0)), diff --git a/Tests/HummingbirdCoreTests/TestUtils.swift b/Tests/HummingbirdCoreTests/TestUtils.swift index 7dac16e7c..45a13e69a 100644 --- a/Tests/HummingbirdCoreTests/TestUtils.swift +++ b/Tests/HummingbirdCoreTests/TestUtils.swift @@ -25,23 +25,23 @@ public enum TestErrors: Error { } /// Basic responder that just returns "Hello" in body -@Sendable public func helloResponder(to request: HBRequest, channel: Channel) async -> HBResponse { +@Sendable public func helloResponder(to request: Request, channel: Channel) async -> Response { let responseBody = channel.allocator.buffer(string: "Hello") - return HBResponse(status: .ok, body: .init(byteBuffer: responseBody)) + return Response(status: .ok, body: .init(byteBuffer: responseBody)) } /// Helper function for testing a server -public func testServer( +public func testServer( responder: @escaping HTTPChannelHandler.Responder, - httpChannelSetup: HBHTTPChannelBuilder, - configuration: HBServerConfiguration, + httpChannelSetup: HTTPChannelBuilder, + configuration: ServerConfiguration, eventLoopGroup: EventLoopGroup, logger: Logger, - _ test: @escaping @Sendable (HBServer, Int) async throws -> Value + _ test: @escaping @Sendable (Server, Int) async throws -> Value ) async throws -> Value { try await withThrowingTaskGroup(of: Void.self) { group in let promise = Promise() - let server = try HBServer( + let server = try Server( childChannelSetup: httpChannelSetup.build(responder), configuration: configuration, onServerRunning: { await promise.complete($0.localAddress!.port!) }, @@ -68,14 +68,14 @@ public func testServer( /// /// Creates test client, runs test function abd ensures everything is /// shutdown correctly -public func testServer( +public func testServer( responder: @escaping HTTPChannelHandler.Responder, - httpChannelSetup: HBHTTPChannelBuilder, - configuration: HBServerConfiguration, + httpChannelSetup: HTTPChannelBuilder, + configuration: ServerConfiguration, eventLoopGroup: EventLoopGroup, logger: Logger, - clientConfiguration: HBTestClient.Configuration = .init(), - _ test: @escaping @Sendable (HBServer, HBTestClient) async throws -> Value + clientConfiguration: TestClient.Configuration = .init(), + _ test: @escaping @Sendable (Server, TestClient) async throws -> Value ) async throws -> Value { try await testServer( responder: responder, @@ -83,8 +83,8 @@ public func testServer( configuration: configuration, eventLoopGroup: eventLoopGroup, logger: logger - ) { (server: HBServer, port: Int) in - let client = HBTestClient( + ) { (server: Server, port: Int) in + let client = TestClient( host: "localhost", port: port, configuration: clientConfiguration, @@ -99,12 +99,12 @@ public func testServer( public func testServer( responder: @escaping HTTPChannelHandler.Responder, - httpChannelSetup: HBHTTPChannelBuilder = .http1(), - configuration: HBServerConfiguration, + httpChannelSetup: HTTPChannelBuilder = .http1(), + configuration: ServerConfiguration, eventLoopGroup: EventLoopGroup, logger: Logger, - clientConfiguration: HBTestClient.Configuration = .init(), - _ test: @escaping @Sendable (HBTestClient) async throws -> Value + clientConfiguration: TestClient.Configuration = .init(), + _ test: @escaping @Sendable (TestClient) async throws -> Value ) async throws -> Value { try await testServer( responder: responder, diff --git a/Tests/HummingbirdJobsTests/HummingbirdJobsTests.swift b/Tests/HummingbirdJobsTests/HummingbirdJobsTests.swift index 7c40ce40d..4e98f0c23 100644 --- a/Tests/HummingbirdJobsTests/HummingbirdJobsTests.swift +++ b/Tests/HummingbirdJobsTests/HummingbirdJobsTests.swift @@ -62,8 +62,8 @@ final class HummingbirdJobsTests: XCTestCase { func testBasic() async throws { let expectation = XCTestExpectation(description: "TestJob.execute was called", expectedFulfillmentCount: 10) - let jobQueue = HBJobQueue(.memory, numWorkers: 1, logger: Logger(label: "HummingbirdJobsTests")) - let job = HBJobDefinition(id: "testBasic") { (parameters: Int, context) in + let jobQueue = JobQueue(.memory, numWorkers: 1, logger: Logger(label: "HummingbirdJobsTests")) + let job = JobDefinition(id: "testBasic") { (parameters: Int, context) in context.logger.info("Parameters=\(parameters)") try await Task.sleep(for: .milliseconds(Int.random(in: 10..<50))) expectation.fulfill() @@ -86,12 +86,12 @@ final class HummingbirdJobsTests: XCTestCase { } func testMultipleWorkers() async throws { - let jobIdentifer = HBJobIdentifier(#function) + let jobIdentifer = JobIdentifier(#function) let runningJobCounter = ManagedAtomic(0) let maxRunningJobCounter = ManagedAtomic(0) let expectation = XCTestExpectation(description: "TestJob.execute was called", expectedFulfillmentCount: 10) - let jobQueue = HBJobQueue(.memory, numWorkers: 4, logger: Logger(label: "HummingbirdJobsTests")) + let jobQueue = JobQueue(.memory, numWorkers: 4, logger: Logger(label: "HummingbirdJobsTests")) jobQueue.registerJob(jobIdentifer) { parameters, context in let runningJobs = runningJobCounter.wrappingIncrementThenLoad(by: 1, ordering: .relaxed) if runningJobs > maxRunningJobCounter.load(ordering: .relaxed) { @@ -122,14 +122,14 @@ final class HummingbirdJobsTests: XCTestCase { } func testErrorRetryCount() async throws { - let jobIdentifer = HBJobIdentifier(#function) + let jobIdentifer = JobIdentifier(#function) let expectation = XCTestExpectation(description: "TestJob.execute was called", expectedFulfillmentCount: 4) let failedJobCount = ManagedAtomic(0) struct FailedError: Error {} var logger = Logger(label: "HummingbirdJobsTests") logger.logLevel = .trace - let jobQueue = HBJobQueue( - HBMemoryQueue { _, _ in failedJobCount.wrappingIncrement(by: 1, ordering: .relaxed) }, + let jobQueue = JobQueue( + MemoryQueue { _, _ in failedJobCount.wrappingIncrement(by: 1, ordering: .relaxed) }, logger: logger ) jobQueue.registerJob(jobIdentifer, maxRetryCount: 3) { _, _ in @@ -150,8 +150,8 @@ final class HummingbirdJobsTests: XCTestCase { let message: String } let expectation = XCTestExpectation(description: "TestJob.execute was called") - let jobIdentifer = HBJobIdentifier(#function) - let jobQueue = HBJobQueue(.memory, numWorkers: 1, logger: Logger(label: "HummingbirdJobsTests")) + let jobIdentifer = JobIdentifier(#function) + let jobQueue = JobQueue(.memory, numWorkers: 1, logger: Logger(label: "HummingbirdJobsTests")) jobQueue.registerJob(jobIdentifer) { parameters, _ in XCTAssertEqual(parameters.id, 23) XCTAssertEqual(parameters.message, "Hello!") @@ -166,14 +166,14 @@ final class HummingbirdJobsTests: XCTestCase { /// Verify test job is cancelled when service group is cancelled func testShutdownJob() async throws { - let jobIdentifer = HBJobIdentifier(#function) + let jobIdentifer = JobIdentifier(#function) let expectation = XCTestExpectation(description: "TestJob.execute was called", expectedFulfillmentCount: 1) let cancelledJobCount = ManagedAtomic(0) var logger = Logger(label: "HummingbirdJobsTests") logger.logLevel = .trace - let jobQueue = HBJobQueue( - HBMemoryQueue { _, error in + let jobQueue = JobQueue( + MemoryQueue { _, error in if error is CancellationError { cancelledJobCount.wrappingIncrement(by: 1, ordering: .relaxed) } @@ -207,13 +207,13 @@ final class HummingbirdJobsTests: XCTestCase { /// test job fails to decode but queue continues to process func testFailToDecode() async throws { let string: NIOLockedValueBox = .init("") - let jobIdentifer1 = HBJobIdentifier(#function) - let jobIdentifer2 = HBJobIdentifier(#function) + let jobIdentifer1 = JobIdentifier(#function) + let jobIdentifer2 = JobIdentifier(#function) let expectation = XCTestExpectation(description: "job was called", expectedFulfillmentCount: 1) var logger = Logger(label: "HummingbirdJobsTests") logger.logLevel = .debug - let jobQueue = HBJobQueue(.memory, numWorkers: 1, logger: Logger(label: "HummingbirdJobsTests")) + let jobQueue = JobQueue(.memory, numWorkers: 1, logger: Logger(label: "HummingbirdJobsTests")) jobQueue.registerJob(jobIdentifer2) { parameters, _ in string.withLockedValue { $0 = parameters } expectation.fulfill() @@ -229,9 +229,9 @@ final class HummingbirdJobsTests: XCTestCase { } func testMultipleJobQueueHandlers() async throws { - let jobIdentifer = HBJobIdentifier(#function) + let jobIdentifer = JobIdentifier(#function) let expectation = XCTestExpectation(description: "TestJob.execute was called", expectedFulfillmentCount: 200) - let job = HBJobDefinition(id: jobIdentifer) { parameters, context in + let job = JobDefinition(id: jobIdentifer) { parameters, context in context.logger.info("Parameters=\(parameters)") try await Task.sleep(for: .milliseconds(Int.random(in: 10..<50))) expectation.fulfill() @@ -241,9 +241,9 @@ final class HummingbirdJobsTests: XCTestCase { logger.logLevel = .debug return logger }() - let jobQueue = HBJobQueue(.memory, numWorkers: 2, logger: Logger(label: "HummingbirdJobsTests")) + let jobQueue = JobQueue(.memory, numWorkers: 2, logger: Logger(label: "HummingbirdJobsTests")) jobQueue.registerJob(job) - let jobQueue2 = HBJobQueue(.memory, numWorkers: 1, logger: Logger(label: "HummingbirdJobsTests")) + let jobQueue2 = JobQueue(.memory, numWorkers: 1, logger: Logger(label: "HummingbirdJobsTests")) jobQueue2.registerJob(job) try await withThrowingTaskGroup(of: Void.self) { group in diff --git a/Tests/HummingbirdRouterTests/MiddlewareTests.swift b/Tests/HummingbirdRouterTests/MiddlewareTests.swift index 56d4e27d2..daf388d45 100644 --- a/Tests/HummingbirdRouterTests/MiddlewareTests.swift +++ b/Tests/HummingbirdRouterTests/MiddlewareTests.swift @@ -28,20 +28,20 @@ final class MiddlewareTests: XCTestCase { } func testMiddleware() async throws { - struct TestMiddleware: HBRouterMiddleware { - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestMiddleware: RouterMiddleware { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var response = try await next(request, context) response.headers[.middleware] = "TestMiddleware" return response } } - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { TestMiddleware() Get("/hello") { _, _ -> String in return "Hello" } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { response in XCTAssertEqual(response.headers[.middleware], "TestMiddleware") @@ -50,22 +50,22 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareOrder() async throws { - struct TestMiddleware: HBRouterMiddleware { + struct TestMiddleware: RouterMiddleware { let string: String - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var response = try await next(request, context) response.headers[values: .middleware].append(self.string) return response } } - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { TestMiddleware(string: "first") TestMiddleware(string: "second") Get("/hello") { _, _ -> String in return "Hello" } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { response in // headers come back in opposite order as middleware is applied to responses in that order @@ -76,21 +76,21 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareRunOnce() async throws { - struct TestMiddleware: HBRouterMiddleware { - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestMiddleware: RouterMiddleware { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var response = try await next(request, context) XCTAssertNil(response.headers[.alreadyRun]) response.headers[.alreadyRun] = "true" return response } } - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { TestMiddleware() Get("/hello") { _, _ -> String in return "Hello" } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { _ in } @@ -98,19 +98,19 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareRunWhenNoRouteFound() async throws { - struct TestMiddleware: HBRouterMiddleware { - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestMiddleware: RouterMiddleware { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { do { return try await next(request, context) - } catch let error as HBHTTPError where error.status == .notFound { - throw HBHTTPError(.notFound, message: "Edited error") + } catch let error as HTTPError where error.status == .notFound { + throw HTTPError(.notFound, message: "Edited error") } } } - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { TestMiddleware() } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { response in @@ -121,8 +121,8 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareResponseBodyWriter() async throws { - struct TransformWriter: HBResponseBodyWriter { - let parentWriter: any HBResponseBodyWriter + struct TransformWriter: ResponseBodyWriter { + let parentWriter: any ResponseBodyWriter let allocator: ByteBufferAllocator func write(_ buffer: ByteBuffer) async throws { @@ -130,8 +130,8 @@ final class MiddlewareTests: XCTestCase { try await self.parentWriter.write(output) } } - struct TransformMiddleware: HBRouterMiddleware { - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TransformMiddleware: RouterMiddleware { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { let response = try await next(request, context) var editedResponse = response editedResponse.body = .withTrailingHeaders { writer in @@ -142,15 +142,15 @@ final class MiddlewareTests: XCTestCase { return editedResponse } } - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { RouteGroup("") { TransformMiddleware() Get("test") { request, _ in - return HBResponse(status: .ok, body: .init(asyncSequence: request.body)) + return Response(status: .ok, body: .init(asyncSequence: request.body)) } } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in let buffer = self.randomBuffer(size: 64000) diff --git a/Tests/HummingbirdRouterTests/RouterTests.swift b/Tests/HummingbirdRouterTests/RouterTests.swift index 08a24c3b2..20859f766 100644 --- a/Tests/HummingbirdRouterTests/RouterTests.swift +++ b/Tests/HummingbirdRouterTests/RouterTests.swift @@ -20,14 +20,14 @@ import NIOCore import XCTest final class RouterTests: XCTestCase { - struct TestMiddleware: HBRouterMiddleware { + struct TestMiddleware: RouterMiddleware { let output: String init(_ output: String = "TestMiddleware") { self.output = output } - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var response = try await next(request, context) response.headers[.middleware] = self.output return response @@ -36,21 +36,21 @@ final class RouterTests: XCTestCase { /// Test endpointPath is set func testEndpointPath() async throws { - struct TestEndpointMiddleware: HBRouterMiddleware { - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestEndpointMiddleware: RouterMiddleware { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { _ = try await next(request, context) guard let endpointPath = context.endpointPath else { return try await next(request, context) } return .init(status: .ok, body: .init(byteBuffer: ByteBuffer(string: endpointPath))) } } - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { TestEndpointMiddleware() Get("/test/{number}") { _, _ in return "xxx" } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/test/1", method: .get) { response in @@ -61,15 +61,15 @@ final class RouterTests: XCTestCase { /// Test endpointPath is prefixed with a "/" func testEndpointPathPrefix() async throws { - struct TestEndpointMiddleware: HBRouterMiddleware { - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestEndpointMiddleware: RouterMiddleware { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { _ = try await next(request, context) guard let endpointPath = context.endpointPath else { return try await next(request, context) } return .init(status: .ok, body: .init(byteBuffer: ByteBuffer(string: endpointPath))) } } - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { TestEndpointMiddleware() Get("test") { _, context in return context.endpointPath @@ -81,7 +81,7 @@ final class RouterTests: XCTestCase { return context.endpointPath } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/", method: .get) { response in @@ -98,14 +98,14 @@ final class RouterTests: XCTestCase { /// Test endpointPath doesn't have "/" at end func testEndpointPathSuffix() async throws { - struct TestEndpointMiddleware: HBRouterMiddleware { - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestEndpointMiddleware: RouterMiddleware { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { guard let endpointPath = context.endpointPath else { return try await next(request, context) } return .init(status: .ok, body: .init(byteBuffer: ByteBuffer(string: endpointPath))) } } - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { TestEndpointMiddleware() Get("test/") { _, context in return context.endpointPath @@ -124,7 +124,7 @@ final class RouterTests: XCTestCase { } } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/test/", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "/test") @@ -146,7 +146,7 @@ final class RouterTests: XCTestCase { /// Test correct endpoints are called from group func testMethodEndpoint() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { RouteGroup("/endpoint") { Get { _, _ in return "GET" @@ -156,7 +156,7 @@ final class RouterTests: XCTestCase { } } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/endpoint", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "GET") @@ -171,7 +171,7 @@ final class RouterTests: XCTestCase { /// Test middle in group is applied to group but not to routes outside /// group func testGroupMiddleware() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { RouteGroup("/group") { TestMiddleware() Get { _, _ in @@ -182,7 +182,7 @@ final class RouterTests: XCTestCase { return "hello" } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/group", method: .get) { response in XCTAssertEqual(response.headers[.middleware], "TestMiddleware") @@ -195,7 +195,7 @@ final class RouterTests: XCTestCase { } func testEndpointMiddleware() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { RouteGroup("/group") { TestMiddleware() Head { _, _ in @@ -203,7 +203,7 @@ final class RouterTests: XCTestCase { } } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/group", method: .head) { response in XCTAssertEqual(response.headers[.middleware], "TestMiddleware") @@ -213,7 +213,7 @@ final class RouterTests: XCTestCase { /// Test middleware in parent group is applied to routes in child group func testGroupGroupMiddleware() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { RouteGroup("/test") { TestMiddleware() RouteGroup("/group") { @@ -223,7 +223,7 @@ final class RouterTests: XCTestCase { } } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/test/group", method: .get) { response in XCTAssertEqual(response.headers[.middleware], "TestMiddleware") @@ -233,18 +233,18 @@ final class RouterTests: XCTestCase { /// Test adding middleware to group doesn't affect middleware in parent groups func testGroupGroupMiddleware2() async throws { - struct TestGroupMiddleware: HBRouterMiddleware { - typealias Context = HBTestRouterContext2 + struct TestGroupMiddleware: RouterMiddleware { + typealias Context = TestRouterContext2 let output: String - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var context = context context.string = self.output return try await next(request, context) } } - let router = HBRouterBuilder(context: HBTestRouterContext2.self) { + let router = RouterBuilder(context: TestRouterContext2.self) { RouteGroup("/test") { TestGroupMiddleware(output: "route1") Get { _, context in @@ -258,7 +258,7 @@ final class RouterTests: XCTestCase { } } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/test/group", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "route2") @@ -271,21 +271,21 @@ final class RouterTests: XCTestCase { /// Test adding middleware to group doesn't affect middleware in parent groups func testRouteBuilder() async throws { - struct TestGroupMiddleware: HBRouterMiddleware { - typealias Context = HBTestRouterContext2 + struct TestGroupMiddleware: RouterMiddleware { + typealias Context = TestRouterContext2 let output: String - func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var context = context context.string += self.output return try await next(request, context) } } - @Sendable func handle(_: HBRequest, _ context: HBTestRouterContext2) async throws -> String { + @Sendable func handle(_: Request, _ context: TestRouterContext2) async throws -> String { context.string } - let router = HBRouterBuilder(context: HBTestRouterContext2.self) { + let router = RouterBuilder(context: TestRouterContext2.self) { RouteGroup("/test") { Get { TestGroupMiddleware(output: "route1") @@ -299,7 +299,7 @@ final class RouterTests: XCTestCase { } } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/test", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "route1") @@ -311,12 +311,12 @@ final class RouterTests: XCTestCase { } func testParameters() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { Delete("/user/:id") { _, context -> String? in return context.parameters.get("id", as: String.self) } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/user/1234", method: .delete) { response in XCTAssertEqual(String(buffer: response.body), "1234") @@ -325,13 +325,13 @@ final class RouterTests: XCTestCase { } func testParameterCollection() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { Delete("/user/:username/:id") { _, context -> String? in XCTAssertEqual(context.parameters.count, 2) return context.parameters.get("id", as: String.self) } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/user/john/1234", method: .delete) { response in XCTAssertEqual(String(buffer: response.body), "1234") @@ -340,7 +340,7 @@ final class RouterTests: XCTestCase { } func testPartialCapture() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { Route(.get, "/files/file.{ext}/{name}.jpg") { _, context -> String in XCTAssertEqual(context.parameters.count, 2) let ext = try context.parameters.require("ext") @@ -348,7 +348,7 @@ final class RouterTests: XCTestCase { return "\(name).\(ext)" } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/files/file.doc/test.jpg", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "test.doc") @@ -357,12 +357,12 @@ final class RouterTests: XCTestCase { } func testPartialWildcard() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { Get("/files/file.*/*.jpg") { _, _ -> HTTPResponse.Status in return .ok } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/files/file.doc/test.jpg", method: .get) { response in XCTAssertEqual(response.status, .ok) @@ -375,12 +375,12 @@ final class RouterTests: XCTestCase { /// Test we have a request id and that it increments with each request func testRequestId() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { Get("id") { _, context in return context.id.description } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in let id = try await client.execute(uri: "/id", method: .get) { response -> String in return String(buffer: response.body) @@ -394,12 +394,12 @@ final class RouterTests: XCTestCase { // Test redirect response func testRedirect() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { Get("redirect") { _, _ in - return HBResponse.redirect(to: "/other") + return Response.redirect(to: "/other") } } - let app = HBApplication(responder: router) + let app = Application(responder: router) try await app.test(.router) { client in try await client.execute(uri: "/redirect", method: .get) { response in XCTAssertEqual(response.headers[.location], "/other") @@ -409,12 +409,12 @@ final class RouterTests: XCTestCase { } func testResponderBuilder() async throws { - let router = HBRouterBuilder(context: HBBasicRouterRequestContext.self) { + let router = RouterBuilder(context: BasicRouterRequestContext.self) { Get("hello") { _, _ in return "hello" } } - let app = HBApplication(router: router) + let app = Application(router: router) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "hello") @@ -423,11 +423,11 @@ final class RouterTests: XCTestCase { } } -public struct HBTestRouterContext2: HBRouterRequestContext, HBRequestContext { +public struct TestRouterContext2: RouterRequestContext, RequestContext { /// router context - public var routerContext: HBRouterBuilderContext + public var routerContext: RouterBuilderContext /// core context - public var coreContext: HBCoreRequestContext + public var coreContext: CoreRequestContext /// Connected remote host public var remoteAddress: SocketAddress? { nil } diff --git a/Tests/HummingbirdTests/ApplicationTests.swift b/Tests/HummingbirdTests/ApplicationTests.swift index 922700554..f58c62b91 100644 --- a/Tests/HummingbirdTests/ApplicationTests.swift +++ b/Tests/HummingbirdTests/ApplicationTests.swift @@ -33,11 +33,11 @@ final class ApplicationTests: XCTestCase { } func testGetRoute() async throws { - let router = HBRouter() + let router = Router() router.get("/hello") { _, context -> ByteBuffer in return context.allocator.buffer(string: "GET: Hello") } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { response in XCTAssertEqual(response.status, .ok) @@ -47,11 +47,11 @@ final class ApplicationTests: XCTestCase { } func testHTTPStatusRoute() async throws { - let router = HBRouter() + let router = Router() router.get("/accepted") { _, _ -> HTTPResponse.Status in return .accepted } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/accepted", method: .get) { response in XCTAssertEqual(response.status, .accepted) @@ -60,11 +60,11 @@ final class ApplicationTests: XCTestCase { } func testStandardHeaders() async throws { - let router = HBRouter() + let router = Router() router.get("/hello") { _, _ in return "Hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.live) { client in try await client.execute(uri: "/hello", method: .get) { response in XCTAssertEqual(response.headers[.contentLength], "5") @@ -74,11 +74,11 @@ final class ApplicationTests: XCTestCase { } func testServerHeaders() async throws { - let router = HBRouter() + let router = Router() router.get("/hello") { _, _ in return "Hello" } - let app = HBApplication(responder: router.buildResponder(), configuration: .init(serverName: "TestServer")) + let app = Application(responder: router.buildResponder(), configuration: .init(serverName: "TestServer")) try await app.test(.live) { client in try await client.execute(uri: "/hello", method: .get) { response in XCTAssertEqual(response.headers[.server], "TestServer") @@ -87,11 +87,11 @@ final class ApplicationTests: XCTestCase { } func testPostRoute() async throws { - let router = HBRouter() + let router = Router() router.post("/hello") { _, _ -> String in return "POST: Hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .post) { response in @@ -102,14 +102,14 @@ final class ApplicationTests: XCTestCase { } func testMultipleMethods() async throws { - let router = HBRouter() + let router = Router() router.post("/hello") { _, _ -> String in return "POST" } router.get("/hello") { _, _ -> String in return "GET" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { response in @@ -122,7 +122,7 @@ final class ApplicationTests: XCTestCase { } func testMultipleGroupMethods() async throws { - let router = HBRouter() + let router = Router() router.group("hello") .post { _, _ -> String in return "POST" @@ -130,7 +130,7 @@ final class ApplicationTests: XCTestCase { .get { _, _ -> String in return "GET" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { response in @@ -143,11 +143,11 @@ final class ApplicationTests: XCTestCase { } func testQueryRoute() async throws { - let router = HBRouter() + let router = Router() router.post("/query") { request, context -> ByteBuffer in return context.allocator.buffer(string: request.uri.queryParameters["test"].map { String($0) } ?? "") } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/query?test=test%20data%C3%A9", method: .post) { response in @@ -158,11 +158,11 @@ final class ApplicationTests: XCTestCase { } func testMultipleQueriesRoute() async throws { - let router = HBRouter() + let router = Router() router.post("/add") { request, _ -> String in return request.uri.queryParameters.getAll("value", as: Int.self).reduce(0,+).description } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/add?value=3&value=45&value=7", method: .post) { response in @@ -173,11 +173,11 @@ final class ApplicationTests: XCTestCase { } func testArray() async throws { - let router = HBRouter() + let router = Router() router.get("array") { _, _ -> [String] in return ["yes", "no"] } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/array", method: .get) { response in @@ -187,14 +187,14 @@ final class ApplicationTests: XCTestCase { } func testResponseBody() async throws { - let router = HBRouter() + let router = Router() router .group("/echo-body") - .post { request, _ -> HBResponse in + .post { request, _ -> Response in let buffer = try await request.body.collect(upTo: .max) return .init(status: .ok, headers: [:], body: .init(byteBuffer: buffer)) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let buffer = self.randomBuffer(size: 1_140_000) @@ -207,9 +207,9 @@ final class ApplicationTests: XCTestCase { /// Test streaming of requests and streaming of responses by streaming the request body into a response streamer func testStreaming() async throws { - let router = HBRouter() - router.post("streaming") { request, _ -> HBResponse in - return HBResponse(status: .ok, body: .init(asyncSequence: request.body)) + let router = Router() + router.post("streaming") { request, _ -> Response in + return Response(status: .ok, body: .init(asyncSequence: request.body)) } router.post("size") { request, _ -> String in var size = 0 @@ -218,7 +218,7 @@ final class ApplicationTests: XCTestCase { } return size.description } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in @@ -239,11 +239,11 @@ final class ApplicationTests: XCTestCase { /// Test streaming of requests and streaming of responses by streaming the request body into a response streamer func testStreamingSmallBuffer() async throws { - let router = HBRouter() - router.post("streaming") { request, _ -> HBResponse in - return HBResponse(status: .ok, body: .init(asyncSequence: request.body)) + let router = Router() + router.post("streaming") { request, _ -> Response in + return Response(status: .ok, body: .init(asyncSequence: request.body)) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let buffer = self.randomBuffer(size: 64) try await client.execute(uri: "/streaming", method: .post, body: buffer) { response in @@ -258,20 +258,20 @@ final class ApplicationTests: XCTestCase { } func testCollateBody() async throws { - struct CollateMiddleware: HBRouterMiddleware { - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct CollateMiddleware: RouterMiddleware { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var request = request _ = try await request.collateBody(context: context) return try await next(request, context) } } - let router = HBRouter() + let router = Router() router.middlewares.add(CollateMiddleware()) router.put("/hello") { request, _ -> String in let buffer = try await request.body.collect(upTo: .max) return buffer.readableBytes.description } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let buffer = self.randomBuffer(size: 512_000) @@ -283,7 +283,7 @@ final class ApplicationTests: XCTestCase { } func testDoubleStreaming() async throws { - let router = HBRouter() + let router = Router() router.post("size") { request, context -> String in var request = request _ = try await request.collateBody(context: context) @@ -293,7 +293,7 @@ final class ApplicationTests: XCTestCase { } return size.description } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let buffer = self.randomBuffer(size: 100_000) @@ -304,14 +304,14 @@ final class ApplicationTests: XCTestCase { } func testOptional() async throws { - let router = HBRouter() + let router = Router() router .group("/echo-body") .post { request, _ -> ByteBuffer? in let buffer = try await request.body.collect(upTo: .max) return buffer.readableBytes > 0 ? buffer : nil } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let buffer = self.randomBuffer(size: 64) @@ -326,8 +326,8 @@ final class ApplicationTests: XCTestCase { } func testOptionalCodable() async throws { - struct SortedJSONRequestContext: HBRequestContext { - var coreContext: HBCoreRequestContext + struct SortedJSONRequestContext: RequestContext { + var coreContext: CoreRequestContext var responseEncoder: JSONEncoder { let encoder = JSONEncoder() encoder.outputFormatting = .sortedKeys @@ -338,17 +338,17 @@ final class ApplicationTests: XCTestCase { self.coreContext = .init(allocator: channel.allocator, logger: logger) } } - struct Name: HBResponseCodable { + struct Name: ResponseCodable { let first: String let last: String } - let router = HBRouter(context: SortedJSONRequestContext.self) + let router = Router(context: SortedJSONRequestContext.self) router .group("/name") .patch { _, _ -> Name? in return Name(first: "john", last: "smith") } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/name", method: .patch) { response in @@ -358,15 +358,15 @@ final class ApplicationTests: XCTestCase { } func testTypedResponse() async throws { - let router = HBRouter() + let router = Router() router.delete("/hello") { _, _ in - return HBEditedResponse( + return EditedResponse( status: .preconditionRequired, headers: [.test: "value", .contentType: "application/json"], response: "Hello" ) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .delete) { response in @@ -379,18 +379,18 @@ final class ApplicationTests: XCTestCase { } func testCodableTypedResponse() async throws { - struct Result: HBResponseEncodable { + struct Result: ResponseEncodable { let value: String } - let router = HBRouter() + let router = Router() router.patch("/hello") { _, _ in - return HBEditedResponse( + return EditedResponse( status: .multipleChoices, headers: [.test: "value", .contentType: "application/json"], response: Result(value: "true") ) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .patch) { response in @@ -403,15 +403,15 @@ final class ApplicationTests: XCTestCase { } func testMaxUploadSize() async throws { - struct MaxUploadRequestContext: HBRequestContext { + struct MaxUploadRequestContext: RequestContext { init(channel: Channel, logger: Logger) { self.coreContext = .init(allocator: channel.allocator, logger: logger) } - var coreContext: HBCoreRequestContext + var coreContext: CoreRequestContext var maxUploadSize: Int { 64 * 1024 } } - let router = HBRouter(context: MaxUploadRequestContext.self) + let router = Router(context: MaxUploadRequestContext.self) router.post("upload") { request, context in _ = try await request.body.collect(upTo: context.maxUploadSize) return "ok" @@ -419,7 +419,7 @@ final class ApplicationTests: XCTestCase { router.post("stream") { _, _ in "ok" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.live) { client in let buffer = self.randomBuffer(size: 128 * 1024) // check non streamed route throws an error @@ -435,9 +435,9 @@ final class ApplicationTests: XCTestCase { func testRemoteAddress() async throws { /// Implementation of a basic request context that supports everything the Hummingbird library needs - struct HBSocketAddressRequestContext: HBRequestContext { + struct SocketAddressRequestContext: RequestContext { /// core context - var coreContext: HBCoreRequestContext + var coreContext: CoreRequestContext // socket address let remoteAddress: SocketAddress? @@ -449,7 +449,7 @@ final class ApplicationTests: XCTestCase { self.remoteAddress = channel.remoteAddress } } - let router = HBRouter(context: HBSocketAddressRequestContext.self) + let router = Router(context: SocketAddressRequestContext.self) router.get("/") { _, context -> String in switch context.remoteAddress { case .v4(let address): @@ -457,10 +457,10 @@ final class ApplicationTests: XCTestCase { case .v6(let address): return String(describing: address.host) default: - throw HBHTTPError(.internalServerError) + throw HTTPError(.internalServerError) } } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.live) { client in try await client.execute(uri: "/", method: .get) { response in @@ -471,15 +471,15 @@ final class ApplicationTests: XCTestCase { } } - /// test we can create an application and pass it around as a `some HBApplicationProtocol`. This + /// test we can create an application and pass it around as a `some ApplicationProtocol`. This /// is more a compilation test than a runtime test func testApplicationProtocolReturnValue() async throws { - func createApplication() -> some HBApplicationProtocol { - let router = HBRouter() + func createApplication() -> some ApplicationProtocol { + let router = Router() router.get("/hello") { _, context -> ByteBuffer in return context.allocator.buffer(string: "GET: Hello") } - return HBApplication(responder: router.buildResponder()) + return Application(responder: router.buildResponder()) } let app = createApplication() try await app.test(.live) { client in @@ -490,13 +490,13 @@ final class ApplicationTests: XCTestCase { } } - /// test we can create out own application type conforming to HBApplicationProtocol + /// test we can create out own application type conforming to ApplicationProtocol func testApplicationProtocol() async throws { - struct MyApp: HBApplicationProtocol { - typealias Context = HBBasicRequestContext + struct MyApp: ApplicationProtocol { + typealias Context = BasicRequestContext - var responder: some HBRequestResponder { - let router = HBRouter(context: Context.self) + var responder: some RequestResponder { + let router = Router(context: Context.self) router.get("/hello") { _, context -> ByteBuffer in return context.allocator.buffer(string: "GET: Hello") } @@ -522,8 +522,8 @@ final class ApplicationTests: XCTestCase { Self.shutdown.store(true, ordering: .relaxed) } } - let router = HBRouter() - var app = HBApplication(responder: router.buildResponder()) + let router = Router() + var app = Application(responder: router.buildResponder()) app.addServices(MyService()) try await app.test(.live) { _ in XCTAssertEqual(MyService.started.load(ordering: .relaxed), true) @@ -536,8 +536,8 @@ final class ApplicationTests: XCTestCase { func testOnServerRunning() async throws { let runOnServerRunning = ManagedAtomic(false) - let router = HBRouter() - let app = HBApplication( + let router = Router() + let app = Application( responder: router.buildResponder(), onServerRunning: { _ in runOnServerRunning.store(true, ordering: .relaxed) @@ -552,8 +552,8 @@ final class ApplicationTests: XCTestCase { func testRunBeforeServer() async throws { let runBeforeServer = ManagedAtomic(false) - let router = HBRouter() - var app = HBApplication( + let router = Router() + var app = Application( responder: router.buildResponder(), onServerRunning: { _ in XCTAssertEqual(runBeforeServer.load(ordering: .relaxed), true) @@ -568,13 +568,13 @@ final class ApplicationTests: XCTestCase { } } - /// test we can create out own application type conforming to HBApplicationProtocol + /// test we can create out own application type conforming to ApplicationProtocol func testTLS() async throws { - let router = HBRouter() + let router = Router() router.get("/") { _, _ -> String in "Hello" } - let app = try HBApplication( + let app = try Application( responder: router.buildResponder(), server: .tls(tlsConfiguration: self.getServerTLSConfiguration()) ) @@ -587,13 +587,13 @@ final class ApplicationTests: XCTestCase { } } - /// test we can create out own application type conforming to HBApplicationProtocol + /// test we can create out own application type conforming to ApplicationProtocol func testHTTP2() async throws { - let router = HBRouter() + let router = Router() router.get("/") { _, _ -> String in "Hello" } - let app = try HBApplication( + let app = try Application( responder: router.buildResponder(), server: .http2Upgrade(tlsConfiguration: self.getServerTLSConfiguration()) ) @@ -606,13 +606,13 @@ final class ApplicationTests: XCTestCase { } } - /// test we can create out own application type conforming to HBApplicationProtocol + /// test we can create out own application type conforming to ApplicationProtocol func testApplicationRouterInit() async throws { - let router = HBRouter() + let router = Router() router.get("/") { _, _ -> String in "Hello" } - let app = HBApplication(router: router) + let app = Application(router: router) try await app.test(.live) { client in try await client.execute(uri: "/", method: .get) { response in XCTAssertEqual(response.status, .ok) @@ -622,11 +622,11 @@ final class ApplicationTests: XCTestCase { } } - /// test we can create out own application type conforming to HBApplicationProtocol + /// test we can create out own application type conforming to ApplicationProtocol func testBidirectionalStreaming() async throws { let buffer = self.randomBuffer(size: 1024 * 1024) - let router = HBRouter() - router.post("/") { request, context -> HBResponse in + let router = Router() + router.post("/") { request, context -> Response in .init( status: .ok, body: .init { writer in @@ -637,7 +637,7 @@ final class ApplicationTests: XCTestCase { } ) } - let app = HBApplication(router: router) + let app = Application(router: router) try await app.test(.live) { client in try await client.execute(uri: "/", method: .post, body: buffer) { response in XCTAssertEqual(response.body, ByteBuffer(bytes: buffer.readableBytesView.map { $0 ^ 0xFF })) @@ -659,5 +659,5 @@ final class ApplicationTests: XCTestCase { /// HTTPField used during tests extension HTTPField.Name { - static let test = Self("Test")! + static let test = Self("HBTest")! } diff --git a/Tests/HummingbirdTests/CookiesTests.swift b/Tests/HummingbirdTests/CookiesTests.swift index 5c5203d5c..c3b531360 100644 --- a/Tests/HummingbirdTests/CookiesTests.swift +++ b/Tests/HummingbirdTests/CookiesTests.swift @@ -18,60 +18,60 @@ import XCTest class CookieTests: XCTestCase { func testNameValue() { - let cookie = HBCookie(from: "name=value") + let cookie = Cookie(from: "name=value") XCTAssertEqual(cookie?.name, "name") XCTAssertEqual(cookie?.value, "value") XCTAssertEqual(cookie?.description, "name=value") } func testPropertyOutput() { - let cookie = HBCookie(from: "name=value; Expires=Wed, 21 Oct 2015 07:28:00 GMT") + let cookie = Cookie(from: "name=value; Expires=Wed, 21 Oct 2015 07:28:00 GMT") XCTAssertEqual(cookie?.description, "name=value; Expires=Wed, 21 Oct 2015 07:28:00 GMT") } func testExpires() { - let cookie = HBCookie(from: "name=value; Expires=Wed, 21 Oct 2015 07:28:00 GMT") - XCTAssertEqual(cookie?.expires, HBDateCache.rfc1123Formatter.date(from: "Wed, 21 Oct 2015 07:28:00 GMT")) + let cookie = Cookie(from: "name=value; Expires=Wed, 21 Oct 2015 07:28:00 GMT") + XCTAssertEqual(cookie?.expires, DateCache.rfc1123Formatter.date(from: "Wed, 21 Oct 2015 07:28:00 GMT")) } func testDomain() { - let cookie = HBCookie(from: "name=value; Domain=test.com") + let cookie = Cookie(from: "name=value; Domain=test.com") XCTAssertEqual(cookie?.domain, "test.com") } func testPath() { - let cookie = HBCookie(from: "name=value; Path=/test") + let cookie = Cookie(from: "name=value; Path=/test") XCTAssertEqual(cookie?.path, "/test") } func testMaxAge() { - let cookie = HBCookie(from: "name=value; Max-Age=3600") + let cookie = Cookie(from: "name=value; Max-Age=3600") XCTAssertEqual(cookie?.maxAge, 3600) } func testSecure() { - let cookie = HBCookie(from: "name=value; Secure") + let cookie = Cookie(from: "name=value; Secure") XCTAssertEqual(cookie?.secure, true) } func testHttpOnly() { - let cookie = HBCookie(from: "name=value; HttpOnly") + let cookie = Cookie(from: "name=value; HttpOnly") XCTAssertEqual(cookie?.httpOnly, true) } func testSameSite() { - let cookie = HBCookie(from: "name=value; SameSite=Secure") + let cookie = Cookie(from: "name=value; SameSite=Secure") XCTAssertEqual(cookie?.sameSite, .secure) } func testSetCookie() async throws { - let router = HBRouter() - router.post("/") { _, _ -> HBResponse in - var response = HBResponse(status: .ok, headers: [:], body: .init()) + let router = Router() + router.post("/") { _, _ -> Response in + var response = Response(status: .ok, headers: [:], body: .init()) response.setCookie(.init(name: "test", value: "value")) return response } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/", method: .post) { response in XCTAssertEqual(response.headers[.setCookie], "test=value; HttpOnly") @@ -80,11 +80,11 @@ class CookieTests: XCTestCase { } func testSetCookieViaRequest() async throws { - let router = HBRouter() + let router = Router() router.post("/") { _, _ in - return HBEditedResponse(headers: [.setCookie: HBCookie(name: "test", value: "value").description], response: "Hello") + return EditedResponse(headers: [.setCookie: Cookie(name: "test", value: "value").description], response: "Hello") } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/", method: .post) { response in XCTAssertEqual(response.headers[.setCookie], "test=value; HttpOnly") @@ -93,11 +93,11 @@ class CookieTests: XCTestCase { } func testReadCookieFromRequest() async throws { - let router = HBRouter() + let router = Router() router.post("/") { request, _ -> String? in return request.cookies["test"]?.value } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/", method: .post, headers: [.cookie: "test=value"]) { response in XCTAssertEqual(String(buffer: response.body), "value") diff --git a/Tests/HummingbirdTests/DateCacheTests.swift b/Tests/HummingbirdTests/DateCacheTests.swift index 1cb4075a3..ff61a4475 100644 --- a/Tests/HummingbirdTests/DateCacheTests.swift +++ b/Tests/HummingbirdTests/DateCacheTests.swift @@ -26,16 +26,16 @@ class HummingbirdDateTests: XCTestCase { for _ in 0..<1000 { let time = Int.random(in: 1...4 * Int(Int32.max)) - XCTAssertEqual(formatter.string(from: Date(timeIntervalSince1970: Double(time))), HBDateCache.formatRFC1123Date(time)) + XCTAssertEqual(formatter.string(from: Date(timeIntervalSince1970: Double(time))), DateCache.formatRFC1123Date(time)) } } func testDateHeader() async throws { - let router = HBRouter() + let router = Router() router.get("date") { _, _ in return "hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.live) { client in let date = try await client.execute(uri: "/date", method: .get) { response in diff --git a/Tests/HummingbirdTests/EnvironmentTests.swift b/Tests/HummingbirdTests/EnvironmentTests.swift index c19f36483..def71cf95 100644 --- a/Tests/HummingbirdTests/EnvironmentTests.swift +++ b/Tests/HummingbirdTests/EnvironmentTests.swift @@ -19,38 +19,38 @@ import XCTest final class EnvironmentTests: XCTestCase { func testInitFromEnvironment() { XCTAssertEqual(setenv("TEST_VAR", "testSetFromEnvironment", 1), 0) - let env = HBEnvironment() + let env = Environment() XCTAssertEqual(env.get("TEST_VAR"), "testSetFromEnvironment") } func testInitFromDictionary() { - let env = HBEnvironment(values: ["TEST_VAR": "testSetFromDictionary"]) + let env = Environment(values: ["TEST_VAR": "testSetFromDictionary"]) XCTAssertEqual(env.get("TEST_VAR"), "testSetFromDictionary") } func testInitFromCodable() { let json = #"{"TEST_VAR": "testSetFromCodable"}"# - var env: HBEnvironment? - XCTAssertNoThrow(env = try JSONDecoder().decode(HBEnvironment.self, from: Data(json.utf8))) + var env: Environment? + XCTAssertNoThrow(env = try JSONDecoder().decode(Environment.self, from: Data(json.utf8))) XCTAssertEqual(env?.get("TEST_VAR"), "testSetFromCodable") } func testSet() { - var env = HBEnvironment() + var env = Environment() env.set("TEST_VAR", value: "testSet") XCTAssertEqual(env.get("TEST_VAR"), "testSet") } func testLogLevel() { setenv("LOG_LEVEL", "trace", 1) - let router = HBRouter() - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + let app = Application(responder: router.buildResponder()) XCTAssertEqual(app.logger.logLevel, .trace) } func testCaseInsensitive() { XCTAssertEqual(setenv("test_VAR", "testSetFromEnvironment", 1), 0) - let env = HBEnvironment() + let env = Environment() XCTAssertEqual(env.get("TEST_VAR"), "testSetFromEnvironment") XCTAssertEqual(env.get("test_var"), "testSetFromEnvironment") } @@ -67,7 +67,7 @@ final class EnvironmentTests: XCTestCase { try? FileManager.default.removeItem(at: envURL) } - let result = try await HBEnvironment.dotEnv() + let result = try await Environment.dotEnv() XCTAssertEqual(result.get("test"), "this") XCTAssertEqual(result.get("credentials"), "sdkfjh") } @@ -77,9 +77,9 @@ final class EnvironmentTests: XCTestCase { TEST #thse """ do { - _ = try HBEnvironment.parseDotEnv(dotenv) + _ = try Environment.parseDotEnv(dotenv) XCTFail("Should fail") - } catch let error as HBEnvironment.Error where error == .dotEnvParseError {} + } catch let error as Environment.Error where error == .dotEnvParseError {} } func testDotEnvSpeechMarks() throws { @@ -87,7 +87,7 @@ final class EnvironmentTests: XCTestCase { TEST="test this" CREDENTIALS=sdkfjh """ - let result = try HBEnvironment.parseDotEnv(dotenv) + let result = try Environment.parseDotEnv(dotenv) XCTAssertEqual(result["test"], "test this") XCTAssertEqual(result["credentials"], "sdkfjh") } @@ -98,7 +98,7 @@ final class EnvironmentTests: XCTestCase { this" CREDENTIALS=sdkfjh """ - let result = try HBEnvironment.parseDotEnv(dotenv) + let result = try Environment.parseDotEnv(dotenv) XCTAssertEqual(result["test"], "test\nthis") XCTAssertEqual(result["credentials"], "sdkfjh") } @@ -110,7 +110,7 @@ final class EnvironmentTests: XCTestCase { CREDENTIALS=sdkfjh # Comment at end """ - let result = try HBEnvironment.parseDotEnv(dotenv) + let result = try Environment.parseDotEnv(dotenv) XCTAssertEqual(result["test"], "this") XCTAssertEqual(result["credentials"], "sdkfjh") } @@ -122,7 +122,7 @@ final class EnvironmentTests: XCTestCase { """ - let result = try HBEnvironment.parseDotEnv(dotenv) + let result = try Environment.parseDotEnv(dotenv) XCTAssertEqual(result["foo"], "BAR") XCTAssertEqual(result.count, 1) } @@ -132,7 +132,7 @@ final class EnvironmentTests: XCTestCase { FOO=BAR """ - let result = try HBEnvironment.parseDotEnv(dotenv) + let result = try Environment.parseDotEnv(dotenv) XCTAssertEqual(result["foo"], "BAR") XCTAssertEqual(result.count, 1) } @@ -149,7 +149,7 @@ final class EnvironmentTests: XCTestCase { } XCTAssertEqual(setenv("TEST_VAR", "testSetFromEnvironment", 1), 0) XCTAssertEqual(setenv("TEST_VAR2", "testSetFromEnvironment2", 1), 0) - let env = try await HBEnvironment().merging(with: .dotEnv(".override.env")) + let env = try await Environment().merging(with: .dotEnv(".override.env")) XCTAssertEqual(env.get("TEST_VAR"), "testDotEnvOverridingEnvironment") XCTAssertEqual(env.get("TEST_VAR2"), "testSetFromEnvironment2") } diff --git a/Tests/HummingbirdTests/FileIOTests.swift b/Tests/HummingbirdTests/FileIOTests.swift index feb6ee3c7..92a262b83 100644 --- a/Tests/HummingbirdTests/FileIOTests.swift +++ b/Tests/HummingbirdTests/FileIOTests.swift @@ -24,9 +24,9 @@ class FileIOTests: XCTestCase { } func testReadFileIO() async throws { - let router = HBRouter() - router.get("test.jpg") { _, context -> HBResponse in - let fileIO = HBFileIO(threadPool: .singleton) + let router = Router() + router.get("test.jpg") { _, context -> Response in + let fileIO = FileIO(threadPool: .singleton) let body = try await fileIO.loadFile(path: "test.jpg", context: context) return .init(status: .ok, headers: [:], body: body) } @@ -36,7 +36,7 @@ class FileIOTests: XCTestCase { XCTAssertNoThrow(try data.write(to: fileURL)) defer { XCTAssertNoThrow(try FileManager.default.removeItem(at: fileURL)) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/test.jpg", method: .get) { response in @@ -47,13 +47,13 @@ class FileIOTests: XCTestCase { func testWrite() async throws { let filename = "testWrite.txt" - let router = HBRouter() + let router = Router() router.put("store") { request, context -> HTTPResponse.Status in - let fileIO = HBFileIO(threadPool: .singleton) + let fileIO = FileIO(threadPool: .singleton) try await fileIO.writeFile(contents: request.body, path: filename, context: context) return .ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let buffer = ByteBufferAllocator().buffer(string: "This is a test") @@ -70,13 +70,13 @@ class FileIOTests: XCTestCase { func testWriteLargeFile() async throws { let filename = "testWriteLargeFile.txt" - let router = HBRouter() + let router = Router() router.put("store") { request, context -> HTTPResponse.Status in - let fileIO = HBFileIO(threadPool: .singleton) + let fileIO = FileIO(threadPool: .singleton) try await fileIO.writeFile(contents: request.body, path: filename, context: context) return .ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.live) { client in let buffer = self.randomBuffer(size: 400_000) diff --git a/Tests/HummingbirdTests/FileMiddlewareTests.swift b/Tests/HummingbirdTests/FileMiddlewareTests.swift index 99727732c..404ce0574 100644 --- a/Tests/HummingbirdTests/FileMiddlewareTests.swift +++ b/Tests/HummingbirdTests/FileMiddlewareTests.swift @@ -34,9 +34,9 @@ class HummingbirdFilesTests: XCTestCase { } func testRead() async throws { - let router = HBRouter() - router.middlewares.add(HBFileMiddleware(".")) - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + router.middlewares.add(FileMiddleware(".")) + let app = Application(responder: router.buildResponder()) let filename = "\(#function).jpg" let text = "Test file contents" @@ -54,9 +54,9 @@ class HummingbirdFilesTests: XCTestCase { } func testReadLargeFile() async throws { - let router = HBRouter() - router.middlewares.add(HBFileMiddleware(".")) - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + router.middlewares.add(FileMiddleware(".")) + let app = Application(responder: router.buildResponder()) let filename = "\(#function).txt" let buffer = self.randomBuffer(size: 380_000) @@ -73,9 +73,9 @@ class HummingbirdFilesTests: XCTestCase { } func testReadRange() async throws { - let router = HBRouter() - router.middlewares.add(HBFileMiddleware(".")) - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + router.middlewares.add(FileMiddleware(".")) + let app = Application(responder: router.buildResponder()) let filename = "\(#function).txt" let buffer = self.randomBuffer(size: 326_000) @@ -115,9 +115,9 @@ class HummingbirdFilesTests: XCTestCase { } func testIfRangeRead() async throws { - let router = HBRouter() - router.middlewares.add(HBFileMiddleware(".")) - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + router.middlewares.add(FileMiddleware(".")) + let app = Application(responder: router.buildResponder()) let filename = "\(#function).txt" let buffer = self.randomBuffer(size: 10000) @@ -151,9 +151,9 @@ class HummingbirdFilesTests: XCTestCase { } func testHead() async throws { - let router = HBRouter() - router.middlewares.add(HBFileMiddleware(".")) - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + router.middlewares.add(FileMiddleware(".")) + let app = Application(responder: router.buildResponder()) let date = Date() let text = "Test file contents" @@ -175,9 +175,9 @@ class HummingbirdFilesTests: XCTestCase { } func testETag() async throws { - let router = HBRouter() - router.middlewares.add(HBFileMiddleware(".")) - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + router.middlewares.add(FileMiddleware(".")) + let app = Application(responder: router.buildResponder()) let filename = "\(#function).txt" let buffer = self.randomBuffer(size: 16200) @@ -198,9 +198,9 @@ class HummingbirdFilesTests: XCTestCase { } func testIfNoneMatch() async throws { - let router = HBRouter() - router.middlewares.add(HBFileMiddleware(".")) - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + router.middlewares.add(FileMiddleware(".")) + let app = Application(responder: router.buildResponder()) let filename = "\(#function).txt" let buffer = self.randomBuffer(size: 16200) @@ -228,9 +228,9 @@ class HummingbirdFilesTests: XCTestCase { } func testIfModifiedSince() async throws { - let router = HBRouter() - router.middlewares.add(HBFileMiddleware(".")) - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + router.middlewares.add(FileMiddleware(".")) + let app = Application(responder: router.buildResponder()) let filename = "\(#function).txt" let buffer = self.randomBuffer(size: 16200) @@ -255,13 +255,13 @@ class HummingbirdFilesTests: XCTestCase { } func testCacheControl() async throws { - let router = HBRouter() - let cacheControl: HBCacheControl = .init([ + let router = Router() + let cacheControl: CacheControl = .init([ (.text, [.maxAge(60 * 60 * 24 * 30)]), (.imageJpeg, [.maxAge(60 * 60 * 24 * 30), .private]), ]) - router.middlewares.add(HBFileMiddleware(".", cacheControl: cacheControl)) - let app = HBApplication(responder: router.buildResponder()) + router.middlewares.add(FileMiddleware(".", cacheControl: cacheControl)) + let app = Application(responder: router.buildResponder()) let filename = "\(#function).txt" let text = "Test file contents" @@ -284,9 +284,9 @@ class HummingbirdFilesTests: XCTestCase { } func testIndexHtml() async throws { - let router = HBRouter() - router.middlewares.add(HBFileMiddleware(".", searchForIndexHtml: true)) - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + router.middlewares.add(FileMiddleware(".", searchForIndexHtml: true)) + let app = Application(responder: router.buildResponder()) let text = "Test file contents" let data = Data(text.utf8) diff --git a/Tests/HummingbirdTests/HTTPTests.swift b/Tests/HummingbirdTests/HTTPTests.swift index f563003de..0d1cf29c2 100644 --- a/Tests/HummingbirdTests/HTTPTests.swift +++ b/Tests/HummingbirdTests/HTTPTests.swift @@ -17,7 +17,7 @@ import HummingbirdCore import XCTest class HTTPTests: XCTestCase { - func testURI(_ uri: HBURI, _ component: KeyPath, _ value: T) { + func testURI(_ uri: URI, _ component: KeyPath, _ value: T) { XCTAssertEqual(uri[keyPath: component], value) } @@ -62,41 +62,41 @@ class HTTPTests: XCTestCase { let urlString = "https://hummingbird.co.uk/test/url?test1=hello%20rg&test2=true" let date = Date() for _ in 0..<10000 { - _ = HBURI(urlString).queryParameters + _ = URI(urlString).queryParameters } print("\(-date.timeIntervalSinceNow)") } func testMediaTypeExtensions() { - XCTAssert(HBMediaType.getMediaType(forExtension: "jpg")?.isType(.imageJpeg) == true) - XCTAssert(HBMediaType.getMediaType(forExtension: "txt")?.isType(.textPlain) == true) - XCTAssert(HBMediaType.getMediaType(forExtension: "html")?.isType(.textHtml) == true) - XCTAssert(HBMediaType.getMediaType(forExtension: "css")?.isType(.textCss) == true) + XCTAssert(MediaType.getMediaType(forExtension: "jpg")?.isType(.imageJpeg) == true) + XCTAssert(MediaType.getMediaType(forExtension: "txt")?.isType(.textPlain) == true) + XCTAssert(MediaType.getMediaType(forExtension: "html")?.isType(.textHtml) == true) + XCTAssert(MediaType.getMediaType(forExtension: "css")?.isType(.textCss) == true) } func testMediaTypeHeaderValues() { - XCTAssert(HBMediaType.applicationUrlEncoded.isType(.application)) - XCTAssert(HBMediaType.audioOgg.isType(.audio)) - XCTAssert(HBMediaType.videoMp4.isType(.video)) - XCTAssert(HBMediaType.fontOtf.isType(.font)) - XCTAssert(HBMediaType.multipartForm.isType(.multipart)) - XCTAssert(HBMediaType.imageSvg.isType(.image)) - XCTAssert(HBMediaType(from: "image/jpeg")?.isType(.imageJpeg) == true) - XCTAssert(HBMediaType(from: "text/plain")?.isType(.textPlain) == true) - XCTAssert(HBMediaType(from: "application/json")?.isType(.applicationJson) == true) - XCTAssert(HBMediaType(from: "application/json; charset=utf8")?.isType(.applicationJson) == true) - XCTAssert(HBMediaType(from: "application/xml")?.isType(.applicationXml) == true) - XCTAssert(HBMediaType(from: "multipart/form-data")?.isType(.multipartForm) == true) - XCTAssert(HBMediaType(from: "audio/ogg")?.isType(.audioOgg) == true) + XCTAssert(MediaType.applicationUrlEncoded.isType(.application)) + XCTAssert(MediaType.audioOgg.isType(.audio)) + XCTAssert(MediaType.videoMp4.isType(.video)) + XCTAssert(MediaType.fontOtf.isType(.font)) + XCTAssert(MediaType.multipartForm.isType(.multipart)) + XCTAssert(MediaType.imageSvg.isType(.image)) + XCTAssert(MediaType(from: "image/jpeg")?.isType(.imageJpeg) == true) + XCTAssert(MediaType(from: "text/plain")?.isType(.textPlain) == true) + XCTAssert(MediaType(from: "application/json")?.isType(.applicationJson) == true) + XCTAssert(MediaType(from: "application/json; charset=utf8")?.isType(.applicationJson) == true) + XCTAssert(MediaType(from: "application/xml")?.isType(.applicationXml) == true) + XCTAssert(MediaType(from: "multipart/form-data")?.isType(.multipartForm) == true) + XCTAssert(MediaType(from: "audio/ogg")?.isType(.audioOgg) == true) } func testMediaTypeMatching() { - switch HBMediaType(from: "application/json; charset=utf8") { + switch MediaType(from: "application/json; charset=utf8") { case .some(.application), .some(.applicationJson): break default: XCTFail() } - switch HBMediaType(from: "application/json") { + switch MediaType(from: "application/json") { case .some(.application), .some(.applicationJson): break default: XCTFail() @@ -104,12 +104,12 @@ class HTTPTests: XCTestCase { } func testMediaTypeMisMatching() { - switch HBMediaType.applicationJson { - case HBMediaType(from: "application/json; charset=utf8")!: + switch MediaType.applicationJson { + case MediaType(from: "application/json; charset=utf8")!: XCTFail() default: break } - switch HBMediaType.application { + switch MediaType.application { case .applicationJson: XCTFail() default: break @@ -117,20 +117,20 @@ class HTTPTests: XCTestCase { } func testMediaTypeParameters() { - let mediaType = HBMediaType(from: "application/json; charset=utf8") + let mediaType = MediaType(from: "application/json; charset=utf8") XCTAssertEqual(mediaType?.parameter?.name, "charset") XCTAssertEqual(mediaType?.parameter?.value, "utf8") - let mediaType2 = HBMediaType(from: "multipart/form-data; boundary=\"---{}hello\"") + let mediaType2 = MediaType(from: "multipart/form-data; boundary=\"---{}hello\"") XCTAssertEqual(mediaType2?.parameter?.name, "boundary") XCTAssertEqual(mediaType2?.parameter?.value, "---{}hello") - let mediaType3 = HBMediaType.multipartForm.withParameter(name: "boundary", value: "----{}hello") + let mediaType3 = MediaType.multipartForm.withParameter(name: "boundary", value: "----{}hello") XCTAssertEqual(mediaType3.parameter?.name, "boundary") XCTAssertEqual(mediaType3.parameter?.value, "----{}hello") } func testInvalidMediaTypes() { - XCTAssertNil(HBMediaType(from: "application/json; charset")) - XCTAssertNil(HBMediaType(from: "appl2ication/json")) - XCTAssertNil(HBMediaType(from: "application/json charset=utf8")) + XCTAssertNil(MediaType(from: "application/json; charset")) + XCTAssertNil(MediaType(from: "appl2ication/json")) + XCTAssertNil(MediaType(from: "application/json charset=utf8")) } } diff --git a/Tests/HummingbirdTests/HandlerTests.swift b/Tests/HummingbirdTests/HandlerTests.swift index 6d371df50..90c87887f 100644 --- a/Tests/HummingbirdTests/HandlerTests.swift +++ b/Tests/HummingbirdTests/HandlerTests.swift @@ -18,22 +18,22 @@ import Logging import XCTest final class HandlerTests: XCTestCase { - struct DecodeTest: HBRouteHandler, Decodable { + struct DecodeTest: RouteHandler, Decodable { let value: Value - init(from request: HBRequest, context: some HBBaseRequestContext) async throws { + init(from request: Request, context: some BaseRequestContext) async throws { self = try await request.decode(as: Self.self, context: context) } - func handle(context: some HBBaseRequestContext) -> String { + func handle(context: some BaseRequestContext) -> String { return "\(Value.self): \(self.value)" } } func testDecodeKeyError() async throws { - let router = HBRouter() + let router = Router() router.post("/hello", use: DecodeTest.self) - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let body = ByteBufferAllocator().buffer(string: #"{"foo": "bar"}"#) @@ -51,9 +51,9 @@ final class HandlerTests: XCTestCase { } func testDecodeTypeError() async throws { - let router = HBRouter() + let router = Router() router.post("/hello", use: DecodeTest.self) - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let body = ByteBufferAllocator().buffer(string: #"{"value": "bar"}"#) @@ -71,9 +71,9 @@ final class HandlerTests: XCTestCase { } func testDecodeValueError() async throws { - let router = HBRouter() + let router = Router() router.post("/hello", use: DecodeTest.self) - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let body = ByteBufferAllocator().buffer(string: #"{"value": null}"#) @@ -96,9 +96,9 @@ final class HandlerTests: XCTestCase { } func testDecodeInputError() async throws { - let router = HBRouter() + let router = Router() router.post("/hello", use: DecodeTest.self) - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let body = ByteBufferAllocator().buffer(string: #"{invalid}"#) @@ -116,9 +116,9 @@ final class HandlerTests: XCTestCase { } func testDecode() async throws { - let router = HBRouter() + let router = Router() router.post("/hello", use: DecodeTest.self) - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in @@ -129,9 +129,9 @@ final class HandlerTests: XCTestCase { } func testDecodeFail() async throws { - let router = HBRouter() + let router = Router() router.get("/hello", use: DecodeTest.self) - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get, body: ByteBufferAllocator().buffer(string: #"{"name2": "Adam"}"#)) { response in @@ -141,20 +141,20 @@ final class HandlerTests: XCTestCase { } func testEmptyRequest() async throws { - struct ParameterTest: HBRouteHandler { + struct ParameterTest: RouteHandler { let parameter: Int - init(from request: HBRequest, context: some HBBaseRequestContext) throws { + init(from request: Request, context: some BaseRequestContext) throws { self.parameter = try context.parameters.require("test", as: Int.self) } - func handle(context: some HBBaseRequestContext) -> String { + func handle(context: some BaseRequestContext) -> String { return "\(self.parameter)" } } - let router = HBRouter() + let router = Router() router.put("/:test", use: ParameterTest.self) - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in diff --git a/Tests/HummingbirdTests/HummingBirdJSONTests.swift b/Tests/HummingbirdTests/HummingBirdJSONTests.swift index d54e2c140..93fc15286 100644 --- a/Tests/HummingbirdTests/HummingBirdJSONTests.swift +++ b/Tests/HummingbirdTests/HummingBirdJSONTests.swift @@ -18,7 +18,7 @@ import Logging import XCTest class HummingbirdJSONTests: XCTestCase { - struct User: HBResponseCodable { + struct User: ResponseCodable { let name: String let email: String let age: Int @@ -27,15 +27,15 @@ class HummingbirdJSONTests: XCTestCase { struct Error: Swift.Error {} func testDecode() async throws { - let router = HBRouter() + let router = Router() router.put("/user") { request, context -> HTTPResponse.Status in - guard let user = try? await request.decode(as: User.self, context: context) else { throw HBHTTPError(.badRequest) } + guard let user = try? await request.decode(as: User.self, context: context) else { throw HTTPError(.badRequest) } XCTAssertEqual(user.name, "John Smith") XCTAssertEqual(user.email, "john.smith@email.com") XCTAssertEqual(user.age, 25) return .ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let body = #"{"name": "John Smith", "email": "john.smith@email.com", "age": 25}"# try await client.execute(uri: "/user", method: .put, body: ByteBufferAllocator().buffer(string: body)) { @@ -45,11 +45,11 @@ class HummingbirdJSONTests: XCTestCase { } func testEncode() async throws { - let router = HBRouter() + let router = Router() router.get("/user") { _, _ -> User in return User(name: "John Smith", email: "john.smith@email.com", age: 25) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/user", method: .get) { response in let user = try JSONDecoder().decode(User.self, from: response.body) @@ -61,11 +61,11 @@ class HummingbirdJSONTests: XCTestCase { } func testEncode2() async throws { - let router = HBRouter() + let router = Router() router.get("/json") { _, _ in return ["message": "Hello, world!"] } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/json", method: .get) { response in XCTAssertEqual(String(buffer: response.body), #"{"message":"Hello, world!"}"#) diff --git a/Tests/HummingbirdTests/MetricsTests.swift b/Tests/HummingbirdTests/MetricsTests.swift index 93f6ced6d..2032e3950 100644 --- a/Tests/HummingbirdTests/MetricsTests.swift +++ b/Tests/HummingbirdTests/MetricsTests.swift @@ -184,81 +184,81 @@ final class MetricsTests: XCTestCase { } func testCounter() async throws { - let router = HBRouter() - router.middlewares.add(HBMetricsMiddleware()) + let router = Router() + router.middlewares.add(MetricsMiddleware()) router.get("/hello") { _, _ -> String in return "Hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { _ in } } - let counter = try XCTUnwrap(Self.testMetrics.counters["hb_requests"] as? TestCounter) + let counter = try XCTUnwrap(Self.testMetrics.counters["_requests"] as? TestCounter) XCTAssertEqual(counter.values[0].1, 1) - XCTAssertEqual(counter.dimensions[0].0, "hb_uri") + XCTAssertEqual(counter.dimensions[0].0, "_uri") XCTAssertEqual(counter.dimensions[0].1, "/hello") - XCTAssertEqual(counter.dimensions[1].0, "hb_method") + XCTAssertEqual(counter.dimensions[1].0, "_method") XCTAssertEqual(counter.dimensions[1].1, "GET") } func testError() async throws { - let router = HBRouter() - router.middlewares.add(HBMetricsMiddleware()) + let router = Router() + router.middlewares.add(MetricsMiddleware()) router.get("/hello") { _, _ -> String in - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { _ in } } - let counter = try XCTUnwrap(Self.testMetrics.counters["hb_errors"] as? TestCounter) + let counter = try XCTUnwrap(Self.testMetrics.counters["_errors"] as? TestCounter) XCTAssertEqual(counter.values.count, 1) XCTAssertEqual(counter.values[0].1, 1) - XCTAssertEqual(counter.dimensions[0].0, "hb_uri") + XCTAssertEqual(counter.dimensions[0].0, "_uri") XCTAssertEqual(counter.dimensions[0].1, "/hello") - XCTAssertEqual(counter.dimensions[1].0, "hb_method") + XCTAssertEqual(counter.dimensions[1].0, "_method") XCTAssertEqual(counter.dimensions[1].1, "GET") } func testNotFoundError() async throws { - let router = HBRouter() - router.middlewares.add(HBMetricsMiddleware()) + let router = Router() + router.middlewares.add(MetricsMiddleware()) router.get("/hello") { _, _ -> String in return "hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello2", method: .get) { _ in } } - let counter = try XCTUnwrap(Self.testMetrics.counters["hb_errors"] as? TestCounter) + let counter = try XCTUnwrap(Self.testMetrics.counters["_errors"] as? TestCounter) XCTAssertEqual(counter.values.count, 1) XCTAssertEqual(counter.values[0].1, 1) XCTAssertEqual(counter.dimensions.count, 1) - XCTAssertEqual(counter.dimensions[0].0, "hb_method") + XCTAssertEqual(counter.dimensions[0].0, "_method") XCTAssertEqual(counter.dimensions[0].1, "GET") } func testParameterEndpoint() async throws { - let router = HBRouter() - router.middlewares.add(HBMetricsMiddleware()) + let router = Router() + router.middlewares.add(MetricsMiddleware()) router.get("/user/:id") { _, _ -> String in - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/user/765", method: .get) { _ in } } - let counter = try XCTUnwrap(Self.testMetrics.counters["hb_errors"] as? TestCounter) + let counter = try XCTUnwrap(Self.testMetrics.counters["_errors"] as? TestCounter) XCTAssertEqual(counter.values.count, 1) XCTAssertEqual(counter.values[0].1, 1) XCTAssertEqual(counter.dimensions.count, 2) - XCTAssertEqual(counter.dimensions[0].0, "hb_uri") + XCTAssertEqual(counter.dimensions[0].0, "_uri") XCTAssertEqual(counter.dimensions[0].1, "/user/:id") - XCTAssertEqual(counter.dimensions[1].0, "hb_method") + XCTAssertEqual(counter.dimensions[1].0, "_method") XCTAssertEqual(counter.dimensions[1].1, "GET") } } diff --git a/Tests/HummingbirdTests/MiddlewareTests.swift b/Tests/HummingbirdTests/MiddlewareTests.swift index 46af27d6c..db0fd6daf 100644 --- a/Tests/HummingbirdTests/MiddlewareTests.swift +++ b/Tests/HummingbirdTests/MiddlewareTests.swift @@ -24,19 +24,19 @@ final class MiddlewareTests: XCTestCase { } func testMiddleware() async throws { - struct TestMiddleware: HBRouterMiddleware { - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestMiddleware: RouterMiddleware { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var response = try await next(request, context) response.headers[.test] = "TestMiddleware" return response } } - let router = HBRouter() + let router = Router() router.middlewares.add(TestMiddleware()) router.get("/hello") { _, _ -> String in return "Hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { response in XCTAssertEqual(response.headers[.test], "TestMiddleware") @@ -45,21 +45,21 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareOrder() async throws { - struct TestMiddleware: HBRouterMiddleware { + struct TestMiddleware: RouterMiddleware { let string: String - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var response = try await next(request, context) response.headers[values: .test].append(self.string) return response } } - let router = HBRouter() + let router = Router() router.middlewares.add(TestMiddleware(string: "first")) router.middlewares.add(TestMiddleware(string: "second")) router.get("/hello") { _, _ -> String in return "Hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { response in // headers come back in opposite order as middleware is applied to responses in that order @@ -70,20 +70,20 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareRunOnce() async throws { - struct TestMiddleware: HBRouterMiddleware { - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestMiddleware: RouterMiddleware { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var response = try await next(request, context) XCTAssertNil(response.headers[.test]) response.headers[.test] = "alreadyRun" return response } } - let router = HBRouter() + let router = Router() router.middlewares.add(TestMiddleware()) router.get("/hello") { _, _ -> String in return "Hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { _ in } @@ -91,18 +91,18 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareRunWhenNoRouteFound() async throws { - struct TestMiddleware: HBRouterMiddleware { - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestMiddleware: RouterMiddleware { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { do { return try await next(request, context) - } catch let error as HBHTTPError where error.status == .notFound { - throw HBHTTPError(.notFound, message: "Edited error") + } catch let error as HTTPError where error.status == .notFound { + throw HTTPError(.notFound, message: "Edited error") } } } - let router = HBRouter() + let router = Router() router.middlewares.add(TestMiddleware()) - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get) { response in @@ -113,19 +113,19 @@ final class MiddlewareTests: XCTestCase { } func testEndpointPathInGroup() async throws { - struct TestMiddleware: HBRouterMiddleware { - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestMiddleware: RouterMiddleware { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { XCTAssertNotNil(context.endpointPath) return try await next(request, context) } } - let router = HBRouter() + let router = Router() router.group() .add(middleware: TestMiddleware()) .get("test") { _, _ in return "test" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/test", method: .get) { _ in } @@ -133,8 +133,8 @@ final class MiddlewareTests: XCTestCase { } func testMiddlewareResponseBodyWriter() async throws { - struct TransformWriter: HBResponseBodyWriter { - let parentWriter: any HBResponseBodyWriter + struct TransformWriter: ResponseBodyWriter { + let parentWriter: any ResponseBodyWriter let allocator: ByteBufferAllocator func write(_ buffer: ByteBuffer) async throws { @@ -142,8 +142,8 @@ final class MiddlewareTests: XCTestCase { try await self.parentWriter.write(output) } } - struct TransformMiddleware: HBRouterMiddleware { - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TransformMiddleware: RouterMiddleware { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { let response = try await next(request, context) var editedResponse = response editedResponse.body = .withTrailingHeaders { writer in @@ -154,13 +154,13 @@ final class MiddlewareTests: XCTestCase { return editedResponse } } - let router = HBRouter() + let router = Router() router.group() .add(middleware: TransformMiddleware()) .get("test") { request, _ in - return HBResponse(status: .ok, body: .init(asyncSequence: request.body)) + return Response(status: .ok, body: .init(asyncSequence: request.body)) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let buffer = self.randomBuffer(size: 64000) @@ -172,12 +172,12 @@ final class MiddlewareTests: XCTestCase { } func testCORSUseOrigin() async throws { - let router = HBRouter() - router.middlewares.add(HBCORSMiddleware()) + let router = Router() + router.middlewares.add(CORSMiddleware()) router.get("/hello") { _, _ -> String in return "Hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get, headers: [.origin: "foo.com"]) { response in // headers come back in opposite order as middleware is applied to responses in that order @@ -187,12 +187,12 @@ final class MiddlewareTests: XCTestCase { } func testCORSUseAll() async throws { - let router = HBRouter() - router.middlewares.add(HBCORSMiddleware(allowOrigin: .all)) + let router = Router() + router.middlewares.add(CORSMiddleware(allowOrigin: .all)) router.get("/hello") { _, _ -> String in return "Hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .get, headers: [.origin: "foo.com"]) { response in // headers come back in opposite order as middleware is applied to responses in that order @@ -202,8 +202,8 @@ final class MiddlewareTests: XCTestCase { } func testCORSOptions() async throws { - let router = HBRouter() - router.middlewares.add(HBCORSMiddleware( + let router = Router() + router.middlewares.add(CORSMiddleware( allowOrigin: .all, allowHeaders: [.contentType, .authorization], allowMethods: [.get, .put, .delete, .options], @@ -214,7 +214,7 @@ final class MiddlewareTests: XCTestCase { router.get("/hello") { _, _ -> String in return "Hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .options, headers: [.origin: "foo.com"]) { response in // headers come back in opposite order as middleware is applied to responses in that order @@ -232,12 +232,12 @@ final class MiddlewareTests: XCTestCase { } func testRouteLoggingMiddleware() async throws { - let router = HBRouter() - router.middlewares.add(HBLogRequestsMiddleware(.debug)) + let router = Router() + router.middlewares.add(LogRequestsMiddleware(.debug)) router.put("/hello") { _, _ -> String in - throw HBHTTPError(.badRequest) + throw HTTPError(.badRequest) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/hello", method: .put) { _ in } diff --git a/Tests/HummingbirdTests/ParserTests.swift b/Tests/HummingbirdTests/ParserTests.swift index 44c23d794..d3b7ea41e 100644 --- a/Tests/HummingbirdTests/ParserTests.swift +++ b/Tests/HummingbirdTests/ParserTests.swift @@ -17,13 +17,13 @@ import XCTest final class ParserTests: XCTestCase { func testCharacter() { - var parser = HBParser("TestString") + var parser = Parser("TestString") XCTAssertEqual(try parser.character(), "T") XCTAssertEqual(try parser.character(), "e") } func testSubstring() { - var parser = HBParser("TestString") + var parser = Parser("TestString") XCTAssertThrowsError(try parser.read(count: 23)) XCTAssertEqual(try parser.read(count: 3).string, "Tes") XCTAssertEqual(try parser.read(count: 5).string, "tStri") @@ -32,7 +32,7 @@ final class ParserTests: XCTestCase { } func testReadCharacter() { - var parser = HBParser("TestString") + var parser = Parser("TestString") XCTAssertNoThrow(try parser.read("T")) XCTAssertNoThrow(try parser.read("e")) XCTAssertEqual(try parser.read("e"), false) @@ -40,40 +40,40 @@ final class ParserTests: XCTestCase { } func testReadUntilCharacter() throws { - var parser = HBParser("TestString") + var parser = Parser("TestString") XCTAssertEqual(try parser.read(until: "S").string, "Test") XCTAssertEqual(try parser.read(until: "n").string, "Stri") XCTAssertThrowsError(try parser.read(until: "!")) } func testReadUntilCharacterSet() throws { - var parser = HBParser("TestString") + var parser = Parser("TestString") XCTAssertEqual(try parser.read(until: Set("Sr")).string, "Test") XCTAssertEqual(try parser.read(until: Set("abcdefg")).string, "Strin") } func testReadUntilString() throws { - var parser = HBParser("") + var parser = Parser("") XCTAssertEqual(try parser.read(untilString: "-->").string, "")) } func testReadWhileCharacter() throws { - var parser = HBParser("122333") + var parser = Parser("122333") XCTAssertEqual(parser.read(while: "1"), 1) XCTAssertEqual(parser.read(while: "2"), 2) XCTAssertEqual(parser.read(while: "3"), 3) } func testReadWhileCharacterSet() throws { - var parser = HBParser("aabbcdd836de") + var parser = Parser("aabbcdd836de") XCTAssertEqual(parser.read(while: Set("abcdef")).string, "aabbcdd") XCTAssertEqual(parser.read(while: Set("123456789")).string, "836") XCTAssertEqual(parser.read(while: Set("abcdef")).string, "de") } func testRetreat() throws { - var parser = HBParser("abcdef") + var parser = Parser("abcdef") XCTAssertThrowsError(try parser.retreat()) _ = try parser.read(count: 4) try parser.retreat(by: 3) @@ -81,7 +81,7 @@ final class ParserTests: XCTestCase { } func testCopy() throws { - var parser = HBParser("abcdef") + var parser = Parser("abcdef") XCTAssertEqual(try parser.read(count: 3).string, "abc") var reader2 = parser XCTAssertEqual(try parser.read(count: 3).string, "def") @@ -89,7 +89,7 @@ final class ParserTests: XCTestCase { } func testSplit() throws { - var parser = HBParser("abc,defgh,ijk") + var parser = Parser("abc,defgh,ijk") let split = parser.split(separator: ",") XCTAssertEqual(split.count, 3) XCTAssertEqual(split[0].string, "abc") @@ -100,7 +100,7 @@ final class ParserTests: XCTestCase { func testPercentDecode() throws { let string = "abc,é☺😀併" let encoded = string.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)! - var parser = HBParser(encoded) + var parser = Parser(encoded) try! parser.read(until: ",") let decoded = try XCTUnwrap(parser.percentDecode()) @@ -109,13 +109,13 @@ final class ParserTests: XCTestCase { func testValidate() { let string = "abc,é☺😀併" - XCTAssertNotNil(HBParser([UInt8](string.utf8), validateUTF8: true)) + XCTAssertNotNil(Parser([UInt8](string.utf8), validateUTF8: true)) } func testSequence() { let string = "abc,é☺😀併 lorem" var string2 = "" - let parser = HBParser(string) + let parser = Parser(string) for c in parser { string2 += String(c) } diff --git a/Tests/HummingbirdTests/PersistTests.swift b/Tests/HummingbirdTests/PersistTests.swift index 53079904c..a90961a84 100644 --- a/Tests/HummingbirdTests/PersistTests.swift +++ b/Tests/HummingbirdTests/PersistTests.swift @@ -17,11 +17,11 @@ import HummingbirdTesting import XCTest final class PersistTests: XCTestCase { - static let redisHostname = HBEnvironment.shared.get("REDIS_HOSTNAME") ?? "localhost" + static let redisHostname = Environment.shared.get("REDIS_HOSTNAME") ?? "localhost" - func createRouter() throws -> (HBRouter, HBPersistDriver) { - let router = HBRouter() - let persist = HBMemoryPersistDriver() + func createRouter() throws -> (Router, PersistDriver) { + let router = Router() + let persist = MemoryPersistDriver() router.put("/persist/:tag") { request, context -> HTTPResponse.Status in let buffer = try await request.body.collect(upTo: .max) @@ -30,18 +30,18 @@ final class PersistTests: XCTestCase { return .ok } router.put("/persist/:tag/:time") { request, context -> HTTPResponse.Status in - guard let time = context.parameters.get("time", as: Int.self) else { throw HBHTTPError(.badRequest) } + guard let time = context.parameters.get("time", as: Int.self) else { throw HTTPError(.badRequest) } let buffer = try await request.body.collect(upTo: .max) let tag = try context.parameters.require("tag") try await persist.set(key: tag, value: String(buffer: buffer), expires: .seconds(time)) return .ok } router.get("/persist/:tag") { _, context -> String? in - guard let tag = context.parameters.get("tag", as: String.self) else { throw HBHTTPError(.badRequest) } + guard let tag = context.parameters.get("tag", as: String.self) else { throw HTTPError(.badRequest) } return try await persist.get(key: tag, as: String.self) } router.delete("/persist/:tag") { _, context -> HTTPResponse.Status in - guard let tag = context.parameters.get("tag", as: String.self) else { throw HBHTTPError(.badRequest) } + guard let tag = context.parameters.get("tag", as: String.self) else { throw HTTPError(.badRequest) } try await persist.remove(key: tag) return .noContent } @@ -50,7 +50,7 @@ final class PersistTests: XCTestCase { func testSetGet() async throws { let (router, _) = try createRouter() - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let tag = UUID().uuidString try await client.execute(uri: "/persist/\(tag)", method: .put, body: ByteBufferAllocator().buffer(string: "Persist")) { _ in } @@ -69,7 +69,7 @@ final class PersistTests: XCTestCase { try await persist.create(key: tag, value: String(buffer: buffer)) return .ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let tag = UUID().uuidString try await client.execute(uri: "/create/\(tag)", method: .put, body: ByteBufferAllocator().buffer(string: "Persist")) { _ in } @@ -86,12 +86,12 @@ final class PersistTests: XCTestCase { let tag = try context.parameters.require("tag") do { try await persist.create(key: tag, value: String(buffer: buffer)) - } catch let error as HBPersistError where error == .duplicate { - throw HBHTTPError(.conflict) + } catch let error as PersistError where error == .duplicate { + throw HTTPError(.conflict) } return .ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let tag = UUID().uuidString try await client.execute(uri: "/create/\(tag)", method: .put, body: ByteBufferAllocator().buffer(string: "Persist")) { response in @@ -105,7 +105,7 @@ final class PersistTests: XCTestCase { func testSetTwice() async throws { let (router, _) = try createRouter() - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let tag = UUID().uuidString @@ -121,7 +121,7 @@ final class PersistTests: XCTestCase { func testExpires() async throws { let (router, _) = try createRouter() - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let tag1 = UUID().uuidString @@ -142,24 +142,24 @@ final class PersistTests: XCTestCase { func testCodable() async throws { #if os(macOS) // disable macOS tests in CI. GH Actions are currently running this when they shouldn't - guard HBEnvironment().get("CI") != "true" else { throw XCTSkip() } + guard Environment().get("CI") != "true" else { throw XCTSkip() } #endif struct TestCodable: Codable { let buffer: String } let (router, persist) = try createRouter() router.put("/codable/:tag") { request, context -> HTTPResponse.Status in - guard let tag = context.parameters.get("tag") else { throw HBHTTPError(.badRequest) } + guard let tag = context.parameters.get("tag") else { throw HTTPError(.badRequest) } let buffer = try await request.body.collect(upTo: .max) try await persist.set(key: tag, value: TestCodable(buffer: String(buffer: buffer))) return .ok } router.get("/codable/:tag") { _, context -> String? in - guard let tag = context.parameters.get("tag") else { throw HBHTTPError(.badRequest) } + guard let tag = context.parameters.get("tag") else { throw HTTPError(.badRequest) } let value = try await persist.get(key: tag, as: TestCodable.self) return value?.buffer } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in @@ -173,7 +173,7 @@ final class PersistTests: XCTestCase { func testRemove() async throws { let (router, _) = try createRouter() - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let tag = UUID().uuidString try await client.execute(uri: "/persist/\(tag)", method: .put, body: ByteBufferAllocator().buffer(string: "ThisIsTest1")) { _ in } @@ -186,7 +186,7 @@ final class PersistTests: XCTestCase { func testExpireAndAdd() async throws { let (router, _) = try createRouter() - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let tag = UUID().uuidString diff --git a/Tests/HummingbirdTests/RouterTests.swift b/Tests/HummingbirdTests/RouterTests.swift index 0e533736f..ddd19d19b 100644 --- a/Tests/HummingbirdTests/RouterTests.swift +++ b/Tests/HummingbirdTests/RouterTests.swift @@ -21,14 +21,14 @@ import Tracing import XCTest final class RouterTests: XCTestCase { - struct TestMiddleware: HBRouterMiddleware { + struct TestMiddleware: RouterMiddleware { let output: String init(_ output: String = "TestMiddleware") { self.output = output } - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var response = try await next(request, context) response.headers[.test] = self.output return response @@ -37,17 +37,17 @@ final class RouterTests: XCTestCase { /// Test endpointPath is set func testEndpointPath() async throws { - struct TestEndpointMiddleware: HBRouterMiddleware { - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestEndpointMiddleware: RouterMiddleware { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { guard let endpointPath = context.endpointPath else { return try await next(request, context) } return .init(status: .ok, body: .init(byteBuffer: ByteBuffer(string: endpointPath))) } } - let router = HBRouter() + let router = Router() router.middlewares.add(TestEndpointMiddleware()) router.get("/test/:number") { _, _ in return "xxx" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/test/1", method: .get) { response in @@ -58,14 +58,14 @@ final class RouterTests: XCTestCase { /// Test endpointPath is prefixed with a "/" func testEndpointPathPrefix() async throws { - struct TestEndpointMiddleware: HBRouterMiddleware { - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestEndpointMiddleware: RouterMiddleware { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { guard let endpointPath = context.endpointPath else { return try await next(request, context) } return .init(status: .ok, body: .init(byteBuffer: ByteBuffer(string: endpointPath))) } } - let router = HBRouter() + let router = Router() router.middlewares.add(TestEndpointMiddleware()) router.get("test") { _, context in return context.endpointPath @@ -76,7 +76,7 @@ final class RouterTests: XCTestCase { router.post("/test2") { _, context in return context.endpointPath } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/", method: .get) { response in @@ -93,14 +93,14 @@ final class RouterTests: XCTestCase { /// Test endpointPath doesn't have "/" at end func testEndpointPathSuffix() async throws { - struct TestEndpointMiddleware: HBRouterMiddleware { - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct TestEndpointMiddleware: RouterMiddleware { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { guard let endpointPath = context.endpointPath else { return try await next(request, context) } return .init(status: .ok, body: .init(byteBuffer: ByteBuffer(string: endpointPath))) } } - let router = HBRouter() + let router = Router() router.middlewares.add(TestEndpointMiddleware()) router.get("test/") { _, context in return context.endpointPath @@ -118,7 +118,7 @@ final class RouterTests: XCTestCase { .get("/") { _, context in return context.endpointPath } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/test/", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "/test") @@ -140,7 +140,7 @@ final class RouterTests: XCTestCase { /// Test correct endpoints are called from group func testMethodEndpoint() async throws { - let router = HBRouter() + let router = Router() router .group("/endpoint") .get { _, _ in @@ -149,7 +149,7 @@ final class RouterTests: XCTestCase { .put { _, _ in return "PUT" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/endpoint", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "GET") @@ -164,7 +164,7 @@ final class RouterTests: XCTestCase { /// Test middle in group is applied to group but not to routes outside /// group func testGroupMiddleware() async throws { - let router = HBRouter() + let router = Router() router .group() .add(middleware: TestMiddleware()) @@ -174,7 +174,7 @@ final class RouterTests: XCTestCase { router.get("/not-group") { _, _ in return "hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/group", method: .get) { response in XCTAssertEqual(response.headers[.test], "TestMiddleware") @@ -187,14 +187,14 @@ final class RouterTests: XCTestCase { } func testEndpointMiddleware() async throws { - let router = HBRouter() + let router = Router() router .group("/group") .add(middleware: TestMiddleware()) .head { _, _ in return "hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/group", method: .head) { response in XCTAssertEqual(response.headers[.test], "TestMiddleware") @@ -204,7 +204,7 @@ final class RouterTests: XCTestCase { /// Test middleware in parent group is applied to routes in child group func testGroupGroupMiddleware() async throws { - let router = HBRouter() + let router = Router() router .group("/test") .add(middleware: TestMiddleware()) @@ -212,7 +212,7 @@ final class RouterTests: XCTestCase { .get { _, _ in return "hello" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/test/group", method: .get) { response in XCTAssertEqual(response.headers[.test], "TestMiddleware") @@ -222,17 +222,17 @@ final class RouterTests: XCTestCase { /// Test adding middleware to group doesn't affect middleware in parent groups func testGroupGroupMiddleware2() async throws { - struct TestGroupMiddleware: HBRouterMiddleware { + struct TestGroupMiddleware: RouterMiddleware { let output: String - public func handle(_ request: HBRequest, context: HBTestRouterContext2, next: (HBRequest, HBTestRouterContext2) async throws -> HBResponse) async throws -> HBResponse { + public func handle(_ request: Request, context: TestRouterContext2, next: (Request, TestRouterContext2) async throws -> Response) async throws -> Response { var context = context context.string = self.output return try await next(request, context) } } - let router = HBRouter(context: HBTestRouterContext2.self) + let router = Router(context: TestRouterContext2.self) router .group("/test") .add(middleware: TestGroupMiddleware(output: "route1")) @@ -244,7 +244,7 @@ final class RouterTests: XCTestCase { .get { _, context in return context.string } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/test/group", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "route2") @@ -256,12 +256,12 @@ final class RouterTests: XCTestCase { } func testParameters() async throws { - let router = HBRouter() + let router = Router() router .delete("/user/:id") { _, context -> String? in return context.parameters.get("id", as: String.self) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/user/1234", method: .delete) { response in XCTAssertEqual(String(buffer: response.body), "1234") @@ -270,13 +270,13 @@ final class RouterTests: XCTestCase { } func testRequireLosslessStringParameter() async throws { - let router = HBRouter() + let router = Router() router .delete("/user/:id") { _, context -> String in let id = try context.parameters.require("id", as: Int.self) return (id + 1).description } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/user/1234", method: .delete) { response in XCTAssertEqual(String(buffer: response.body), "1235") @@ -292,12 +292,12 @@ final class RouterTests: XCTestCase { case this case that } - let router = HBRouter() + let router = Router() router .delete("/user/:id") { _, context -> String in return try context.parameters.require("id", as: TestEnum.self).rawValue } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/user/this", method: .delete) { response in XCTAssertEqual(String(buffer: response.body), "this") @@ -309,13 +309,13 @@ final class RouterTests: XCTestCase { } func testParameterCollection() async throws { - let router = HBRouter() + let router = Router() router .delete("/user/:username/:id") { _, context -> String? in XCTAssertEqual(context.parameters.count, 2) return context.parameters.get("id", as: String.self) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/user/john/1234", method: .delete) { response in XCTAssertEqual(String(buffer: response.body), "1234") @@ -324,7 +324,7 @@ final class RouterTests: XCTestCase { } func testPartialCapture() async throws { - let router = HBRouter() + let router = Router() router .get("/files/file.{ext}/{name}.jpg") { _, context -> String in XCTAssertEqual(context.parameters.count, 2) @@ -332,7 +332,7 @@ final class RouterTests: XCTestCase { let name = try context.parameters.require("name") return "\(name).\(ext)" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/files/file.doc/test.jpg", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "test.doc") @@ -341,12 +341,12 @@ final class RouterTests: XCTestCase { } func testPartialWildcard() async throws { - let router = HBRouter() + let router = Router() router .get("/files/file.*/*.jpg") { _, _ -> HTTPResponse.Status in return .ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/files/file.doc/test.jpg", method: .get) { response in XCTAssertEqual(response.status, .ok) @@ -358,13 +358,13 @@ final class RouterTests: XCTestCase { } func testRequireLosslessStringQuery() async throws { - let router = HBRouter() + let router = Router() router .get("/user/") { request, _ -> [Int] in let ids = try request.uri.queryParameters.requireAll("id", as: Int.self) return ids.map { $0 + 1 } } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/user/?id=24&id=56", method: .get) { response in XCTAssertEqual(String(buffer: response.body), "[25,57]") @@ -381,13 +381,13 @@ final class RouterTests: XCTestCase { case and case that } - let router = HBRouter() + let router = Router() router .patch("/user/") { request, _ -> [TestEnum] in let ids = try request.uri.queryParameters.requireAll("id", as: TestEnum.self) return ids } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/user/?id=this&id=and&id=that", method: .patch) { response in XCTAssertEqual(String(buffer: response.body), "[\"this\",\"and\",\"that\"]") @@ -400,11 +400,11 @@ final class RouterTests: XCTestCase { /// Test we have a request id and that it increments with each request func testRequestId() async throws { - let router = HBRouter() + let router = Router() router.get("id") { _, context in return context.id.description } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let id = try await client.execute(uri: "/id", method: .get) { response -> String in return String(buffer: response.body) @@ -418,11 +418,11 @@ final class RouterTests: XCTestCase { // Test redirect response func testRedirect() async throws { - let router = HBRouter() + let router = Router() router.get("redirect") { _, _ in - return HBResponse.redirect(to: "/other") + return Response.redirect(to: "/other") } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/redirect", method: .get) { response in XCTAssertEqual(response.headers[.location], "/other") @@ -433,14 +433,14 @@ final class RouterTests: XCTestCase { // Test case insensitive router works func testCaseInsensitive() async throws { - let router = HBRouter(options: .caseInsensitive) + let router = Router(options: .caseInsensitive) router.get("Uppercased") { _, _ in return HTTPResponse.Status.ok } router.get("lowercased") { _, _ in return HTTPResponse.Status.ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/uppercased", method: .get) { response in XCTAssertEqual(response.status, .ok) @@ -453,20 +453,20 @@ final class RouterTests: XCTestCase { // Test auto generation of HEAD endpoints works func testAutoGenerateHeadEndpoints() async throws { - let router = HBRouter(options: .autoGenerateHeadEndpoints) + let router = Router(options: .autoGenerateHeadEndpoints) router.get("nohead") { _, _ in return "TestString" } router.head("withhead") { _, _ in - return HBResponse(status: .ok, headers: [.contentLength: "0", .contentLanguage: "en"], body: .init()) + return Response(status: .ok, headers: [.contentLength: "0", .contentLanguage: "en"], body: .init()) } router.get("withhead") { _, _ in - return HBResponse(status: .ok, headers: [.contentLength: "999"], body: .init()) + return Response(status: .ok, headers: [.contentLength: "999"], body: .init()) } router.post("post") { _, _ in - return HBResponse(status: .ok, headers: [.contentLength: "999"], body: .init()) + return Response(status: .ok, headers: [.contentLength: "999"], body: .init()) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/nohead", method: .head) { response in XCTAssertEqual(response.status, .ok) @@ -483,14 +483,14 @@ final class RouterTests: XCTestCase { } } -struct HBTestRouterContext2: HBRequestContext { +struct TestRouterContext2: RequestContext { init(channel: Channel, logger: Logger) { self.coreContext = .init(allocator: channel.allocator, logger: logger) self.string = "" } /// parameters - var coreContext: HBCoreRequestContext + var coreContext: CoreRequestContext /// additional data var string: String diff --git a/Tests/HummingbirdTests/TracingTests.swift b/Tests/HummingbirdTests/TracingTests.swift index 8b766e72d..13357ca3b 100644 --- a/Tests/HummingbirdTests/TracingTests.swift +++ b/Tests/HummingbirdTests/TracingTests.swift @@ -35,12 +35,12 @@ final class TracingTests: XCTestCase { tracer.onEndSpan = { _ in expectation.fulfill() } InstrumentationSystem.bootstrapInternal(tracer) - let router = HBRouter() - router.middlewares.add(HBTracingMiddleware(attributes: ["net.host.name": "127.0.0.1", "net.host.port": 8080])) + let router = Router() + router.middlewares.add(TracingMiddleware(attributes: ["net.host.name": "127.0.0.1", "net.host.port": 8080])) router.get("users/:id") { _, _ -> String in return "42" } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/users/42", method: .get) { response in XCTAssertEqual(response.status, .ok) @@ -74,12 +74,12 @@ final class TracingTests: XCTestCase { tracer.onEndSpan = { _ in expectation.fulfill() } InstrumentationSystem.bootstrapInternal(tracer) - let router = HBRouter() - router.middlewares.add(HBTracingMiddleware()) + let router = Router() + router.middlewares.add(TracingMiddleware()) router.post("users") { _, _ -> String in - throw HBHTTPError(.internalServerError) + throw HTTPError(.internalServerError) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/users", method: .post, headers: [.contentLength: "2"], body: ByteBuffer(string: "42")) { response in XCTAssertEqual(response.status, .internalServerError) @@ -95,7 +95,7 @@ final class TracingTests: XCTestCase { XCTAssertEqual(span.status, .init(code: .error)) XCTAssertEqual(span.recordedErrors.count, 1) - let error = try XCTUnwrap(span.recordedErrors.first?.0 as? HBHTTPError, "Recorded unexpected errors: \(span.recordedErrors)") + let error = try XCTUnwrap(span.recordedErrors.first?.0 as? HTTPError, "Recorded unexpected errors: \(span.recordedErrors)") XCTAssertEqual(error.status, .internalServerError) XCTAssertSpanAttributesEqual(span.attributes, [ @@ -113,21 +113,21 @@ final class TracingTests: XCTestCase { tracer.onEndSpan = { _ in expectation.fulfill() } InstrumentationSystem.bootstrapInternal(tracer) - let router = HBRouter() - router.middlewares.add(HBTracingMiddleware(recordingHeaders: [ + let router = Router() + router.middlewares.add(TracingMiddleware(recordingHeaders: [ .accept, .contentType, .cacheControl, .test, ])) - router.get("users/:id") { _, _ -> HBResponse in + router.get("users/:id") { _, _ -> Response in var headers = HTTPFields() headers[values: .cacheControl] = ["86400", "public"] headers[.contentType] = "text/plain" - return HBResponse( + return Response( status: .ok, headers: headers, body: .init(byteBuffer: ByteBuffer(string: "42")) ) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in var requestHeaders = HTTPFields() requestHeaders[values: .accept] = ["text/plain", "application/json"] @@ -166,12 +166,12 @@ final class TracingTests: XCTestCase { tracer.onEndSpan = { _ in expectation.fulfill() } InstrumentationSystem.bootstrapInternal(tracer) - let router = HBRouter() - router.middlewares.add(HBTracingMiddleware()) + let router = Router() + router.middlewares.add(TracingMiddleware()) router.post("/users") { _, _ -> HTTPResponse.Status in return .noContent } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/users", method: .post) { response in XCTAssertEqual(response.status, .noContent) @@ -202,12 +202,12 @@ final class TracingTests: XCTestCase { tracer.onEndSpan = { _ in expectation.fulfill() } InstrumentationSystem.bootstrapInternal(tracer) - let router = HBRouter() - router.middlewares.add(HBTracingMiddleware()) + let router = Router() + router.middlewares.add(TracingMiddleware()) router.get("/") { _, _ -> HTTPResponse.Status in return .ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/", method: .get) { response in XCTAssertEqual(response.status, .ok) @@ -238,9 +238,9 @@ final class TracingTests: XCTestCase { tracer.onEndSpan = { _ in expectation.fulfill() } InstrumentationSystem.bootstrapInternal(tracer) - let router = HBRouter() - router.middlewares.add(HBTracingMiddleware()) - let app = HBApplication(responder: router.buildResponder()) + let router = Router() + router.middlewares.add(TracingMiddleware()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/", method: .get) { response in XCTAssertEqual(response.status, .notFound) @@ -255,7 +255,7 @@ final class TracingTests: XCTestCase { XCTAssertNil(span.status) XCTAssertEqual(span.recordedErrors.count, 1) - let error = try XCTUnwrap(span.recordedErrors.first?.0 as? HBHTTPError, "Recorded unexpected errors: \(span.recordedErrors)") + let error = try XCTUnwrap(span.recordedErrors.first?.0 as? HTTPError, "Recorded unexpected errors: \(span.recordedErrors)") XCTAssertEqual(error.status, .notFound) XCTAssertSpanAttributesEqual(span.attributes, [ @@ -274,8 +274,8 @@ final class TracingTests: XCTestCase { tracer.onEndSpan = { _ in expectation.fulfill() } InstrumentationSystem.bootstrapInternal(tracer) - let router = HBRouter() - router.middlewares.add(HBTracingMiddleware()) + let router = Router() + router.middlewares.add(TracingMiddleware()) router.get("/") { _, _ -> HTTPResponse.Status in var serviceContext = ServiceContext.current ?? ServiceContext.topLevel serviceContext.testID = "test" @@ -283,7 +283,7 @@ final class TracingTests: XCTestCase { span.end() return .ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/", method: .get) { response in XCTAssertEqual(response.status, .ok) @@ -308,8 +308,8 @@ final class TracingTests: XCTestCase { tracer.onEndSpan = { _ in expectation.fulfill() } InstrumentationSystem.bootstrapInternal(tracer) - let router = HBRouter() - router.middlewares.add(HBTracingMiddleware()) + let router = Router() + router.middlewares.add(TracingMiddleware()) router.get("/") { _, _ -> HTTPResponse.Status in var serviceContext = ServiceContext.current ?? ServiceContext.topLevel serviceContext.testID = "test" @@ -318,7 +318,7 @@ final class TracingTests: XCTestCase { return .ok } } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/", method: .get) { response in XCTAssertEqual(response.status, .ok) @@ -342,8 +342,8 @@ final class TracingTests: XCTestCase { let expectation = expectation(description: "Expected span to be ended.") expectation.expectedFulfillmentCount = 2 - struct SpanMiddleware: HBRouterMiddleware { - public func handle(_ request: HBRequest, context: Context, next: (HBRequest, Context) async throws -> HBResponse) async throws -> HBResponse { + struct SpanMiddleware: RouterMiddleware { + public func handle(_ request: Request, context: Context, next: (Request, Context) async throws -> Response) async throws -> Response { var serviceContext = ServiceContext.current ?? ServiceContext.topLevel serviceContext.testID = "testMiddleware" @@ -359,14 +359,14 @@ final class TracingTests: XCTestCase { } InstrumentationSystem.bootstrapInternal(tracer) - let router = HBRouter() + let router = Router() router.middlewares.add(SpanMiddleware()) - router.middlewares.add(HBTracingMiddleware()) + router.middlewares.add(TracingMiddleware()) router.get("/") { _, _ -> HTTPResponse.Status in try await Task.sleep(for: .milliseconds(2)) return .ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/", method: .get) { response in XCTAssertEqual(response.status, .ok) @@ -395,15 +395,15 @@ extension TracingTests { tracer.onEndSpan = { _ in expectation.fulfill() } InstrumentationSystem.bootstrapInternal(tracer) - let router = HBRouter() - router.middlewares.add(HBTracingMiddleware()) + let router = Router() + router.middlewares.add(TracingMiddleware()) router.get("/") { _, _ -> HTTPResponse.Status in try await Task.sleep(nanoseconds: 1000) return InstrumentationSystem.tracer.withAnySpan("testing", ofKind: .server) { _ in return .ok } } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/", method: .get) { response in XCTAssertEqual(response.status, .ok) diff --git a/Tests/HummingbirdTests/TrieRouterTests.swift b/Tests/HummingbirdTests/TrieRouterTests.swift index b5949bf15..f13c33715 100644 --- a/Tests/HummingbirdTests/TrieRouterTests.swift +++ b/Tests/HummingbirdTests/TrieRouterTests.swift @@ -83,7 +83,7 @@ class TrieRouterTests: XCTestCase { XCTAssertEqual(trie.getValueAndParameters("/Test/")?.parameters?.getCatchAll(), nil) XCTAssertEqual(trie.getValueAndParameters("/Test/one/two")?.parameters?.getCatchAll(), ["one", "two"]) XCTAssertEqual(trie.getValueAndParameters("/Test2/one/two")?.parameters?.getCatchAll(), ["two"]) - XCTAssertEqual(HBParameters().getCatchAll(), []) + XCTAssertEqual(Parameters().getCatchAll(), []) } func testPrefixWildcard() { diff --git a/Tests/HummingbirdTests/URLEncodedForm/Application+URLEncodedFormTests.swift b/Tests/HummingbirdTests/URLEncodedForm/Application+URLEncodedFormTests.swift index 03eaca844..2dfa48795 100644 --- a/Tests/HummingbirdTests/URLEncodedForm/Application+URLEncodedFormTests.swift +++ b/Tests/HummingbirdTests/URLEncodedForm/Application+URLEncodedFormTests.swift @@ -19,14 +19,14 @@ import NIOCore import XCTest class HummingBirdURLEncodedTests: XCTestCase { - struct User: HBResponseCodable { + struct User: ResponseCodable { let name: String let email: String let age: Int } - struct URLEncodedCodingRequestContext: HBRequestContext { - var coreContext: HBCoreRequestContext + struct URLEncodedCodingRequestContext: RequestContext { + var coreContext: CoreRequestContext init(channel: Channel, logger: Logger) { self.coreContext = .init(allocator: channel.allocator, logger: logger) @@ -39,15 +39,15 @@ class HummingBirdURLEncodedTests: XCTestCase { struct Error: Swift.Error {} func testDecode() async throws { - let router = HBRouter(context: URLEncodedCodingRequestContext.self) + let router = Router(context: URLEncodedCodingRequestContext.self) router.put("/user") { request, context -> HTTPResponse.Status in - guard let user = try? await request.decode(as: User.self, context: context) else { throw HBHTTPError(.badRequest) } + guard let user = try? await request.decode(as: User.self, context: context) else { throw HTTPError(.badRequest) } XCTAssertEqual(user.name, "John Smith") XCTAssertEqual(user.email, "john.smith@email.com") XCTAssertEqual(user.age, 25) return .ok } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let body = "name=John%20Smith&email=john.smith%40email.com&age=25" try await client.execute(uri: "/user", method: .put, body: ByteBufferAllocator().buffer(string: body)) { @@ -57,11 +57,11 @@ class HummingBirdURLEncodedTests: XCTestCase { } func testEncode() async throws { - let router = HBRouter(context: URLEncodedCodingRequestContext.self) + let router = Router(context: URLEncodedCodingRequestContext.self) router.get("/user") { _, _ -> User in return User(name: "John Smith", email: "john.smith@email.com", age: 25) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in try await client.execute(uri: "/user", method: .get) { response in let user = try URLEncodedFormDecoder().decode(User.self, from: String(buffer: response.body)) diff --git a/Tests/HummingbirdTests/UUIDTests.swift b/Tests/HummingbirdTests/UUIDTests.swift index 92ac797ab..845d0f71e 100644 --- a/Tests/HummingbirdTests/UUIDTests.swift +++ b/Tests/HummingbirdTests/UUIDTests.swift @@ -18,11 +18,11 @@ import XCTest final class UUIDTests: XCTestCase { func testGetUUID() async throws { - let router = HBRouter() + let router = Router() router.get(":id") { _, context -> UUID? in return context.parameters.get("id", as: UUID.self) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let uuid = UUID() try await client.execute(uri: "\(uuid)", method: .get) { response in @@ -34,11 +34,11 @@ final class UUIDTests: XCTestCase { } func testRequireUUID() async throws { - let router = HBRouter() + let router = Router() router.get(":id") { _, context -> UUID in return try context.parameters.require("id", as: UUID.self) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let uuid = UUID() try await client.execute(uri: "\(uuid)", method: .get) { response in @@ -50,12 +50,12 @@ final class UUIDTests: XCTestCase { } func testGetUUIDs() async throws { - let router = HBRouter() + let router = Router() router.get { request, _ -> [UUID] in let queryParameters = request.uri.queryParameters return queryParameters.getAll("id", as: UUID.self) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let uuid = UUID() let uuid2 = UUID() @@ -68,12 +68,12 @@ final class UUIDTests: XCTestCase { } func testRequireUUIDs() async throws { - let router = HBRouter() + let router = Router() router.get { request, _ -> [UUID] in let queryParameters = request.uri.queryParameters return try queryParameters.requireAll("id", as: UUID.self) } - let app = HBApplication(responder: router.buildResponder()) + let app = Application(responder: router.buildResponder()) try await app.test(.router) { client in let uuid = UUID() let uuid2 = UUID() diff --git a/scripts/generate-certs.sh b/scripts/generate-certs.sh index 3f95d1b7f..923e744b0 100755 --- a/scripts/generate-certs.sh +++ b/scripts/generate-certs.sh @@ -55,7 +55,7 @@ function generateServerCertificate() { function generateClientCertificate() { SUBJECT=$1 NAME=$2 - PASSWORD=HBTests + PASSWORD=Tests openssl req \ -new \ -nodes \ From 7bba06d3b2ef2454abc7823946f1343d7a94143e Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 9 Mar 2024 16:35:11 +0000 Subject: [PATCH 08/11] RequestResponder -> HTTPResponder --- Sources/Hummingbird/Application.swift | 8 ++++---- Sources/Hummingbird/Middleware/Middleware.swift | 2 +- Sources/Hummingbird/Middleware/MiddlewareGroup.swift | 2 +- Sources/Hummingbird/Router/EndpointResponder.swift | 6 +++--- Sources/Hummingbird/Router/Router.swift | 12 ++++++------ Sources/Hummingbird/Router/RouterResponder.swift | 6 +++--- Sources/Hummingbird/Server/RequestResponder.swift | 4 ++-- Sources/HummingbirdRouter/RouterBuilder.swift | 2 +- Sources/HummingbirdTesting/RouterTestFramework.swift | 2 +- Tests/HummingbirdTests/ApplicationTests.swift | 2 +- 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Sources/Hummingbird/Application.swift b/Sources/Hummingbird/Application.swift index 047b01ffe..495aa2e91 100644 --- a/Sources/Hummingbird/Application.swift +++ b/Sources/Hummingbird/Application.swift @@ -43,7 +43,7 @@ public enum EventLoopGroupProvider { public protocol ApplicationProtocol: Service where Context: RequestContext { /// Responder that generates a response from a requests and context - associatedtype Responder: RequestResponder + associatedtype Responder: HTTPResponder /// Child Channel setup. This defaults to support HTTP1 associatedtype ChildChannel: ServerChildChannel & HTTPChannelHandler = HTTP1Channel /// Context passed with Request to responder @@ -159,7 +159,7 @@ extension ApplicationProtocol { /// try await app.runService() /// ``` /// Editing the application setup after calling `runService` will produce undefined behaviour. -public struct Application: ApplicationProtocol where Responder.Context: RequestContext { +public struct Application: ApplicationProtocol where Responder.Context: RequestContext { public typealias Context = Responder.Context public typealias ChildChannel = ChildChannel public typealias Responder = Responder @@ -168,7 +168,7 @@ public struct Application( + public init( router: ResponderBuilder, server: HTTPChannelBuilder = .http1(), configuration: ApplicationConfiguration = ApplicationConfiguration(), diff --git a/Sources/Hummingbird/Middleware/Middleware.swift b/Sources/Hummingbird/Middleware/Middleware.swift index e1f0846b8..c738c1af9 100644 --- a/Sources/Hummingbird/Middleware/Middleware.swift +++ b/Sources/Hummingbird/Middleware/Middleware.swift @@ -52,7 +52,7 @@ public protocol MiddlewareProtocol: Sendable { /// Middleware protocol with Request as input and Response as output public protocol RouterMiddleware: MiddlewareProtocol where Input == Request, Output == Response {} -struct MiddlewareResponder: RequestResponder { +struct MiddlewareResponder: HTTPResponder { let middleware: any RouterMiddleware let next: @Sendable (Request, Context) async throws -> Response diff --git a/Sources/Hummingbird/Middleware/MiddlewareGroup.swift b/Sources/Hummingbird/Middleware/MiddlewareGroup.swift index e609c69d5..7e22dc428 100644 --- a/Sources/Hummingbird/Middleware/MiddlewareGroup.swift +++ b/Sources/Hummingbird/Middleware/MiddlewareGroup.swift @@ -29,7 +29,7 @@ public final class MiddlewareGroup { /// Construct responder chain from this middleware group /// - Parameter finalResponder: The responder the last middleware calls /// - Returns: Responder chain - public func constructResponder(finalResponder: any RequestResponder) -> any RequestResponder { + public func constructResponder(finalResponder: any HTTPResponder) -> any HTTPResponder { var currentResponser = finalResponder for i in (0..: Sendable { self.methods = [:] } - public func getResponder(for method: HTTPRequest.Method) -> (any RequestResponder)? { + public func getResponder(for method: HTTPRequest.Method) -> (any HTTPResponder)? { return self.methods[method] } - mutating func addResponder(for method: HTTPRequest.Method, responder: any RequestResponder) { + mutating func addResponder(for method: HTTPRequest.Method, responder: any HTTPResponder) { guard self.methods[method] == nil else { preconditionFailure("\(method.rawValue) already has a handler") } @@ -42,6 +42,6 @@ struct EndpointResponders: Sendable { } } - var methods: [HTTPRequest.Method: any RequestResponder] + var methods: [HTTPRequest.Method: any HTTPResponder] var path: String } diff --git a/Sources/Hummingbird/Router/Router.swift b/Sources/Hummingbird/Router/Router.swift index 9a7509fbf..3f0a8de59 100644 --- a/Sources/Hummingbird/Router/Router.swift +++ b/Sources/Hummingbird/Router/Router.swift @@ -43,7 +43,7 @@ import NIOCore /// Both of these match routes which start with "/user" and the next path segment being anything. /// The second version extracts the path segment out and adds it to `Request.parameters` with the /// key "id". -public final class Router: RouterMethods, RequestResponderBuilder { +public final class Router: RouterMethods, HTTPResponderBuilder { var trie: RouterPathTrieBuilder> public let middlewares: MiddlewareGroup let options: RouterOptions @@ -59,7 +59,7 @@ public final class Router: RouterMethods, RequestRe /// - path: URI path /// - method: http method /// - responder: handler to call - public func add(_ path: String, method: HTTPRequest.Method, responder: any RequestResponder) { + public func add(_ path: String, method: HTTPRequest.Method, responder: any HTTPResponder) { // ensure path starts with a "/" and doesn't end with a "/" let path = "/\(path.dropSuffix("/").dropPrefix("/"))" self.trie.addEntry(.init(path), value: EndpointResponders(path: path)) { node in @@ -105,15 +105,15 @@ public final class Router: RouterMethods, RequestRe } /// Responder that return a not found error -struct NotFoundResponder: RequestResponder { +struct NotFoundResponder: HTTPResponder { func respond(to request: Request, context: Context) throws -> Response { throw HTTPError(.notFound) } } -/// A type that has a single method to build a responder -public protocol RequestResponderBuilder { - associatedtype Responder: RequestResponder +/// A type that has a single method to build a HTTPResponder +public protocol HTTPResponderBuilder { + associatedtype Responder: HTTPResponder /// build a responder func buildResponder() -> Responder } diff --git a/Sources/Hummingbird/Router/RouterResponder.swift b/Sources/Hummingbird/Router/RouterResponder.swift index a10fd08c7..c4abec9ae 100644 --- a/Sources/Hummingbird/Router/RouterResponder.swift +++ b/Sources/Hummingbird/Router/RouterResponder.swift @@ -17,16 +17,16 @@ /// Conforms to `Responder` so need to provide its own implementation of /// `func respond(to request: Request, context: Context) async throws -> Response`. /// -public struct RouterResponder: RequestResponder { +public struct RouterResponder: HTTPResponder { let trie: RouterPathTrie> - let notFoundResponder: any RequestResponder + let notFoundResponder: any HTTPResponder let options: RouterOptions init( context: Context.Type, trie: RouterPathTrie>, options: RouterOptions, - notFoundResponder: any RequestResponder + notFoundResponder: any HTTPResponder ) { self.trie = trie self.options = options diff --git a/Sources/Hummingbird/Server/RequestResponder.swift b/Sources/Hummingbird/Server/RequestResponder.swift index 204819035..7b9475094 100644 --- a/Sources/Hummingbird/Server/RequestResponder.swift +++ b/Sources/Hummingbird/Server/RequestResponder.swift @@ -18,14 +18,14 @@ import ServiceContextModule /// Protocol for object that produces a response given a request /// /// This is the core protocol for Hummingbird. It defines an object that can respond to a request. -public protocol RequestResponder: Sendable { +public protocol HTTPResponder: Sendable { associatedtype Context /// Return response to the request supplied @Sendable func respond(to request: Request, context: Context) async throws -> Response } /// Responder that calls supplied closure -public struct CallbackResponder: RequestResponder { +public struct CallbackResponder: HTTPResponder { let callback: @Sendable (Request, Context) async throws -> Response public init(callback: @escaping @Sendable (Request, Context) async throws -> Response) { diff --git a/Sources/HummingbirdRouter/RouterBuilder.swift b/Sources/HummingbirdRouter/RouterBuilder.swift index f21f30f1c..81492525c 100644 --- a/Sources/HummingbirdRouter/RouterBuilder.swift +++ b/Sources/HummingbirdRouter/RouterBuilder.swift @@ -44,7 +44,7 @@ public struct RouterBuilder Output { try await self.handle(request, context: context) { _, _ in throw HTTPError(.notFound) diff --git a/Sources/HummingbirdTesting/RouterTestFramework.swift b/Sources/HummingbirdTesting/RouterTestFramework.swift index 67cdd7de8..0574564b6 100644 --- a/Sources/HummingbirdTesting/RouterTestFramework.swift +++ b/Sources/HummingbirdTesting/RouterTestFramework.swift @@ -25,7 +25,7 @@ import NIOPosix import ServiceLifecycle /// Test sending requests directly to router. This does not setup a live server -struct RouterTestFramework: ApplicationTestFramework where Responder.Context: BaseRequestContext { +struct RouterTestFramework: ApplicationTestFramework where Responder.Context: BaseRequestContext { let responder: Responder let makeContext: @Sendable (Logger) -> Responder.Context let services: [any Service] diff --git a/Tests/HummingbirdTests/ApplicationTests.swift b/Tests/HummingbirdTests/ApplicationTests.swift index f58c62b91..efc4ecc80 100644 --- a/Tests/HummingbirdTests/ApplicationTests.swift +++ b/Tests/HummingbirdTests/ApplicationTests.swift @@ -495,7 +495,7 @@ final class ApplicationTests: XCTestCase { struct MyApp: ApplicationProtocol { typealias Context = BasicRequestContext - var responder: some RequestResponder { + var responder: some HTTPResponder { let router = Router(context: Context.self) router.get("/hello") { _, context -> ByteBuffer in return context.allocator.buffer(string: "GET: Hello") From a7b616c0d8ab4a7f2fb3c7c3ae0dabe43bf843b5 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sun, 10 Mar 2024 11:26:31 +0000 Subject: [PATCH 09/11] Deprecated typealiases --- Sources/Hummingbird/Deprecations.swift | 97 +++++++++++++++++++ Sources/Hummingbird/Exports.swift | 9 ++ Sources/HummingbirdCore/Deprecations.swift | 40 ++++++++ Sources/HummingbirdRouter/Deprecations.swift | 28 ++++++ Sources/HummingbirdTesting/Deprecations.swift | 26 +++++ 5 files changed, 200 insertions(+) create mode 100644 Sources/Hummingbird/Deprecations.swift create mode 100644 Sources/HummingbirdCore/Deprecations.swift create mode 100644 Sources/HummingbirdRouter/Deprecations.swift create mode 100644 Sources/HummingbirdTesting/Deprecations.swift diff --git a/Sources/Hummingbird/Deprecations.swift b/Sources/Hummingbird/Deprecations.swift new file mode 100644 index 000000000..ec926ca45 --- /dev/null +++ b/Sources/Hummingbird/Deprecations.swift @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 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 +// +//===----------------------------------------------------------------------===// + +// Below is a list of deprecated symbols with the "HB" prefix. These are available +// temporarily to ease transition from the old symbols that included the "HB" +// prefix to the new ones. +// +// This file will be removed before we do a 2.0 release + +@_documentation(visibility: internal) @available(*, deprecated, renamed: "Application") +public typealias HBApplication = Application +@_documentation(visibility: internal) @available(*, deprecated, renamed: "ApplicationConfiguration") +public typealias HBApplicationConfiguration = ApplicationConfiguration +@_documentation(visibility: internal) @available(*, deprecated, renamed: "ApplicationProtocol") +public typealias HBApplicationProtocol = ApplicationProtocol +@_documentation(visibility: internal) @available(*, deprecated, renamed: "Environment") +public typealias HBEnvironment = Environment +@_documentation(visibility: internal) @available(*, deprecated, renamed: "FileIO") +public typealias HBFileIO = FileIO + +@_documentation(visibility: internal) @available(*, deprecated, renamed: "BaseRequestContext") +public typealias HBBaseRequestContext = BaseRequestContext +@_documentation(visibility: internal) @available(*, deprecated, renamed: "BasicRequestContext") +public typealias HBBasicRequestContext = BasicRequestContext +@_documentation(visibility: internal) @available(*, deprecated, renamed: "CoreRequestContext") +public typealias HBCoreRequestContext = CoreRequestContext +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RequestContext") +public typealias HBRequestContext = RequestContext +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RequestDecoder") +public typealias HBRequestDecoder = RequestDecoder +@_documentation(visibility: internal) @available(*, deprecated, renamed: "ResponseEncodable") +public typealias HBResponseEncodable = ResponseEncodable +@_documentation(visibility: internal) @available(*, deprecated, renamed: "ResponseEncoder") +public typealias HBResponseEncoder = ResponseEncoder +@_documentation(visibility: internal) @available(*, deprecated, renamed: "ResponseGenerator") +public typealias HBResponseGenerator = ResponseGenerator +@_documentation(visibility: internal) @available(*, deprecated, renamed: "Router") +public typealias HBRouter = Router +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RouterGroup") +public typealias HBRouterGroup = RouterGroup +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RouterMethods") +public typealias HBRouterMethods = RouterMethods +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RouterOptions") +public typealias HBRouterOptions = RouterOptions +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RouterPath") +public typealias HBRouterPath = RouterPath +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RouterResponder") +public typealias HBRouterResponder = RouterResponder + +@_documentation(visibility: internal) @available(*, deprecated, renamed: "CORSMiddleware") +public typealias HBCORSMiddleware = CORSMiddleware +@_documentation(visibility: internal) @available(*, deprecated, renamed: "FileMiddleware") +public typealias HBFileMiddleware = FileMiddleware +@_documentation(visibility: internal) @available(*, deprecated, renamed: "LogRequestsMiddleware") +public typealias HBLogRequestsMiddleware = LogRequestsMiddleware +@_documentation(visibility: internal) @available(*, deprecated, renamed: "MetricsMiddleware") +public typealias HBMetricsMiddleware = MetricsMiddleware +@_documentation(visibility: internal) @available(*, deprecated, renamed: "MiddlewareGroup") +public typealias HBMiddlewareGroup = MiddlewareGroup +@_documentation(visibility: internal) @available(*, deprecated, renamed: "TracingMiddleware") +public typealias HBTracingMiddleware = TracingMiddleware + +@_documentation(visibility: internal) @available(*, deprecated, renamed: "CacheControl") +public typealias HBCacheControl = CacheControl +@_documentation(visibility: internal) @available(*, deprecated, renamed: "Cookie") +public typealias HBCookie = Cookie +@_documentation(visibility: internal) @available(*, deprecated, renamed: "Cookies") +public typealias HBCookies = Cookies +@_documentation(visibility: internal) @available(*, deprecated, renamed: "MediaType") +public typealias HBMediaType = MediaType + +@_documentation(visibility: internal) @available(*, deprecated, renamed: "HTTPResponder") +public typealias HBResponder = HTTPResponder +@_documentation(visibility: internal) @available(*, deprecated, renamed: "HTTPResponderBuilder") +public typealias HBResponderBuilder = HTTPResponderBuilder +@_documentation(visibility: internal) @available(*, deprecated, renamed: "CallbackResponder") +public typealias HBCallbackResponder = CallbackResponder +@_documentation(visibility: internal) @available(*, deprecated, renamed: "EditedResponse") +public typealias HBEditedResponse = EditedResponse + +@_documentation(visibility: internal) @available(*, deprecated, renamed: "MemoryPersistDriver") +public typealias HBMemoryPersistDriver = MemoryPersistDriver +@_documentation(visibility: internal) @available(*, deprecated, renamed: "PersistDriver") +public typealias HBPersistDriver = PersistDriver +@_documentation(visibility: internal) @available(*, deprecated, renamed: "PersistError") +public typealias HBPersistError = PersistError diff --git a/Sources/Hummingbird/Exports.swift b/Sources/Hummingbird/Exports.swift index 18d24009b..5e8828e8c 100644 --- a/Sources/Hummingbird/Exports.swift +++ b/Sources/Hummingbird/Exports.swift @@ -30,3 +30,12 @@ @_exported @_documentation(visibility: internal) import struct HTTPTypes.HTTPFields @_exported @_documentation(visibility: internal) import struct HTTPTypes.HTTPRequest @_exported @_documentation(visibility: internal) import struct HTTPTypes.HTTPResponse + +// Temporary exports or deprecated typealiases +@_exported import struct HummingbirdCore.HBHTTPError +@_exported import protocol HummingbirdCore.HBHTTPResponseError +@_exported import struct HummingbirdCore.HBRequest +@_exported import struct HummingbirdCore.HBRequestBody +@_exported import struct HummingbirdCore.HBResponse +@_exported import struct HummingbirdCore.HBResponseBody +@_exported import protocol HummingbirdCore.HBResponseBodyWriter diff --git a/Sources/HummingbirdCore/Deprecations.swift b/Sources/HummingbirdCore/Deprecations.swift new file mode 100644 index 000000000..f0e74a1a0 --- /dev/null +++ b/Sources/HummingbirdCore/Deprecations.swift @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 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 +// +//===----------------------------------------------------------------------===// + +// Below is a list of deprecated symbols with the "HB" prefix. These are available +// temporarily to ease transition from the old symbols that included the "HB" +// prefix to the new ones. +// +// This file will be removed before we do a 2.0 release + +@_documentation(visibility: internal) @available(*, deprecated, renamed: "Request") +public typealias HBRequest = Request +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RequestBody") +public typealias HBRequestBody = RequestBody +@_documentation(visibility: internal) @available(*, deprecated, renamed: "Response") +public typealias HBResponse = Response +@_documentation(visibility: internal) @available(*, deprecated, renamed: "ResponseBody") +public typealias HBResponseBody = ResponseBody +@_documentation(visibility: internal) @available(*, deprecated, renamed: "ResponseBodyWriter") +public typealias HBResponseBodyWriter = ResponseBodyWriter +@_documentation(visibility: internal) @available(*, deprecated, renamed: "HTTPError") +public typealias HBHTTPError = HTTPError +@_documentation(visibility: internal) @available(*, deprecated, renamed: "HTTPResponseError") +public typealias HBHTTPResponseError = HTTPResponseError +@_documentation(visibility: internal) @available(*, deprecated, renamed: "Server") +public typealias HBServer = Server +@_documentation(visibility: internal) @available(*, deprecated, renamed: "ServerConfiguration") +public typealias HBServerConfiguration = ServerConfiguration +@_documentation(visibility: internal) @available(*, deprecated, renamed: "URI") +public typealias HBURL = URI diff --git a/Sources/HummingbirdRouter/Deprecations.swift b/Sources/HummingbirdRouter/Deprecations.swift new file mode 100644 index 000000000..d01cf56ab --- /dev/null +++ b/Sources/HummingbirdRouter/Deprecations.swift @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 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 +// +//===----------------------------------------------------------------------===// + +// Below is a list of deprecated symbols with the "HB" prefix. These are available +// temporarily to ease transition from the old symbols that included the "HB" +// prefix to the new ones. +// +// This file will be removed before we do a 2.0 release + +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RouterBuilder") +public typealias HBRouterBuilder = RouterBuilder +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RouterBuilderContext") +public typealias HBRouterBuilderContext = RouterBuilderContext +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RouterRequestContext") +public typealias HBRouterRequestContext = RouterRequestContext +@_documentation(visibility: internal) @available(*, deprecated, renamed: "BasicRouterRequestContext") +public typealias HBBasicRouterRequestContext = BasicRouterRequestContext diff --git a/Sources/HummingbirdTesting/Deprecations.swift b/Sources/HummingbirdTesting/Deprecations.swift new file mode 100644 index 000000000..512ab184d --- /dev/null +++ b/Sources/HummingbirdTesting/Deprecations.swift @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 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 +// +//===----------------------------------------------------------------------===// + +// Below is a list of deprecated symbols with the "HB" prefix. These are available +// temporarily to ease transition from the old symbols that included the "HB" +// prefix to the new ones. +// +// This file will be removed before we do a 2.0 release + +@_documentation(visibility: internal) @available(*, deprecated, renamed: "TestClientProtocol") +public typealias HBXCTClientProtocol = TestClientProtocol +@_documentation(visibility: internal) @available(*, deprecated, renamed: "TestClient") +public typealias HBXCTClient = TestClient +@_documentation(visibility: internal) @available(*, deprecated, renamed: "TestResponse") +public typealias HBXCTResponse = TestResponse From 335e0bb988e644dc17818c8f37a6d59c838a8ead Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sun, 10 Mar 2024 12:02:12 +0000 Subject: [PATCH 10/11] Add HBMiddlewareProtocol --- Sources/Hummingbird/Deprecations.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/Hummingbird/Deprecations.swift b/Sources/Hummingbird/Deprecations.swift index ec926ca45..59081cadb 100644 --- a/Sources/Hummingbird/Deprecations.swift +++ b/Sources/Hummingbird/Deprecations.swift @@ -70,6 +70,8 @@ public typealias HBMetricsMiddleware = MetricsMiddleware public typealias HBMiddlewareGroup = MiddlewareGroup @_documentation(visibility: internal) @available(*, deprecated, renamed: "TracingMiddleware") public typealias HBTracingMiddleware = TracingMiddleware +@_documentation(visibility: internal) @available(*, deprecated, renamed: "RouterMiddleware") +public typealias HBMiddlewareProtocol = RouterMiddleware @_documentation(visibility: internal) @available(*, deprecated, renamed: "CacheControl") public typealias HBCacheControl = CacheControl From 462411fbe670eaa63e9ff69d19824aeb59bf87e8 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sun, 10 Mar 2024 12:24:29 +0000 Subject: [PATCH 11/11] Add HBResponseCodable to deprecations --- Sources/Hummingbird/Deprecations.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/Hummingbird/Deprecations.swift b/Sources/Hummingbird/Deprecations.swift index 59081cadb..81ef0cf7a 100644 --- a/Sources/Hummingbird/Deprecations.swift +++ b/Sources/Hummingbird/Deprecations.swift @@ -39,6 +39,8 @@ public typealias HBCoreRequestContext = CoreRequestContext public typealias HBRequestContext = RequestContext @_documentation(visibility: internal) @available(*, deprecated, renamed: "RequestDecoder") public typealias HBRequestDecoder = RequestDecoder +@_documentation(visibility: internal) @available(*, deprecated, renamed: "ResponseCodable") +public typealias HBResponseCodable = ResponseCodable @_documentation(visibility: internal) @available(*, deprecated, renamed: "ResponseEncodable") public typealias HBResponseEncodable = ResponseEncodable @_documentation(visibility: internal) @available(*, deprecated, renamed: "ResponseEncoder")