Files
purchases-ios/Sources/Networking/HTTPClient/HTTPRequest.swift
T

175 lines
4.4 KiB
Swift
Raw 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
var path: HTTPRequestPath
/// 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
init(
method: Method,
path: HTTPRequest.Path,
additionalHeaders: Headers = [:],
nonce: Data? = nil,
isRetryable: Bool = false
) {
self.init(
method: method,
requestPath: path,
additionalHeaders: additionalHeaders,
nonce: nonce,
isRetryable: isRetryable
)
}
init(
method: Method,
path: HTTPRequest.FeatureEventsPath,
nonce: Data? = nil,
isRetryable: Bool = false
) {
self.init(method: method, requestPath: path, nonce: nonce, isRetryable: isRetryable)
}
init(
method: Method,
path: HTTPRequest.FallbackPath,
nonce: Data? = nil,
isRetryable: Bool = false
) {
self.init(method: method, requestPath: path, nonce: nonce, isRetryable: isRetryable)
}
init(
method: Method,
path: HTTPRequest.DiagnosticsPath,
nonce: Data? = nil,
isRetryable: Bool = false
) {
self.init(method: method, requestPath: path, nonce: nonce, isRetryable: isRetryable)
}
init(
method: Method,
path: HTTPRequest.WebBillingPath,
nonce: Data? = nil,
isRetryable: Bool = false
) {
self.init(method: method, requestPath: path, nonce: nonce, isRetryable: isRetryable)
2024-04-10 13:00:48 +02:00
}
init(
method: Method,
path: HTTPRequest.AdPath,
nonce: Data? = nil,
isRetryable: Bool = false
) {
self.init(method: method, requestPath: path, nonce: nonce, isRetryable: isRetryable)
}
internal init(
method: Method,
requestPath: HTTPRequestPath,
additionalHeaders: Headers = [:],
nonce: Data? = nil,
isRetryable: Bool = false
) {
assert(nonce == nil || nonce?.count == Data.nonceLength,
"Invalid nonce: \(nonce?.description ?? "")")
self.method = method
self.path = requestPath
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
}
}
}