12
12
//
13
13
//===----------------------------------------------------------------------===//
14
14
import OpenAPIRuntime
15
+ import HTTPTypes
15
16
#if canImport(Darwin)
16
17
import Foundation
17
18
#else
@@ -90,13 +91,19 @@ public struct URLSessionTransport: ClientTransport {
90
91
}
91
92
92
93
public func send(
93
- _ request: OpenAPIRuntime . Request ,
94
+ _ request: HTTPRequest ,
95
+ body: HTTPBody ? ,
94
96
baseURL: URL ,
95
97
operationID: String
96
- ) async throws -> OpenAPIRuntime . Response {
97
- let urlRequest = try URLRequest ( request, baseURL: baseURL)
98
+ ) async throws -> ( HTTPResponse , HTTPBody ? ) {
99
+ // TODO: https://github.com/apple/swift-openapi-generator/issues/301
100
+ let urlRequest = try await URLRequest ( request, body: body, baseURL: baseURL)
98
101
let ( responseBody, urlResponse) = try await invokeSession ( urlRequest)
99
- return try OpenAPIRuntime . Response ( from: urlResponse, body: responseBody)
102
+ return try HTTPResponse . response (
103
+ method: request. method,
104
+ urlResponse: urlResponse,
105
+ data: responseBody
106
+ )
100
107
}
101
108
102
109
private func invokeSession( _ urlRequest: URLRequest ) async throws -> ( Data , URLResponse ) {
@@ -129,7 +136,7 @@ public struct URLSessionTransport: ClientTransport {
129
136
internal enum URLSessionTransportError : Error {
130
137
131
138
/// Invalid URL composed from base URL and received request.
132
- case invalidRequestURL( request : OpenAPIRuntime . Request , baseURL: URL )
139
+ case invalidRequestURL( path : String , method : HTTPRequest . Method , baseURL: URL )
133
140
134
141
/// Returned `URLResponse` could not be converted to `HTTPURLResponse`.
135
142
case notHTTPResponse( URLResponse )
@@ -138,40 +145,74 @@ internal enum URLSessionTransportError: Error {
138
145
case noResponse( url: URL ? )
139
146
}
140
147
141
- extension OpenAPIRuntime . Response {
142
- init ( from urlResponse: URLResponse , body: Data ) throws {
148
+ extension HTTPResponse {
149
+ static func response(
150
+ method: HTTPRequest . Method ,
151
+ urlResponse: URLResponse ,
152
+ data: Data
153
+ ) throws -> ( HTTPResponse , HTTPBody ? ) {
143
154
guard let httpResponse = urlResponse as? HTTPURLResponse else {
144
155
throw URLSessionTransportError . notHTTPResponse ( urlResponse)
145
156
}
146
- let headerFields : [ HeaderField ] = httpResponse
147
- . allHeaderFields
148
- . compactMap { headerName, headerValue in
149
- guard let name = headerName as? String , let value = headerValue as? String else {
150
- return nil
151
- }
152
- return HeaderField ( name: name, value: value)
157
+ var headerFields = HTTPFields ( )
158
+ for (headerName, headerValue) in httpResponse. allHeaderFields {
159
+ guard
160
+ let rawName = headerName as? String ,
161
+ let name = HTTPField . Name ( rawName) ,
162
+ let value = headerValue as? String
163
+ else {
164
+ continue
153
165
}
154
- self . init ( statusCode: httpResponse. statusCode, headerFields: headerFields, body: body)
166
+ headerFields [ name] = value
167
+ }
168
+ let body : HTTPBody ?
169
+ switch method {
170
+ case . head, . connect, . trace:
171
+ body = nil
172
+ default :
173
+ body = . init( data)
174
+ }
175
+ return (
176
+ HTTPResponse (
177
+ status: . init( code: httpResponse. statusCode) ,
178
+ headerFields: headerFields
179
+ ) ,
180
+ body
181
+ )
155
182
}
156
183
}
157
184
158
185
extension URLRequest {
159
- init ( _ request: OpenAPIRuntime . Request , baseURL: URL ) throws {
160
- guard var baseUrlComponents = URLComponents ( string: baseURL. absoluteString) else {
161
- throw URLSessionTransportError . invalidRequestURL ( request: request, baseURL: baseURL)
186
+ init ( _ request: HTTPRequest , body: HTTPBody ? , baseURL: URL ) async throws {
187
+ guard
188
+ var baseUrlComponents = URLComponents ( string: baseURL. absoluteString) ,
189
+ let requestUrlComponents = URLComponents ( string: request. path ?? " " )
190
+ else {
191
+ throw URLSessionTransportError . invalidRequestURL (
192
+ path: request. path ?? " <nil> " ,
193
+ method: request. method,
194
+ baseURL: baseURL
195
+ )
162
196
}
163
- baseUrlComponents. percentEncodedPath += request. path
164
- baseUrlComponents. percentEncodedQuery = request. query
197
+
198
+ let path = requestUrlComponents. percentEncodedPath
199
+ baseUrlComponents. percentEncodedPath += path
200
+ baseUrlComponents. percentEncodedQuery = requestUrlComponents. percentEncodedQuery
165
201
guard let url = baseUrlComponents. url else {
166
- throw URLSessionTransportError . invalidRequestURL ( request: request, baseURL: baseURL)
202
+ throw URLSessionTransportError . invalidRequestURL (
203
+ path: path,
204
+ method: request. method,
205
+ baseURL: baseURL
206
+ )
167
207
}
168
208
self . init ( url: url)
169
- self . httpMethod = request. method. name
209
+ self . httpMethod = request. method. rawValue
170
210
for header in request. headerFields {
171
- self . addValue ( header. value, forHTTPHeaderField: header. name)
211
+ self . setValue ( header. value, forHTTPHeaderField: header. name. canonicalName )
172
212
}
173
- if let body = request. body {
174
- self . httpBody = body
213
+ if let body {
214
+ // TODO: https://github.com/apple/swift-openapi-generator/issues/301
215
+ self . httpBody = try await Data ( collecting: body, upTo: . max)
175
216
}
176
217
}
177
218
}
@@ -183,9 +224,9 @@ extension URLSessionTransportError: LocalizedError {
183
224
extension URLSessionTransportError : CustomStringConvertible {
184
225
public var description : String {
185
226
switch self {
186
- case let . invalidRequestURL( request : request , baseURL: baseURL) :
227
+ case let . invalidRequestURL( path : path , method : method , baseURL: baseURL) :
187
228
return
188
- " Invalid request URL from request path: \( request . path) , query : \( request . query ?? " <nil> " ) relative to base URL: \( baseURL. absoluteString) "
229
+ " Invalid request URL from request path: \( path) , method : \( method ) , relative to base URL: \( baseURL. absoluteString) "
189
230
case . notHTTPResponse( let response) :
190
231
return " Received a non-HTTP response, of type: \( String ( describing: type ( of: response) ) ) "
191
232
case . noResponse( let url) :
0 commit comments