@@ -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