diff --git a/Package.swift b/Package.swift index de42a4c..dace077 100644 --- a/Package.swift +++ b/Package.swift @@ -96,6 +96,7 @@ let package = Package( .product(name: "AsyncHTTPClient", package: "async-http-client"), .product(name: "NIOHTTP1", package: "swift-nio"), + .product(name: "NIOSSL", package: "swift-nio-ssl"), ], swiftSettings: extraSettings ), diff --git a/Sources/AHCHTTPClient/AHC+HTTPClient.swift b/Sources/AHCHTTPClient/AHC+HTTPClient.swift index 5500e63..fa231db 100644 --- a/Sources/AHCHTTPClient/AHC+HTTPClient.swift +++ b/Sources/AHCHTTPClient/AHC+HTTPClient.swift @@ -18,6 +18,7 @@ import Foundation import HTTPTypes import NIOCore import NIOHTTP1 +import NIOSSL import Synchronization @available(anyAppleOS 26.0, *) @@ -25,8 +26,8 @@ extension AsyncHTTPClient.HTTPClient: HTTPAPIs.HTTPClient { public typealias RequestWriter = RequestBodyWriter public typealias ResponseConcludingReader = ResponseReader - public struct RequestOptions: HTTPClientCapability.RequestOptions { - + public struct RequestOptions: HTTPClientCapability.DeclarativeTLS { + public var serverTrustPolicy: TrustEvaluationPolicy = .default } public struct RequestBodyWriter: AsyncWriter, ~Copyable { @@ -163,6 +164,7 @@ extension AsyncHTTPClient.HTTPClient: HTTPAPIs.HTTPClient { let sequence = request.headerFields.lazy.map({ ($0.name.rawName, $0.value) }) ahcRequest.headers.add(contentsOf: sequence) } + ahcRequest.tlsConfiguration = Self.tlsConfiguration(for: options.serverTrustPolicy) if let body, body.knownLength != 0 { let (asyncStream, startUploadContinuation) = AsyncStream.makeStream(of: HTTPClientRequest.Body.RequestWriter.self) @@ -217,4 +219,19 @@ extension AsyncHTTPClient.HTTPClient: HTTPAPIs.HTTPClient { return try result!.get() } + + private static func tlsConfiguration(for policy: TrustEvaluationPolicy) -> TLSConfiguration? { + switch policy { + case .default: + return nil + case .allowNameMismatch: + var config = TLSConfiguration.makeClientConfiguration() + config.certificateVerification = .noHostnameVerification + return config + case .allowAny: + var config = TLSConfiguration.makeClientConfiguration() + config.certificateVerification = .none + return config + } + } } diff --git a/Sources/URLSessionHTTPClient/HTTPClientCapability+DeclarativeTLSHandler.swift b/Sources/HTTPAPIs/Client/HTTPClientCapability+DeclarativeTLS.swift similarity index 96% rename from Sources/URLSessionHTTPClient/HTTPClientCapability+DeclarativeTLSHandler.swift rename to Sources/HTTPAPIs/Client/HTTPClientCapability+DeclarativeTLS.swift index 894c295..8c07b28 100644 --- a/Sources/URLSessionHTTPClient/HTTPClientCapability+DeclarativeTLSHandler.swift +++ b/Sources/HTTPAPIs/Client/HTTPClientCapability+DeclarativeTLS.swift @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +public import NetworkTypes + @available(anyAppleOS 26.0, *) extension HTTPClientCapability { /// A protocol for HTTP request options that support TLS policies. diff --git a/Sources/HTTPAPIs/HTTP.swift b/Sources/HTTPAPIs/HTTP.swift index 9ceab1c..e98e2f3 100644 --- a/Sources/HTTPAPIs/HTTP.swift +++ b/Sources/HTTPAPIs/HTTP.swift @@ -14,6 +14,7 @@ @_exported public import AsyncStreaming @_exported public import ContainersPreview @_exported public import HTTPTypes +@_exported public import NetworkTypes /// The namespace for HTTP. public enum HTTP {} diff --git a/Sources/HTTPClient/DefaultHTTPClient.swift b/Sources/HTTPClient/DefaultHTTPClient.swift index 3d1d5d5..05bee49 100644 --- a/Sources/HTTPClient/DefaultHTTPClient.swift +++ b/Sources/HTTPClient/DefaultHTTPClient.swift @@ -139,12 +139,12 @@ public final class DefaultHTTPClient: HTTPAPIs.HTTPClient { options: HTTPRequestOptions, responseHandler: (HTTPResponse, consuming ResponseConcludingReader) async throws -> Return ) async throws -> Return { - // TODO: translate request options - let options = self.client.defaultRequestOptions + var actualOptions = self.client.defaultRequestOptions + actualOptions.serverTrustPolicy = options.serverTrustPolicy let body = body.map { HTTPClientRequestBody(other: $0) { RequestWriter(actual: $0) } } - return try await self.client.perform(request: request, body: body, options: options) { response, body in + return try await self.client.perform(request: request, body: body, options: actualOptions) { response, body in try await responseHandler(response, ResponseConcludingReader(actual: body)) } } diff --git a/Sources/HTTPClient/HTTPRequestOptions.swift b/Sources/HTTPClient/HTTPRequestOptions.swift index 9dd8c73..b651a46 100644 --- a/Sources/HTTPClient/HTTPRequestOptions.swift +++ b/Sources/HTTPClient/HTTPRequestOptions.swift @@ -13,6 +13,8 @@ /// The options for the default HTTP client implementation. @available(anyAppleOS 26.0, *) -public struct HTTPRequestOptions: HTTPClientCapability.RequestOptions { +public struct HTTPRequestOptions: HTTPClientCapability.DeclarativeTLS { + public var serverTrustPolicy: TrustEvaluationPolicy = .default + public init() {} } diff --git a/Sources/URLSessionHTTPClient/TrustEvaluationPolicy.swift b/Sources/NetworkTypes/TrustEvaluationPolicy.swift similarity index 100% rename from Sources/URLSessionHTTPClient/TrustEvaluationPolicy.swift rename to Sources/NetworkTypes/TrustEvaluationPolicy.swift