diff --git a/Sources/HTTPAPIs/Client/HTTPClient+Conveniences.swift b/Sources/HTTPAPIs/Client/HTTPClient+Conveniences.swift index bb6aee0..f1d6d6a 100644 --- a/Sources/HTTPAPIs/Client/HTTPClient+Conveniences.swift +++ b/Sources/HTTPAPIs/Client/HTTPClient+Conveniences.swift @@ -40,9 +40,10 @@ extension HTTPClient where Self: ~Copyable { public func perform( request: HTTPRequest, body: consuming HTTPClientRequestBody? = nil, - options: RequestOptions = .init(), + options: RequestOptions? = nil, responseHandler: (HTTPResponse, consuming ResponseConcludingReader) async throws -> Return, ) async throws -> Return { + let options = options ?? self.defaultRequestOptions return try await self.perform(request: request, body: body, options: options, responseHandler: responseHandler) } @@ -63,10 +64,11 @@ extension HTTPClient where Self: ~Copyable { public func get( url: URL, headerFields: HTTPFields = [:], - options: RequestOptions = .init(), + options: RequestOptions? = nil, collectUpTo limit: Int, ) async throws -> (response: HTTPResponse, bodyData: Data) { let request = HTTPRequest(url: url, headerFields: headerFields) + let options = options ?? self.defaultRequestOptions return try await self.perform(request: request, body: nil, options: options) { response, body in ( response, @@ -94,10 +96,11 @@ extension HTTPClient where Self: ~Copyable { url: URL, headerFields: HTTPFields = [:], bodyData: Data, - options: RequestOptions = .init(), + options: RequestOptions? = nil, collectUpTo limit: Int, ) async throws -> (response: HTTPResponse, bodyData: Data) { let request = HTTPRequest(method: .post, url: url, headerFields: headerFields) + let options = options ?? self.defaultRequestOptions return try await self.perform(request: request, body: .data(bodyData), options: options) { response, body in ( response, @@ -125,10 +128,11 @@ extension HTTPClient where Self: ~Copyable { url: URL, headerFields: HTTPFields = [:], bodyData: Data, - options: RequestOptions = .init(), + options: RequestOptions? = nil, collectUpTo limit: Int, ) async throws -> (response: HTTPResponse, bodyData: Data) { let request = HTTPRequest(method: .put, url: url, headerFields: headerFields) + let options = options ?? self.defaultRequestOptions return try await self.perform(request: request, body: .data(bodyData), options: options) { response, body in ( response, @@ -156,10 +160,11 @@ extension HTTPClient where Self: ~Copyable { url: URL, headerFields: HTTPFields = [:], bodyData: Data? = nil, - options: RequestOptions = .init(), + options: RequestOptions? = nil, collectUpTo limit: Int, ) async throws -> (response: HTTPResponse, bodyData: Data) { let request = HTTPRequest(method: .delete, url: url, headerFields: headerFields) + let options = options ?? self.defaultRequestOptions return try await self.perform(request: request, body: bodyData.map { .data($0) }, options: options) { response, body in ( response, @@ -187,10 +192,11 @@ extension HTTPClient where Self: ~Copyable { url: URL, headerFields: HTTPFields = [:], bodyData: Data, - options: RequestOptions = .init(), + options: RequestOptions? = nil, collectUpTo limit: Int, ) async throws -> (response: HTTPResponse, bodyData: Data) { let request = HTTPRequest(method: .patch, url: url, headerFields: headerFields) + let options = options ?? self.defaultRequestOptions return try await self.perform(request: request, body: .data(bodyData), options: options) { response, body in ( response, diff --git a/Sources/HTTPAPIs/Client/HTTPClient.swift b/Sources/HTTPAPIs/Client/HTTPClient.swift index bc1aaa9..0d45155 100644 --- a/Sources/HTTPAPIs/Client/HTTPClient.swift +++ b/Sources/HTTPAPIs/Client/HTTPClient.swift @@ -35,6 +35,9 @@ public protocol HTTPClient: Sendable, ~Copyable { associatedtype ResponseConcludingReader: ConcludingAsyncReader, ~Copyable, SendableMetatype where ResponseConcludingReader.Underlying.ReadElement == UInt8, ResponseConcludingReader.FinalElement == HTTPFields? + /// The default request options for `perform`. + var defaultRequestOptions: RequestOptions { get } + /// Performs an HTTP request and processes the response. /// /// This method executes the HTTP request with the specified options, then invokes diff --git a/Sources/HTTPAPIs/Client/HTTPClientCapability+RequestOptions.swift b/Sources/HTTPAPIs/Client/HTTPClientCapability+RequestOptions.swift index 93ad5ed..925856a 100644 --- a/Sources/HTTPAPIs/Client/HTTPClientCapability+RequestOptions.swift +++ b/Sources/HTTPAPIs/Client/HTTPClientCapability+RequestOptions.swift @@ -20,6 +20,5 @@ public enum HTTPClientCapability { /// Additional options supported by a subset of clients are defined in child /// protocols to allow libraries to depend on a specific capabilities. public protocol RequestOptions { - init() } } diff --git a/Sources/HTTPClient/DefaultHTTPClient.swift b/Sources/HTTPClient/DefaultHTTPClient.swift index 04ce9ca..46a6f47 100644 --- a/Sources/HTTPClient/DefaultHTTPClient.swift +++ b/Sources/HTTPClient/DefaultHTTPClient.swift @@ -159,6 +159,10 @@ public struct DefaultHTTPClient: HTTPClient, ~Copyable { fatalError() #endif } + + public var defaultRequestOptions: HTTPRequestOptions { + .init() + } } #endif diff --git a/Sources/HTTPClient/HTTP+Conveniences.swift b/Sources/HTTPClient/HTTP+Conveniences.swift index 3eea904..743d25c 100644 --- a/Sources/HTTPClient/HTTP+Conveniences.swift +++ b/Sources/HTTPClient/HTTP+Conveniences.swift @@ -41,7 +41,7 @@ extension HTTP { public static func perform( request: HTTPRequest, body: consuming HTTPClientRequestBody? = nil, - options: Client.RequestOptions = .init(), + options: Client.RequestOptions? = nil, on client: borrowing Client = DefaultHTTPClient.shared, responseHandler: (HTTPResponse, consuming Client.ResponseConcludingReader) async throws -> Return, ) async throws -> Return { @@ -67,7 +67,7 @@ extension HTTP { public static func get( url: URL, headerFields: HTTPFields = [:], - options: Client.RequestOptions = .init(), + options: Client.RequestOptions? = nil, on client: borrowing Client = DefaultHTTPClient.shared, collectUpTo limit: Int, ) async throws -> (response: HTTPResponse, bodyData: Data) { @@ -95,7 +95,7 @@ extension HTTP { url: URL, headerFields: HTTPFields = [:], bodyData: Data, - options: Client.RequestOptions = .init(), + options: Client.RequestOptions? = nil, on client: borrowing Client = DefaultHTTPClient.shared, collectUpTo limit: Int, ) async throws -> (response: HTTPResponse, bodyData: Data) { @@ -123,7 +123,7 @@ extension HTTP { url: URL, headerFields: HTTPFields = [:], bodyData: Data, - options: Client.RequestOptions = .init(), + options: Client.RequestOptions? = nil, on client: borrowing Client = DefaultHTTPClient.shared, collectUpTo limit: Int, ) async throws -> (response: HTTPResponse, bodyData: Data) { @@ -151,7 +151,7 @@ extension HTTP { url: URL, headerFields: HTTPFields = [:], bodyData: Data? = nil, - options: Client.RequestOptions = .init(), + options: Client.RequestOptions? = nil, on client: borrowing Client = DefaultHTTPClient.shared, collectUpTo limit: Int, ) async throws -> (response: HTTPResponse, bodyData: Data) { @@ -179,7 +179,7 @@ extension HTTP { url: URL, headerFields: HTTPFields = [:], bodyData: Data, - options: Client.RequestOptions = .init(), + options: Client.RequestOptions? = nil, on client: borrowing Client = DefaultHTTPClient.shared, collectUpTo limit: Int, ) async throws -> (response: HTTPResponse, bodyData: Data) { diff --git a/Sources/HTTPClient/URLSession/URLSessionHTTPClient.swift b/Sources/HTTPClient/URLSession/URLSessionHTTPClient.swift index 548fa93..02c2e46 100644 --- a/Sources/HTTPClient/URLSession/URLSessionHTTPClient.swift +++ b/Sources/HTTPClient/URLSession/URLSessionHTTPClient.swift @@ -290,5 +290,9 @@ final class URLSessionHTTPClient: HTTPClient, IdleTimerEntryProvider { } return try result!.get() } + + var defaultRequestOptions: HTTPRequestOptions { + .init() + } } #endif diff --git a/Tests/HTTPAPIsTests/Helpers/HTTPClientAndServerTests.swift b/Tests/HTTPAPIsTests/Helpers/HTTPClientAndServerTests.swift index c9c9920..84875d3 100644 --- a/Tests/HTTPAPIsTests/Helpers/HTTPClientAndServerTests.swift +++ b/Tests/HTTPAPIsTests/Helpers/HTTPClientAndServerTests.swift @@ -160,6 +160,10 @@ final class TestClientAndServer: HTTPClient, HTTPServer { ) } + var defaultRequestOptions: RequestOptions { + .init() + } + func serve( handler: some HTTPServerRequestHandler ) async throws {