Skip to content

Commit 986dc47

Browse files
authored
Add swift-configuration support (#878)
Users should be able to use swift-configuration to create the http client configuration object Changes - duplicate package.swift to create a separate version for 6.0 and 6.1, since Configuration is 6.2+ - add helper to create http client configuration using ConfigReader
1 parent e2ab0d1 commit 986dc47

6 files changed

Lines changed: 692 additions & 3 deletions

File tree

Package.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:6.0
1+
// swift-tools-version:6.2
22
//===----------------------------------------------------------------------===//
33
//
44
// This source file is part of the AsyncHTTPClient open source project
@@ -44,6 +44,7 @@ let package = Package(
4444
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.2"),
4545
.package(url: "https://github.com/apple/swift-algorithms.git", from: "1.0.0"),
4646
.package(url: "https://github.com/apple/swift-distributed-tracing.git", from: "1.3.0"),
47+
.package(url: "https://github.com/apple/swift-configuration.git", from: "1.0.0"),
4748
],
4849
targets: [
4950
.target(
@@ -69,6 +70,7 @@ let package = Package(
6970
.product(name: "NIOTransportServices", package: "swift-nio-transport-services"),
7071
.product(name: "Atomics", package: "swift-atomics"),
7172
.product(name: "Algorithms", package: "swift-algorithms"),
73+
.product(name: "Configuration", package: "swift-configuration"),
7274
// Observability support
7375
.product(name: "Logging", package: "swift-log"),
7476
.product(name: "Tracing", package: "swift-distributed-tracing"),
@@ -90,6 +92,7 @@ let package = Package(
9092
.product(name: "NIOSOCKS", package: "swift-nio-extras"),
9193
.product(name: "Atomics", package: "swift-atomics"),
9294
.product(name: "Algorithms", package: "swift-algorithms"),
95+
.product(name: "Configuration", package: "swift-configuration"),
9396
// Observability support
9497
.product(name: "Logging", package: "swift-log"),
9598
.product(name: "InMemoryLogging", package: "swift-log"),

Package@swift-6.0.swift

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// swift-tools-version:6.0
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// This source file is part of the AsyncHTTPClient open source project
5+
//
6+
// Copyright (c) 2018-2019 Apple Inc. and the AsyncHTTPClient project authors
7+
// Licensed under Apache License v2.0
8+
//
9+
// See LICENSE.txt for license information
10+
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
11+
//
12+
// SPDX-License-Identifier: Apache-2.0
13+
//
14+
//===----------------------------------------------------------------------===//
15+
16+
import PackageDescription
17+
18+
let strictConcurrencyDevelopment = false
19+
20+
let strictConcurrencySettings: [SwiftSetting] = {
21+
var initialSettings: [SwiftSetting] = []
22+
23+
if strictConcurrencyDevelopment {
24+
// -warnings-as-errors here is a workaround so that IDE-based development can
25+
// get tripped up on -require-explicit-sendable.
26+
initialSettings.append(.unsafeFlags(["-Xfrontend", "-require-explicit-sendable", "-warnings-as-errors"]))
27+
}
28+
29+
return initialSettings
30+
}()
31+
32+
let package = Package(
33+
name: "async-http-client",
34+
products: [
35+
.library(name: "AsyncHTTPClient", targets: ["AsyncHTTPClient"])
36+
],
37+
dependencies: [
38+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.81.0"),
39+
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.30.0"),
40+
.package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.36.0"),
41+
.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.26.0"),
42+
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.24.0"),
43+
.package(url: "https://github.com/apple/swift-log.git", from: "1.7.1"),
44+
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.2"),
45+
.package(url: "https://github.com/apple/swift-algorithms.git", from: "1.0.0"),
46+
.package(url: "https://github.com/apple/swift-distributed-tracing.git", from: "1.3.0"),
47+
],
48+
targets: [
49+
.target(
50+
name: "CAsyncHTTPClient",
51+
cSettings: [
52+
.define("_GNU_SOURCE")
53+
]
54+
),
55+
.target(
56+
name: "AsyncHTTPClient",
57+
dependencies: [
58+
.target(name: "CAsyncHTTPClient"),
59+
.product(name: "NIO", package: "swift-nio"),
60+
.product(name: "NIOTLS", package: "swift-nio"),
61+
.product(name: "NIOCore", package: "swift-nio"),
62+
.product(name: "NIOPosix", package: "swift-nio"),
63+
.product(name: "NIOHTTP1", package: "swift-nio"),
64+
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
65+
.product(name: "NIOHTTP2", package: "swift-nio-http2"),
66+
.product(name: "NIOSSL", package: "swift-nio-ssl"),
67+
.product(name: "NIOHTTPCompression", package: "swift-nio-extras"),
68+
.product(name: "NIOSOCKS", package: "swift-nio-extras"),
69+
.product(name: "NIOTransportServices", package: "swift-nio-transport-services"),
70+
.product(name: "Atomics", package: "swift-atomics"),
71+
.product(name: "Algorithms", package: "swift-algorithms"),
72+
// Observability support
73+
.product(name: "Logging", package: "swift-log"),
74+
.product(name: "Tracing", package: "swift-distributed-tracing"),
75+
],
76+
swiftSettings: strictConcurrencySettings
77+
),
78+
.testTarget(
79+
name: "AsyncHTTPClientTests",
80+
dependencies: [
81+
.target(name: "AsyncHTTPClient"),
82+
.product(name: "NIOTLS", package: "swift-nio"),
83+
.product(name: "NIOCore", package: "swift-nio"),
84+
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
85+
.product(name: "NIOEmbedded", package: "swift-nio"),
86+
.product(name: "NIOFoundationCompat", package: "swift-nio"),
87+
.product(name: "NIOTestUtils", package: "swift-nio"),
88+
.product(name: "NIOSSL", package: "swift-nio-ssl"),
89+
.product(name: "NIOHTTP2", package: "swift-nio-http2"),
90+
.product(name: "NIOSOCKS", package: "swift-nio-extras"),
91+
.product(name: "Atomics", package: "swift-atomics"),
92+
.product(name: "Algorithms", package: "swift-algorithms"),
93+
// Observability support
94+
.product(name: "Logging", package: "swift-log"),
95+
.product(name: "InMemoryLogging", package: "swift-log"),
96+
.product(name: "Tracing", package: "swift-distributed-tracing"),
97+
.product(name: "InMemoryTracing", package: "swift-distributed-tracing"),
98+
],
99+
resources: [
100+
.copy("Resources/self_signed_cert.pem"),
101+
.copy("Resources/self_signed_key.pem"),
102+
.copy("Resources/example.com.cert.pem"),
103+
.copy("Resources/example.com.private-key.pem"),
104+
],
105+
swiftSettings: strictConcurrencySettings
106+
),
107+
]
108+
)
109+
110+
// --- STANDARD CROSS-REPO SETTINGS DO NOT EDIT --- //
111+
for target in package.targets {
112+
switch target.type {
113+
case .regular, .test, .executable:
114+
var settings = target.swiftSettings ?? []
115+
// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md
116+
settings.append(.enableUpcomingFeature("MemberImportVisibility"))
117+
target.swiftSettings = settings
118+
case .macro, .plugin, .system, .binary:
119+
() // not applicable
120+
@unknown default:
121+
() // we don't know what to do here, do nothing
122+
}
123+
}
124+
// --- END: STANDARD CROSS-REPO SETTINGS DO NOT EDIT --- //

Package@swift-6.1.swift

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// swift-tools-version:6.0
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// This source file is part of the AsyncHTTPClient open source project
5+
//
6+
// Copyright (c) 2018-2019 Apple Inc. and the AsyncHTTPClient project authors
7+
// Licensed under Apache License v2.0
8+
//
9+
// See LICENSE.txt for license information
10+
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
11+
//
12+
// SPDX-License-Identifier: Apache-2.0
13+
//
14+
//===----------------------------------------------------------------------===//
15+
16+
import PackageDescription
17+
18+
let strictConcurrencyDevelopment = false
19+
20+
let strictConcurrencySettings: [SwiftSetting] = {
21+
var initialSettings: [SwiftSetting] = []
22+
23+
if strictConcurrencyDevelopment {
24+
// -warnings-as-errors here is a workaround so that IDE-based development can
25+
// get tripped up on -require-explicit-sendable.
26+
initialSettings.append(.unsafeFlags(["-Xfrontend", "-require-explicit-sendable", "-warnings-as-errors"]))
27+
}
28+
29+
return initialSettings
30+
}()
31+
32+
let package = Package(
33+
name: "async-http-client",
34+
products: [
35+
.library(name: "AsyncHTTPClient", targets: ["AsyncHTTPClient"])
36+
],
37+
dependencies: [
38+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.81.0"),
39+
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.30.0"),
40+
.package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.36.0"),
41+
.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.26.0"),
42+
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.24.0"),
43+
.package(url: "https://github.com/apple/swift-log.git", from: "1.7.1"),
44+
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.2"),
45+
.package(url: "https://github.com/apple/swift-algorithms.git", from: "1.0.0"),
46+
.package(url: "https://github.com/apple/swift-distributed-tracing.git", from: "1.3.0"),
47+
],
48+
targets: [
49+
.target(
50+
name: "CAsyncHTTPClient",
51+
cSettings: [
52+
.define("_GNU_SOURCE")
53+
]
54+
),
55+
.target(
56+
name: "AsyncHTTPClient",
57+
dependencies: [
58+
.target(name: "CAsyncHTTPClient"),
59+
.product(name: "NIO", package: "swift-nio"),
60+
.product(name: "NIOTLS", package: "swift-nio"),
61+
.product(name: "NIOCore", package: "swift-nio"),
62+
.product(name: "NIOPosix", package: "swift-nio"),
63+
.product(name: "NIOHTTP1", package: "swift-nio"),
64+
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
65+
.product(name: "NIOHTTP2", package: "swift-nio-http2"),
66+
.product(name: "NIOSSL", package: "swift-nio-ssl"),
67+
.product(name: "NIOHTTPCompression", package: "swift-nio-extras"),
68+
.product(name: "NIOSOCKS", package: "swift-nio-extras"),
69+
.product(name: "NIOTransportServices", package: "swift-nio-transport-services"),
70+
.product(name: "Atomics", package: "swift-atomics"),
71+
.product(name: "Algorithms", package: "swift-algorithms"),
72+
// Observability support
73+
.product(name: "Logging", package: "swift-log"),
74+
.product(name: "Tracing", package: "swift-distributed-tracing"),
75+
],
76+
swiftSettings: strictConcurrencySettings
77+
),
78+
.testTarget(
79+
name: "AsyncHTTPClientTests",
80+
dependencies: [
81+
.target(name: "AsyncHTTPClient"),
82+
.product(name: "NIOTLS", package: "swift-nio"),
83+
.product(name: "NIOCore", package: "swift-nio"),
84+
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
85+
.product(name: "NIOEmbedded", package: "swift-nio"),
86+
.product(name: "NIOFoundationCompat", package: "swift-nio"),
87+
.product(name: "NIOTestUtils", package: "swift-nio"),
88+
.product(name: "NIOSSL", package: "swift-nio-ssl"),
89+
.product(name: "NIOHTTP2", package: "swift-nio-http2"),
90+
.product(name: "NIOSOCKS", package: "swift-nio-extras"),
91+
.product(name: "Atomics", package: "swift-atomics"),
92+
.product(name: "Algorithms", package: "swift-algorithms"),
93+
// Observability support
94+
.product(name: "Logging", package: "swift-log"),
95+
.product(name: "InMemoryLogging", package: "swift-log"),
96+
.product(name: "Tracing", package: "swift-distributed-tracing"),
97+
.product(name: "InMemoryTracing", package: "swift-distributed-tracing"),
98+
],
99+
resources: [
100+
.copy("Resources/self_signed_cert.pem"),
101+
.copy("Resources/self_signed_key.pem"),
102+
.copy("Resources/example.com.cert.pem"),
103+
.copy("Resources/example.com.private-key.pem"),
104+
],
105+
swiftSettings: strictConcurrencySettings
106+
),
107+
]
108+
)
109+
110+
// --- STANDARD CROSS-REPO SETTINGS DO NOT EDIT --- //
111+
for target in package.targets {
112+
switch target.type {
113+
case .regular, .test, .executable:
114+
var settings = target.swiftSettings ?? []
115+
// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md
116+
settings.append(.enableUpcomingFeature("MemberImportVisibility"))
117+
target.swiftSettings = settings
118+
case .macro, .plugin, .system, .binary:
119+
() // not applicable
120+
@unknown default:
121+
() // we don't know what to do here, do nothing
122+
}
123+
}
124+
// --- END: STANDARD CROSS-REPO SETTINGS DO NOT EDIT --- //

Sources/AsyncHTTPClient/HTTPClient.swift

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ extension HTTPClient.Configuration {
12651265

12661266
/// Specifies redirect processing settings.
12671267
public struct RedirectConfiguration: Sendable {
1268-
enum Mode {
1268+
enum Mode: Hashable {
12691269
/// Redirects are not followed.
12701270
case disallow
12711271
/// Redirects are followed with a specified limit.
@@ -1340,7 +1340,7 @@ extension HTTPClient.Configuration {
13401340
}
13411341

13421342
public struct HTTPVersion: Sendable, Hashable {
1343-
enum Configuration {
1343+
enum Configuration: String {
13441344
case http1Only
13451345
case automatic
13461346
}
@@ -1394,6 +1394,9 @@ public struct HTTPClientError: Error, Equatable, CustomStringConvertible {
13941394
case deadlineExceeded
13951395
case httpEndReceivedAfterHeadWith1xx
13961396
case shutdownUnsupported
1397+
case invalidRedirectConfiguration
1398+
case invalidHTTPVersionConfiguration
1399+
case invalidDNSOverridesConfiguration
13971400
case internalStateFailure(file: String, line: UInt)
13981401
}
13991402

@@ -1480,6 +1483,13 @@ public struct HTTPClientError: Error, Equatable, CustomStringConvertible {
14801483
return "HTTP end received after head with 1xx"
14811484
case .shutdownUnsupported:
14821485
return "The global singleton HTTP client cannot be shut down"
1486+
case .invalidRedirectConfiguration:
1487+
return "The redirect mode specified in the configuration is not a valid value"
1488+
case .invalidHTTPVersionConfiguration:
1489+
return "The HTTP version specified in the configuration is not a valid value"
1490+
case .invalidDNSOverridesConfiguration:
1491+
return
1492+
"The DNS overrides specified in the configuration are not valid. Please specify in the format hostname1:ip1,hostname2:ip2"
14831493
case .internalStateFailure(let file, let line):
14841494
return
14851495
"An internal state failure has occurred (File: \(file), line: \(line)). Please open an issue with a reproducer if possible"
@@ -1574,6 +1584,15 @@ public struct HTTPClientError: Error, Equatable, CustomStringConvertible {
15741584
/// - Tasks are not processed fast enough on the existing connections, to process all waiters in time
15751585
public static let getConnectionFromPoolTimeout = HTTPClientError(code: .getConnectionFromPoolTimeout)
15761586

1587+
/// The redirect mode specified in the configuration is not a valid value.
1588+
public static let invalidRedirectConfiguration = HTTPClientError(code: .invalidRedirectConfiguration)
1589+
1590+
/// The http version specified in the configuration is not a valid value.
1591+
public static let invalidHTTPVersionConfiguration = HTTPClientError(code: .invalidHTTPVersionConfiguration)
1592+
1593+
/// The DNS overrides specified in the configuration are not valid.
1594+
public static let invalidDNSOverridesConfiguration = HTTPClientError(code: .invalidDNSOverridesConfiguration)
1595+
15771596
/// A state machine has reached an unsupported state, that wasn't considered when implementing.
15781597
public static func internalStateFailure(file: String = #fileID, line: UInt = #line) -> HTTPClientError {
15791598
HTTPClientError(code: .internalStateFailure(file: file, line: line))

0 commit comments

Comments
 (0)