Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

2.x.x - Hello and HTTP2 examples #43

Merged
merged 8 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Examples converted to Hummingbird 2.0
- [hello](https://github.com/hummingbird-project/hummingbird-examples/tree/main/hello) - Basic application setup
- [http2](https://github.com/hummingbird-project/hummingbird-examples/tree/main/http2) - Basic application with HTTP2 upgrade added
- [todos-dynamodb](https://github.com/hummingbird-project/hummingbird-examples/tree/main/todos-dynamodb) - Todos application, based off [TodoBackend](http://todobackend.com) spec, using DynamoDB

Examples still working with Hummingbird 1.0
Expand All @@ -10,7 +11,6 @@ Examples still working with Hummingbird 1.0
- [auth-srp](https://github.com/hummingbird-project/hummingbird-examples/tree/main/auth-srp) - Secure Remote Password authentication.
- [graphql-server](https://github.com/hummingbird-project/hummingbird-examples/tree/main/graphql-server) - GraphQL server using [Graphiti](https://github.com/GraphQLSwift/Graphiti)
- [html-form](https://github.com/hummingbird-project/hummingbird-examples/tree/main/html-form) - Link HTML form to Hummingbird application
- [http2](https://github.com/hummingbird-project/hummingbird-examples/tree/main/http2) - Basic application with HTTP2 upgrade added
- [ios-image-server](https://github.com/hummingbird-project/hummingbird-examples/tree/main/ios-image-server) - iOS web server that provides access to iPhone photo library.
- [jobs](https://github.com/hummingbird-project/hummingbird-examples/tree/main/jobs) - Demonstrating offloading of jobs to another server.
- [multipart-form](https://github.com/hummingbird-project/hummingbird-examples/tree/main/multipart-form) - HTML form using Multipart form data, using MultipartKit
Expand Down
1 change: 1 addition & 0 deletions hello/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ let package = Package(
name: "AppTests",
dependencies: [
.byName(name: "App"),
.product(name: "Hummingbird", package: "hummingbird"),
.product(name: "HummingbirdXCT", package: "hummingbird"),
]
),
Expand Down
9 changes: 3 additions & 6 deletions hello/Sources/App/Application+build.swift
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import Hummingbird
import HummingbirdCore
import HummingbirdFoundation

func buildApplication(configuration: HBApplicationConfiguration) -> HBApplication<some HBResponder<HBBasicRequestContext>, HTTP1Channel> {
let router = HBRouterBuilder()
router.middlewares.add(HBFileMiddleware())
func buildApplication(configuration: HBApplicationConfiguration) -> some HBApplicationProtocol {
let router = HBRouter()
router.get("/") { _, _ in
return "Hello"
}
adam-fowler marked this conversation as resolved.
Show resolved Hide resolved

let app = HBApplication(
responder: router.buildResponder(),
router: router,
configuration: configuration
)
return app
Expand Down
19 changes: 8 additions & 11 deletions hello/Tests/AppTests/AppTests.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import App
@testable import App
import Hummingbird
import HummingbirdXCT
import XCTest

final class AppTests: XCTestCase {
func testApp() throws {
let app = HBApplication(testing: .live)
try app.configure()

try app.XCTStart()
defer { app.XCTStop() }

try app.XCTExecute(uri: "/", method: .GET) { response in
XCTAssertEqual(response.status, .ok)
XCTAssertEqual(response.body.map { String(buffer: $0) }, "Hello")
func testApp() async throws {
let app = buildApplication(configuration: .init())
try await app.test(.router) { client in
try await client.XCTExecute(uri: "/", method: .get) { response in
XCTAssertEqual(response.status, .ok)
XCTAssertEqual(String(buffer: response.body), "Hello")
}
}
}
}
11 changes: 4 additions & 7 deletions http2/Package.swift
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
// swift-tools-version:5.7
// swift-tools-version:5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "http2",
platforms: [.macOS(.v10_14)],
platforms: [.macOS(.v14)],
products: [
.executable(name: "App", targets: ["App"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-certificates.git", from: "1.0.0"),
.package(url: "https://github.com/hummingbird-project/hummingbird-core.git", from: "1.0.0"),
.package(url: "https://github.com/hummingbird-project/hummingbird.git", from: "1.0.0"),
.package(url: "https://github.com/hummingbird-project/hummingbird-xct-async-http-client.git", from: "0.1.0"),
.package(url: "https://github.com/hummingbird-project/hummingbird.git", branch: "2.x.x"),
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.0.0"),
],
targets: [
.executableTarget(
name: "App",
dependencies: [
.product(name: "Hummingbird", package: "hummingbird"),
.product(name: "HummingbirdHTTP2", package: "hummingbird-core"),
.product(name: "HummingbirdHTTP2", package: "hummingbird"),
.product(name: "ArgumentParser", package: "swift-argument-parser"),
],
swiftSettings: [
Expand All @@ -37,7 +35,6 @@ let package = Package(
.byName(name: "App"),
.product(name: "X509", package: "swift-certificates"),
.product(name: "HummingbirdXCT", package: "hummingbird"),
.product(name: "HBXCTAsyncHTTPClient", package: "hummingbird-xct-async-http-client"),
]
),
]
Expand Down
50 changes: 50 additions & 0 deletions http2/Sources/App/Application+build.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Hummingbird
import HummingbirdHTTP2
import Logging
import NIOCore
import NIOHTTPTypesHTTP2

public protocol AppArguments {
var tlsConfiguration: TLSConfiguration { get throws }
}

struct ChannelRequestContext: HBRequestContext {
init(allocator: ByteBufferAllocator, logger: Logger) {
self.coreContext = .init(allocator: allocator, logger: logger)
self.channel = nil
}

init(channel: Channel, logger: Logger) {
self.coreContext = .init(allocator: channel.allocator, logger: logger)
self.channel = channel
}

var hasHTTP2Handler: Bool {
get async {
if let channel = self.channel {
return (try? await channel.pipeline.handler(type: HTTP2FramePayloadToHTTPServerCodec.self).get()) != nil
}
return false
}
}

var coreContext: HBCoreRequestContext
let channel: Channel?
}

import Hummingbird

func buildApplication(arguments: some AppArguments, configuration: HBApplicationConfiguration) throws -> some HBApplicationProtocol {
let router = HBRouter(context: ChannelRequestContext.self)
router.get("/http") { _, context in
// return "Using http v\(request.head. == "h2" ? "2.0" : "1.1")"
return "Using http v\(await context.hasHTTP2Handler ? "2.0" : "1.1")"
}

let app = try HBApplication(
router: router,
server: .http2(tlsConfiguration: arguments.tlsConfiguration),
configuration: configuration
)
return app
}
16 changes: 7 additions & 9 deletions http2/Sources/App/app.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import Hummingbird
import NIOSSL

@main
struct HummingbirdArguments: ParsableCommand, AppArguments {
struct HummingbirdArguments: AsyncParsableCommand, AppArguments {
@Option(name: .shortAndLong)
var hostname: String = "127.0.0.1"

@Option(name: .shortAndLong)
var port: Int = 8080
var port: Int = 8081

@Option(name: .shortAndLong, help: "PEM file containing certificate chain")
var certificateChain: String
Expand All @@ -27,16 +27,14 @@ struct HummingbirdArguments: ParsableCommand, AppArguments {
}
}

func run() throws {
let app = HBApplication(
func run() async throws {
let app = try buildApplication(
arguments: self,
configuration: .init(
address: .hostname(self.hostname, port: self.port),
serverName: "Hummingbird",
idleTimeoutConfiguration: .init(readTimeout: .seconds(5), writeTimeout: .seconds(5))
serverName: "Hummingbird"
)
)
try app.configure(self)
try app.start()
app.wait()
try await app.runService()
}
}
24 changes: 0 additions & 24 deletions http2/Sources/App/application+configure.swift

This file was deleted.

31 changes: 11 additions & 20 deletions http2/Tests/AppTests/AppTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
@testable import App
import Crypto
import HBXCTAsyncHTTPClient
import Hummingbird
import HummingbirdXCT
import NIOHTTP2
Expand Down Expand Up @@ -48,27 +47,19 @@ struct TestAppArguments: AppArguments {
}

final class AppTests: XCTestCase {
func testApp() throws {
var clientConfiguration = TLSConfiguration.makeClientConfiguration()
clientConfiguration.certificateVerification = .none
let app = HBApplication(
testing: .ahc(scheme: .https),
configuration: .init(idleTimeoutConfiguration: .init(readTimeout: .seconds(5), writeTimeout: .seconds(5))),
clientConfiguration: .init(tlsConfiguration: clientConfiguration)
)
try app.configure(TestAppArguments())
func testApp() async throws {
let app = try buildApplication(arguments: TestAppArguments(), configuration: .init())

try app.XCTStart()
defer { app.XCTStop() }

try app.XCTExecute(uri: "/http", method: .GET) { response in
XCTAssertEqual(response.status, .ok)
XCTAssertEqual(response.body.map { String(buffer: $0) }, "Using http v2.0")
}
try await app.test(.ahc(.https)) { client in
try await client.XCTExecute(uri: "/http", method: .get) { response in
XCTAssertEqual(response.status, .ok)
XCTAssertEqual(String(buffer: response.body), "Using http v2.0")
}

try app.XCTExecute(uri: "/http", method: .GET) { response in
XCTAssertEqual(response.status, .ok)
XCTAssertEqual(response.body.map { String(buffer: $0) }, "Using http v2.0")
try await client.XCTExecute(uri: "/http", method: .get) { response in
XCTAssertEqual(response.status, .ok)
XCTAssertEqual(String(buffer: response.body), "Using http v2.0")
}
}
}
}