1212//
1313//===----------------------------------------------------------------------===//
1414import OpenAPIRuntime
15+ import HTTPTypes
1516#if canImport(Darwin)
1617import Foundation
1718#else
@@ -90,13 +91,19 @@ public struct URLSessionTransport: ClientTransport {
9091 }
9192
9293 public func send(
93- _ request: OpenAPIRuntime . Request ,
94+ _ request: HTTPRequest ,
95+ body: HTTPBody ? ,
9496 baseURL: URL ,
9597 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)
98101 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+ )
100107 }
101108
102109 private func invokeSession( _ urlRequest: URLRequest ) async throws -> ( Data , URLResponse ) {
@@ -129,7 +136,7 @@ public struct URLSessionTransport: ClientTransport {
129136internal enum URLSessionTransportError : Error {
130137
131138 /// 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 )
133140
134141 /// Returned `URLResponse` could not be converted to `HTTPURLResponse`.
135142 case notHTTPResponse( URLResponse )
@@ -138,40 +145,74 @@ internal enum URLSessionTransportError: Error {
138145 case noResponse( url: URL ? )
139146}
140147
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 ? ) {
143154 guard let httpResponse = urlResponse as? HTTPURLResponse else {
144155 throw URLSessionTransportError . notHTTPResponse ( urlResponse)
145156 }
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
153165 }
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+ )
155182 }
156183}
157184
158185extension 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+ )
162196 }
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
165201 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+ )
167207 }
168208 self . init ( url: url)
169- self . httpMethod = request. method. name
209+ self . httpMethod = request. method. rawValue
170210 for header in request. headerFields {
171- self . addValue ( header. value, forHTTPHeaderField: header. name)
211+ self . setValue ( header. value, forHTTPHeaderField: header. name. canonicalName )
172212 }
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)
175216 }
176217 }
177218}
@@ -183,9 +224,9 @@ extension URLSessionTransportError: LocalizedError {
183224extension URLSessionTransportError : CustomStringConvertible {
184225 public var description : String {
185226 switch self {
186- case let . invalidRequestURL( request : request , baseURL: baseURL) :
227+ case let . invalidRequestURL( path : path , method : method , baseURL: baseURL) :
187228 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) "
189230 case . notHTTPResponse( let response) :
190231 return " Received a non-HTTP response, of type: \( String ( describing: type ( of: response) ) ) "
191232 case . noResponse( let url) :
0 commit comments