Skip to content

Commit

Permalink
2.x.x - Hello and HTTP2 examples (#43)
Browse files Browse the repository at this point in the history
* Fix hello tests

* HTTP2

* Update README

* Update README

* Update for changes on 2.x.x

* Don’t export HBXCTAsyncHTTPClient

* Update http2/Sources/App/Application+build.swift

Co-authored-by: Joannis Orlandos <[email protected]>

* Fix up after changes to Hummingbird

---------

Co-authored-by: Joannis Orlandos <[email protected]>
  • Loading branch information
adam-fowler and Joannis authored Jan 17, 2024
1 parent dd83013 commit a18dcc2
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 78 deletions.
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"
}

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")
}
}
}
}

0 comments on commit a18dcc2

Please sign in to comment.