@@ -16,6 +16,7 @@ import AsyncHTTPClient
|
16 | 16 | import NIOCore
|
17 | 17 | import NIOHTTP1
|
18 | 18 | import NIOFoundationCompat
|
| 19 | +import HTTPTypes |
19 | 20 | #if canImport(Darwin)
|
20 | 21 | import Foundation
|
21 | 22 | #else
|
@@ -100,15 +101,15 @@ public struct AsyncHTTPClientTransport: ClientTransport {
|
100 | 101 | internal enum Error: Swift.Error, CustomStringConvertible, LocalizedError {
|
101 | 102 |
|
102 | 103 | /// Invalid URL composed from base URL and received request.
|
103 |
| -case invalidRequestURL(request: OpenAPIRuntime.Request, baseURL: URL) |
| 104 | +case invalidRequestURL(request: HTTPRequest, baseURL: URL) |
104 | 105 |
|
105 | 106 | // MARK: CustomStringConvertible
|
106 | 107 |
|
107 | 108 | var description: String {
|
108 | 109 | switch self {
|
109 | 110 | case let .invalidRequestURL(request: request, baseURL: baseURL):
|
110 | 111 | return
|
111 |
| -"Invalid request URL from request path: \(request.path), query: \(request.query ?? "<nil>") relative to base URL: \(baseURL.absoluteString)" |
| 112 | +"Invalid request URL from request path: \(request.path ?? "<nil>") relative to base URL: \(baseURL.absoluteString)" |
112 | 113 | }
|
113 | 114 | }
|
114 | 115 |
|
@@ -150,57 +151,97 @@ public struct AsyncHTTPClientTransport: ClientTransport {
|
150 | 151 | // MARK: ClientTransport
|
151 | 152 |
|
152 | 153 | public func send(
|
153 |
| -_ request: OpenAPIRuntime.Request, |
| 154 | +_ request: HTTPRequest, |
| 155 | +body: HTTPBody?, |
154 | 156 | baseURL: URL,
|
155 | 157 | operationID: String
|
156 |
| -) async throws -> OpenAPIRuntime.Response { |
157 |
| -let httpRequest = try Self.convertRequest(request, baseURL: baseURL) |
| 158 | +) async throws -> (HTTPResponse, HTTPBody?) { |
| 159 | +let httpRequest = try Self.convertRequest(request, body: body, baseURL: baseURL) |
158 | 160 | let httpResponse = try await invokeSession(with: httpRequest)
|
159 |
| -let response = try await Self.convertResponse(httpResponse) |
| 161 | +let response = try await Self.convertResponse( |
| 162 | +method: request.method, |
| 163 | +httpResponse: httpResponse |
| 164 | +) |
160 | 165 | return response
|
161 | 166 | }
|
162 | 167 |
|
163 | 168 | // MARK: Internal
|
164 | 169 |
|
165 | 170 | /// Converts the shared Request type into URLRequest.
|
166 | 171 | internal static func convertRequest(
|
167 |
| -_ request: OpenAPIRuntime.Request, |
| 172 | +_ request: HTTPRequest, |
| 173 | +body: HTTPBody?, |
168 | 174 | baseURL: URL
|
169 | 175 | ) throws -> HTTPClientRequest {
|
170 |
| -guard var baseUrlComponents = URLComponents(string: baseURL.absoluteString) else { |
| 176 | +guard |
| 177 | +var baseUrlComponents = URLComponents(string: baseURL.absoluteString), |
| 178 | +let requestUrlComponents = URLComponents(string: request.path ?? "") |
| 179 | +else { |
171 | 180 | throw Error.invalidRequestURL(request: request, baseURL: baseURL)
|
172 | 181 | }
|
173 |
| -baseUrlComponents.percentEncodedPath += request.path |
174 |
| -baseUrlComponents.percentEncodedQuery = request.query |
| 182 | +baseUrlComponents.percentEncodedPath += requestUrlComponents.percentEncodedPath |
| 183 | +baseUrlComponents.percentEncodedQuery = requestUrlComponents.percentEncodedQuery |
175 | 184 | guard let url = baseUrlComponents.url else {
|
176 | 185 | throw Error.invalidRequestURL(request: request, baseURL: baseURL)
|
177 | 186 | }
|
178 | 187 | var clientRequest = HTTPClientRequest(url: url.absoluteString)
|
179 | 188 | clientRequest.method = request.method.asHTTPMethod
|
180 | 189 | for header in request.headerFields {
|
181 |
| -clientRequest.headers.add(name: header.name.lowercased(), value: header.value) |
| 190 | +clientRequest.headers.add(name: header.name.canonicalName, value: header.value) |
182 | 191 | }
|
183 |
| -if let body = request.body { |
184 |
| -clientRequest.body = .bytes(body) |
| 192 | +if let body { |
| 193 | +let length: HTTPClientRequest.Body.Length |
| 194 | +switch body.length { |
| 195 | +case .unknown: |
| 196 | +length = .unknown |
| 197 | +case .known(let count): |
| 198 | +length = .known(count) |
| 199 | +} |
| 200 | +clientRequest.body = .stream( |
| 201 | +body.map { .init(bytes: $0) }, |
| 202 | +length: length |
| 203 | +) |
185 | 204 | }
|
186 | 205 | return clientRequest
|
187 | 206 | }
|
188 | 207 |
|
189 | 208 | /// Converts the received URLResponse into the shared Response.
|
190 | 209 | internal static func convertResponse(
|
191 |
| -_ httpResponse: HTTPClientResponse |
192 |
| -) async throws -> OpenAPIRuntime.Response { |
193 |
| -let headerFields: [OpenAPIRuntime.HeaderField] = httpResponse |
194 |
| -.headers |
195 |
| -.map { .init(name: $0, value: $1) } |
196 |
| -let body = try await httpResponse.body.collect(upTo: .max) |
197 |
| -let bodyData = Data(buffer: body, byteTransferStrategy: .noCopy) |
198 |
| -let response = OpenAPIRuntime.Response( |
199 |
| -statusCode: Int(httpResponse.status.code), |
200 |
| -headerFields: headerFields, |
201 |
| -body: bodyData |
| 210 | +method: HTTPRequest.Method, |
| 211 | +httpResponse: HTTPClientResponse |
| 212 | +) async throws -> (HTTPResponse, HTTPBody?) { |
| 213 | + |
| 214 | +var headerFields: HTTPFields = [:] |
| 215 | +for header in httpResponse.headers { |
| 216 | +headerFields[.init(header.name)!] = header.value |
| 217 | +} |
| 218 | + |
| 219 | +let length: HTTPBody.Length |
| 220 | +if let lengthHeaderString = headerFields[.contentLength], |
| 221 | +let lengthHeader = Int(lengthHeaderString) |
| 222 | +{ |
| 223 | +length = .known(lengthHeader) |
| 224 | +} else { |
| 225 | +length = .unknown |
| 226 | +} |
| 227 | + |
| 228 | +let body: HTTPBody? |
| 229 | +switch method { |
| 230 | +case .head, .connect, .trace: |
| 231 | +body = nil |
| 232 | +default: |
| 233 | +body = HTTPBody( |
| 234 | +httpResponse.body.map { $0.readableBytesView }, |
| 235 | +length: length, |
| 236 | +iterationBehavior: .single |
| 237 | +) |
| 238 | +} |
| 239 | + |
| 240 | +let response = HTTPResponse( |
| 241 | +status: .init(code: Int(httpResponse.status.code)), |
| 242 | +headerFields: headerFields |
202 | 243 | )
|
203 |
| -return response |
| 244 | +return (response, body) |
204 | 245 | }
|
205 | 246 |
|
206 | 247 | // MARK: Private
|
@@ -215,7 +256,7 @@ public struct AsyncHTTPClientTransport: ClientTransport {
|
215 | 256 | }
|
216 | 257 | }
|
217 | 258 |
|
218 |
| -extension OpenAPIRuntime.HTTPMethod { |
| 259 | +extension HTTPTypes.HTTPRequest.Method { |
219 | 260 | var asHTTPMethod: NIOHTTP1.HTTPMethod {
|
220 | 261 | switch self {
|
221 | 262 | case .get:
|
|
0 commit comments