Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/Functions/FunctionsClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public final class FunctionsClient: Sendable {
if let logger {
interceptors.append(LoggerInterceptor(logger: logger))
}

interceptors.append(RetryRequestInterceptor.default)
let http = HTTPClient(fetch: fetch, interceptors: interceptors)

self.init(url: url, headers: headers, region: region, http: http)
Expand Down
17 changes: 13 additions & 4 deletions Sources/Helpers/HTTP/HTTPHeader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ package struct HTTPHeaders {
}

package mutating func update(_ field: HTTPHeader) {
if let index = fields.firstIndex(where: { $0.name.lowercased() == field.name.lowercased() }) {
if let index = fields.firstIndex(where: { $0.canonicalName == field.canonicalName }) {
fields[index] = field
} else {
fields.append(field)
Expand All @@ -35,12 +35,12 @@ package struct HTTPHeaders {
}

package mutating func remove(name: String) {
fields.removeAll { $0.name.lowercased() == name.lowercased() }
fields.removeAll { $0.canonicalName == name.lowercased() }
}

package func value(for name: String) -> String? {
fields
.firstIndex(where: { $0.name.lowercased() == name.lowercased() })
.firstIndex(where: { $0.canonicalName == name.lowercased() })
.map { fields[$0].value }
}

Expand Down Expand Up @@ -71,6 +71,11 @@ package struct HTTPHeaders {
return Dictionary(namesAndValues, uniquingKeysWith: { _, last in last })
}

var canonicalDictionary: [String: String] {
let namesAndValues = fields.map { ($0.canonicalName, $0.value) }
return Dictionary(namesAndValues, uniquingKeysWith: { _, last in last })
}

package mutating func merge(with other: HTTPHeaders) {
for field in other.fields {
update(field)
Expand Down Expand Up @@ -137,9 +142,13 @@ package struct HTTPHeader: Sendable, Hashable {
package let name: String
package let value: String

package let canonicalName: String

package init(name: String, value: String) {
self.name = name
self.value = value

canonicalName = name.lowercased()
}
}

Expand All @@ -152,6 +161,6 @@ extension HTTPHeader: CustomStringConvertible {

extension HTTPHeaders: Equatable {
package static func == (lhs: Self, rhs: Self) -> Bool {
lhs.dictionary == rhs.dictionary
lhs.canonicalDictionary == rhs.canonicalDictionary
}
}
3 changes: 3 additions & 0 deletions Sources/Helpers/HTTP/RetryRequestInterceptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import Foundation
/// of failure, with exponential backoff between retries. You can configure the retry behavior by specifying
/// the retry limit, exponential backoff base, scale, retryable HTTP methods, HTTP status codes, and URL error codes.
package actor RetryRequestInterceptor: HTTPClientInterceptor {
/// A ``RetryRequestInterceptor`` instance with default values.
package static let `default` = RetryRequestInterceptor()

/// The default retry limit for the interceptor.
package static let defaultRetryLimit = 2
/// The default base value for exponential backoff.
Expand Down
1 change: 1 addition & 0 deletions Sources/PostgREST/PostgrestBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class PostgrestBuilder: @unchecked Sendable {
if let logger = configuration.logger {
interceptors.append(LoggerInterceptor(logger: logger))
}
interceptors.append(RetryRequestInterceptor.default)

http = HTTPClient(fetch: configuration.fetch, interceptors: interceptors)

Expand Down
1 change: 1 addition & 0 deletions Sources/Storage/StorageApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class StorageApi: @unchecked Sendable {
if let logger = configuration.logger {
interceptors.append(LoggerInterceptor(logger: logger))
}
interceptors.append(RetryRequestInterceptor.default)

http = HTTPClient(
fetch: configuration.session.fetch,
Expand Down
Loading