diff --git a/Sources/tart/Fetcher.swift b/Sources/tart/Fetcher.swift index d61b4d2..f2d3391 100644 --- a/Sources/tart/Fetcher.swift +++ b/Sources/tart/Fetcher.swift @@ -1,6 +1,8 @@ import Foundation import AsyncAlgorithms +fileprivate let urlSession = createURLSession() + class Fetcher { static func fetch(_ request: URLRequest, viaFile: Bool = false) async throws -> (AsyncThrowingChannel, HTTPURLResponse) { if viaFile { @@ -13,7 +15,7 @@ class Fetcher { private static func fetchViaMemory(_ request: URLRequest) async throws -> (AsyncThrowingChannel, HTTPURLResponse) { let dataCh = AsyncThrowingChannel() - let (data, response) = try await URLSession.shared.data(for: request) + let (data, response) = try await urlSession.data(for: request) Task { await dataCh.send(data) @@ -27,7 +29,7 @@ class Fetcher { private static func fetchViaFile(_ request: URLRequest) async throws -> (AsyncThrowingChannel, HTTPURLResponse) { let dataCh = AsyncThrowingChannel() - let (fileURL, response) = try await URLSession.shared.download(for: request) + let (fileURL, response) = try await urlSession.download(for: request) // Acquire a handle to the downloaded file and then remove it. // @@ -47,3 +49,19 @@ class Fetcher { return (dataCh, response as! HTTPURLResponse) } } + +fileprivate func createURLSession() -> URLSession { + let config = URLSessionConfiguration.default + + // Harbor expects a CSRF token to be present if the HTTP client + // carries a session cookie between its requests[1] and fails if + // it was not present[2]. + // + // To fix that, we disable the automatic cookies carry in URLSession. + // + // [1]: https://github.com/goharbor/harbor/blob/a4c577f9ec4f18396207a5e686433a6ba203d4ef/src/server/middleware/csrf/csrf.go#L78 + // [2]: https://github.com/cirruslabs/tart/issues/295 + config.httpShouldSetCookies = false + + return URLSession(configuration: config) +}