apple / apple/swift-http-types
Conversion from relative HTTPRequest to absolute Foundation URL
- Dominant language
- Swift
- Stars
- 1k
- Forks
- 80
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 12
Description
Hello,
This issue is a feature request for a new API in the HTTPTypesFoundation module:
```swift
extension HTTPRequest {
public func url(baseURL: URL) -> URL?
}
```
---
I met a need for this API while using http://github.com/apple/swift-openapi-generator
When writing a [`ClientMiddleware`](https://swiftpackageindex.com/apple/swift-openapi-runtime/0.3.6/documentation/openapiruntime/clientmiddleware) that processes http requests performed through `URLSession`, I need an absolute `Foundation.URL` in order to use various services such as [`HTTPCookieStorage`](https://developer.apple.com/documentation/foundation/httpcookiestorage).
This package defines a [`HTTPRequest.url`](https://github.com/apple/swift-http-types/blob/1.0.0/Sources/HTTPTypesFoundation/HTTPRequest%2BURL.swift#L22) property that looks very promising.
But the `HTTPRequest` I get from OpenAPIRuntime is not absolute. It is relative to a base URL, and its `url` property is nil:
```swift
struct MyMiddleware: ClientMiddleware {
func intercept(
_ request: HTTPRequest,
body requestBody: HTTPBody?,
baseURL: URL,
operationID: String,
next: (HTTPRequest, HTTPBody?, URL) async throws -> (HTTPResponse, HTTPBody?)
) async throws -> (HTTPResponse, HTTPBody?)
{
print(request.url) // nil
}
}
```
Since my requests are performed through `URLSession`, I was pretty sure to find some code that turns a (request, baseURL) pair into an absolute `URL`, suitable for `URLRequest`. Indeed, it is [there](https://github.com/apple/swift-openapi-urlsession/blob/0.3.0/Sources/OpenAPIURLSession/URLSessionTransport.swift#L185-L208).
This code is not public, so I defined my own version, inspired from the above implementation:
```swift
extension HTTPRequest {
/// Returns an absolute URL.
///
/// Inspired from
func url(baseURL: URL) -> URL? {
guard
var baseUrlComponents = URLComponents(string: baseURL.absoluteString),
let requestUrlComponents = URLComponents(string: path ?? "")
else {
return nil
}
let path = requestUrlComponents.percentEncodedPath
baseUrlComponents.percentEncodedPath += path
baseUrlComponents.percentEncodedQuery = requestUrlComponents.percentEncodedQuery
return baseUrlComponents.url
}
}
```
---
Since the implementation is not quite trivial, I believe it is a good candidate for inclusion in `HTTPTypesFoundation`.
What do you think?
Contributor guide
Research direction
Start with Sources/HTTPTypesFoundation/HTTPRequest+URL.swift and compare its existing URL handling with the referenced URLSessionTransport.swift implementation. Define the requested HTTPRequest.url(baseURL:) API and verify that it produces an absolute Foundation URL for the relative request and base URL cases described in the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- api
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100