Skip to content

Commit a4aaa63

Browse files
committed
Integrate swift-configuration
1 parent 2a97348 commit a4aaa63

File tree

9 files changed

+513
-3
lines changed

9 files changed

+513
-3
lines changed

Package.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:6.0
1+
// swift-tools-version:6.1
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
@@ -9,7 +9,7 @@ let swiftSettings: [SwiftSetting] = [
99

1010
let package = Package(
1111
name: "hummingbird",
12-
platforms: [.macOS(.v14), .iOS(.v17), .macCatalyst(.v17), .tvOS(.v17), .visionOS(.v1)],
12+
platforms: [.macOS(.v15), .iOS(.v17), .macCatalyst(.v17), .tvOS(.v17), .visionOS(.v1)],
1313
products: [
1414
.library(name: "Hummingbird", targets: ["Hummingbird"]),
1515
.library(name: "HummingbirdCore", targets: ["HummingbirdCore"]),
@@ -19,6 +19,10 @@ let package = Package(
1919
.library(name: "HummingbirdTesting", targets: ["HummingbirdTesting"]),
2020
.executable(name: "PerformanceTest", targets: ["PerformanceTest"]),
2121
],
22+
traits: [
23+
.trait(name: "ExperimentalConfiguration"),
24+
.default(enabledTraits: ["ExperimentalConfiguration"]),
25+
],
2226
dependencies: [
2327
.package(url: "https://github.com/apple/swift-async-algorithms.git", from: "1.0.2"),
2428
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.0"),
@@ -34,6 +38,7 @@ let package = Package(
3438
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.20.0"),
3539
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.0.0"),
3640
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.19.0"),
41+
.package(url: "https://github.com/apple/swift-configuration.git", from: "0.1.1"),
3742
],
3843
targets: [
3944
.target(
@@ -43,6 +48,7 @@ let package = Package(
4348
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
4449
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
4550
.product(name: "Atomics", package: "swift-atomics"),
51+
.product(name: "Configuration", package: "swift-configuration", condition: .when(traits: ["ExperimentalConfiguration"])),
4652
.product(name: "HTTPTypes", package: "swift-http-types"),
4753
.product(name: "Logging", package: "swift-log"),
4854
.product(name: "Metrics", package: "swift-metrics"),
@@ -57,6 +63,7 @@ let package = Package(
5763
dependencies: [
5864
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
5965
.product(name: "Collections", package: "swift-collections"),
66+
.product(name: "Configuration", package: "swift-configuration", condition: .when(traits: ["ExperimentalConfiguration"])),
6067
.product(name: "HTTPTypes", package: "swift-http-types"),
6168
.product(name: "Logging", package: "swift-log"),
6269
.product(name: "NIOCore", package: "swift-nio"),
@@ -102,6 +109,7 @@ let package = Package(
102109
name: "HummingbirdHTTP2",
103110
dependencies: [
104111
.byName(name: "HummingbirdCore"),
112+
.product(name: "Configuration", package: "swift-configuration", condition: .when(traits: ["ExperimentalConfiguration"])),
105113
.product(name: "NIOCore", package: "swift-nio"),
106114
.product(name: "NIOHTTP2", package: "swift-nio-http2"),
107115
.product(name: "NIOHTTPTypes", package: "swift-nio-extras"),
@@ -114,6 +122,7 @@ let package = Package(
114122
name: "HummingbirdTLS",
115123
dependencies: [
116124
.byName(name: "HummingbirdCore"),
125+
.product(name: "Configuration", package: "swift-configuration", condition: .when(traits: ["ExperimentalConfiguration"])),
117126
.product(name: "NIOCore", package: "swift-nio"),
118127
.product(name: "NIOSSL", package: "swift-nio-ssl"),
119128
],

[email protected]

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// swift-tools-version:6.0
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let swiftSettings: [SwiftSetting] = [
7+
.enableUpcomingFeature("ExistentialAny")
8+
]
9+
10+
let package = Package(
11+
name: "hummingbird",
12+
platforms: [.macOS(.v14), .iOS(.v17), .macCatalyst(.v17), .tvOS(.v17), .visionOS(.v1)],
13+
products: [
14+
.library(name: "Hummingbird", targets: ["Hummingbird"]),
15+
.library(name: "HummingbirdCore", targets: ["HummingbirdCore"]),
16+
.library(name: "HummingbirdHTTP2", targets: ["HummingbirdHTTP2"]),
17+
.library(name: "HummingbirdTLS", targets: ["HummingbirdTLS"]),
18+
.library(name: "HummingbirdRouter", targets: ["HummingbirdRouter"]),
19+
.library(name: "HummingbirdTesting", targets: ["HummingbirdTesting"]),
20+
.executable(name: "PerformanceTest", targets: ["PerformanceTest"]),
21+
],
22+
dependencies: [
23+
.package(url: "https://github.com/apple/swift-async-algorithms.git", from: "1.0.2"),
24+
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.0"),
25+
.package(url: "https://github.com/apple/swift-collections.git", from: "1.0.0"),
26+
.package(url: "https://github.com/apple/swift-log.git", from: "1.4.0"),
27+
.package(url: "https://github.com/apple/swift-http-types.git", from: "1.0.0"),
28+
.package(url: "https://github.com/apple/swift-metrics.git", from: "2.5.0"),
29+
.package(url: "https://github.com/apple/swift-distributed-tracing.git", from: "1.1.0"),
30+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.83.0"),
31+
.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.20.0"),
32+
.package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.38.0"),
33+
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.14.0"),
34+
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.20.0"),
35+
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.0.0"),
36+
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.19.0"),
37+
],
38+
targets: [
39+
.target(
40+
name: "Hummingbird",
41+
dependencies: [
42+
.byName(name: "HummingbirdCore"),
43+
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
44+
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
45+
.product(name: "Atomics", package: "swift-atomics"),
46+
.product(name: "HTTPTypes", package: "swift-http-types"),
47+
.product(name: "Logging", package: "swift-log"),
48+
.product(name: "Metrics", package: "swift-metrics"),
49+
.product(name: "Tracing", package: "swift-distributed-tracing"),
50+
.product(name: "NIOCore", package: "swift-nio"),
51+
.product(name: "NIOPosix", package: "swift-nio"),
52+
],
53+
swiftSettings: swiftSettings
54+
),
55+
.target(
56+
name: "HummingbirdCore",
57+
dependencies: [
58+
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
59+
.product(name: "Collections", package: "swift-collections"),
60+
.product(name: "HTTPTypes", package: "swift-http-types"),
61+
.product(name: "Logging", package: "swift-log"),
62+
.product(name: "NIOCore", package: "swift-nio"),
63+
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
64+
.product(name: "NIOHTTPTypes", package: "swift-nio-extras"),
65+
.product(name: "NIOHTTPTypesHTTP1", package: "swift-nio-extras"),
66+
.product(name: "NIOExtras", package: "swift-nio-extras"),
67+
.product(name: "NIOPosix", package: "swift-nio"),
68+
.product(
69+
name: "NIOTransportServices",
70+
package: "swift-nio-transport-services",
71+
condition: .when(platforms: [.macOS, .iOS, .macCatalyst, .tvOS, .visionOS])
72+
),
73+
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
74+
],
75+
swiftSettings: swiftSettings
76+
),
77+
.target(
78+
name: "HummingbirdRouter",
79+
dependencies: [
80+
.byName(name: "Hummingbird"),
81+
.product(name: "Logging", package: "swift-log"),
82+
],
83+
swiftSettings: swiftSettings
84+
),
85+
.target(
86+
name: "HummingbirdTesting",
87+
dependencies: [
88+
.byName(name: "Hummingbird"),
89+
.product(name: "AsyncHTTPClient", package: "async-http-client"),
90+
.product(name: "HTTPTypes", package: "swift-http-types"),
91+
.product(name: "NIOCore", package: "swift-nio"),
92+
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
93+
.product(name: "NIOEmbedded", package: "swift-nio"),
94+
.product(name: "NIOHTTPTypes", package: "swift-nio-extras"),
95+
.product(name: "NIOHTTPTypesHTTP1", package: "swift-nio-extras"),
96+
.product(name: "NIOPosix", package: "swift-nio"),
97+
.product(name: "NIOSSL", package: "swift-nio-ssl"),
98+
],
99+
swiftSettings: swiftSettings
100+
),
101+
.target(
102+
name: "HummingbirdHTTP2",
103+
dependencies: [
104+
.byName(name: "HummingbirdCore"),
105+
.product(name: "NIOCore", package: "swift-nio"),
106+
.product(name: "NIOHTTP2", package: "swift-nio-http2"),
107+
.product(name: "NIOHTTPTypes", package: "swift-nio-extras"),
108+
.product(name: "NIOHTTPTypesHTTP1", package: "swift-nio-extras"),
109+
.product(name: "NIOHTTPTypesHTTP2", package: "swift-nio-extras"),
110+
.product(name: "NIOSSL", package: "swift-nio-ssl"),
111+
]
112+
),
113+
.target(
114+
name: "HummingbirdTLS",
115+
dependencies: [
116+
.byName(name: "HummingbirdCore"),
117+
.product(name: "NIOCore", package: "swift-nio"),
118+
.product(name: "NIOSSL", package: "swift-nio-ssl"),
119+
],
120+
swiftSettings: [.enableExperimentalFeature("StrictConcurrency=complete")]
121+
),
122+
.executableTarget(
123+
name: "PerformanceTest",
124+
dependencies: [
125+
.byName(name: "Hummingbird"),
126+
.product(name: "NIOPosix", package: "swift-nio"),
127+
],
128+
swiftSettings: [.enableExperimentalFeature("StrictConcurrency=complete")]
129+
),
130+
// test targets
131+
.testTarget(
132+
name: "HummingbirdTests",
133+
dependencies: [
134+
.byName(name: "Hummingbird"),
135+
.byName(name: "HummingbirdTLS"),
136+
.byName(name: "HummingbirdHTTP2"),
137+
.byName(name: "HummingbirdTesting"),
138+
.byName(name: "HummingbirdRouter"),
139+
]
140+
),
141+
.testTarget(
142+
name: "HummingbirdRouterTests",
143+
dependencies: [
144+
.byName(name: "HummingbirdRouter"),
145+
.byName(name: "HummingbirdTesting"),
146+
]
147+
),
148+
.testTarget(
149+
name: "HummingbirdCoreTests",
150+
dependencies: [
151+
.byName(name: "HummingbirdCore"),
152+
.byName(name: "HummingbirdTLS"),
153+
.byName(name: "HummingbirdTesting"),
154+
.product(name: "AsyncHTTPClient", package: "async-http-client"),
155+
],
156+
resources: [.process("Certificates")]
157+
),
158+
.testTarget(
159+
name: "HummingbirdHTTP2Tests",
160+
dependencies: [
161+
.byName(name: "HummingbirdCore"),
162+
.byName(name: "HummingbirdHTTP2"),
163+
.byName(name: "HummingbirdTesting"),
164+
.product(name: "AsyncHTTPClient", package: "async-http-client"),
165+
]
166+
),
167+
]
168+
)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Hummingbird server framework project
4+
//
5+
// Copyright (c) 2025 the Hummingbird authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#if ExperimentalConfiguration
16+
17+
public import Configuration
18+
19+
@available(macOS 15, iOS 18, macCatalyst 18, tvOS 18, visionOS 2, *)
20+
extension ApplicationConfiguration {
21+
/// Initialize a ApplicationConfiguration from a ConfigReader
22+
///
23+
/// - Configuration keys:
24+
/// - `host` (string, optional, default: "127.0.0.1"): Hostname or IP to bind server to
25+
/// - `port` (int, optional, default: 8080): Port to bind server to
26+
/// - `unix.domain.socket` (string, optional): Unix domain socket name
27+
/// - `server.name` (string, optional): Server name reported in HTTP headers
28+
///
29+
/// - Parameters
30+
/// - reader: ConfigReader
31+
public init(reader: ConfigReader) {
32+
var configuration = Self()
33+
if let hostname = reader.string(forKey: "host") {
34+
let port = reader.int(forKey: "port", default: 8080)
35+
configuration.address = .hostname(hostname, port: port)
36+
} else if let unixDomainSocket = reader.string(forKey: "unix.domain.socket") {
37+
configuration.address = .unixDomainSocket(path: unixDomainSocket)
38+
}
39+
if let serverName = reader.string(forKey: "server.name") {
40+
configuration.serverName = serverName
41+
}
42+
self = configuration
43+
}
44+
}
45+
46+
#endif
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Hummingbird server framework project
4+
//
5+
// Copyright (c) 2025the Hummingbird authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#if ExperimentalConfiguration
16+
17+
public import Configuration
18+
19+
@available(macOS 15, iOS 18, macCatalyst 18, tvOS 18, visionOS 2, *)
20+
extension HTTP1Channel.Configuration {
21+
/// Initialize a HTTP1Channel.Configuration from a ConfigReader
22+
///
23+
/// - Configuration keys
24+
/// - `idle.timeout` (double, optional): Time in seconds a connection can be left idle before closing
25+
///
26+
/// - Parameters
27+
/// - reader: ConfigReader
28+
public init(reader: ConfigReader) {
29+
var configuration = Self()
30+
if let idleTimeout = reader.double(forKey: "idle.timeout") {
31+
configuration.idleTimeout = .nanoseconds(Int64(idleTimeout * 1_000_000_000))
32+
}
33+
self = configuration
34+
}
35+
}
36+
37+
#endif
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Hummingbird server framework project
4+
//
5+
// Copyright (c) 2025 the Hummingbird authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#if ExperimentalConfiguration
16+
17+
public import Configuration
18+
import HummingbirdCore
19+
20+
@available(macOS 15, iOS 18, macCatalyst 18, tvOS 18, visionOS 2, *)
21+
extension HTTP2Channel.Configuration {
22+
/// Initialize a HTTP2Channel.Configuration from a ConfigReader
23+
///
24+
/// - Configuration Keys
25+
/// - `h2.idle.timeout` (double optional): Time in seconds before an HTTP2 connection should be closed.
26+
/// - `h2.graceful.close.timeout` (double optional): Time in seconds to wait for client response after
27+
/// all streams have been closed.
28+
/// - `h2.max.age.timeout` (double optional): Maximum time in seconds a connection can stay open.
29+
/// - `h2.stream`: HTTP2 stream options. See ``HTTP1Channel/Configuration/init(reader:)``
30+
///
31+
/// - Parameters
32+
/// - reader: ConfigReader
33+
public init(reader: ConfigReader) {
34+
var configuration = Self()
35+
if let idleTimeout = reader.double(forKey: "h2.idle.timeout") {
36+
configuration.idleTimeout = .seconds(idleTimeout)
37+
}
38+
if let gracefulCloseTimeout = reader.double(forKey: "h2.graceful.close.timeout") {
39+
configuration.gracefulCloseTimeout = .seconds(gracefulCloseTimeout)
40+
}
41+
if let maxAgeTimeout = reader.double(forKey: "h2.max.age.timeout") {
42+
configuration.maxAgeTimeout = .seconds(maxAgeTimeout)
43+
}
44+
let streamReader = reader.scoped(to: "h2.stream")
45+
configuration.streamConfiguration = HTTP1Channel.Configuration(reader: streamReader)
46+
self = configuration
47+
}
48+
}
49+
50+
#endif

0 commit comments

Comments
 (0)