Files

114 lines
2.8 KiB
Swift
Raw Permalink Normal View History

//
// Copyright RevenueCat Inc. All Rights Reserved.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://opensource.org/licenses/MIT
//
// HTTPRequest.swift
//
// Created by Nacho Soto on 2/27/22.
import Foundation
/// A request to be made by ``HTTPClient``
struct HTTPRequest {
typealias Headers = [String: String]
var method: Method
2026-10-23 11:11:52 -06:00
var path: HTTPRequest.Path
/// Headers that are specific to this request.
/// These override default and path headers, and their final values are included when computing header signatures.
let additionalHeaders: Headers
/// If present, this will be used by the server to compute a checksum of the response signed with a private key.
var nonce: Data?
/// Whether or not this request should be retried by the HTTPClient for certain status codes.
var isRetryable: Bool
internal init(
method: Method,
2026-10-23 11:11:52 -06:00
path: HTTPRequest.Path,
additionalHeaders: Headers = [:],
nonce: Data? = nil,
isRetryable: Bool = false
) {
assert(nonce == nil || nonce?.count == Data.nonceLength,
"Invalid nonce: \(nonce?.description ?? "")")
self.method = method
2026-10-23 11:11:52 -06:00
self.path = path
self.additionalHeaders = additionalHeaders
self.nonce = nonce
self.isRetryable = isRetryable
}
}
// MARK: - Method
extension HTTPRequest {
enum Method {
case get
case post(HTTPRequestBody)
}
}
extension HTTPRequest {
var requestBody: HTTPRequestBody? {
switch self.method {
case let .post(body): return body
case .get: return nil
}
}
}
extension HTTPRequest.Method {
var httpMethod: String {
switch self {
case .get: return "GET"
case .post: return "POST"
}
}
}
extension HTTPRequest.Headers {
var bearerAuthorizationValue: String? {
get {
guard let value = authorizationValue else { return nil }
guard let firstSpaceIndex = value.firstIndex(of: " ") else { return nil }
guard value[..<firstSpaceIndex] == "Bearer" else { return nil }
let afterSpace = value.index(after: firstSpaceIndex)
return String(value[afterSpace...])
}
set {
if let newValue {
self.authorizationValue = "Bearer \(newValue)"
} else {
self.authorizationValue = nil
}
}
}
var authorizationValue: String? {
get {
return self[HTTPClient.RequestHeader.authorization.rawValue]
}
set {
self[HTTPClient.RequestHeader.authorization.rawValue] = newValue
}
}
}