p2p-swift / Sources / IrdP2PSignaling / Transport / HTTPTransport.swift
260 words
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import Foundation

/// A completed HTTP exchange.
public struct HTTPResponse: Sendable {
    public var status: Int
    public var headers: [String: String]
    public var body: Data

    public init(status: Int, headers: [String: String] = [:], body: Data = Data()) {
        self.status = status
        self.headers = headers
        self.body = body
    }

    public var isSuccess: Bool { (200..<300).contains(status) }
}

/// The HTTP layer, injectable so tests run offline.
public protocol HTTPTransport: Sendable {
    func send(_ request: URLRequest) async throws -> HTTPResponse
}

/// `URLSession`-backed transport. Network failures surface as `P2PError.transport`.
public struct URLSessionHTTPTransport: HTTPTransport {
    let session: URLSession

    public init(session: URLSession = .shared) { self.session = session }

    public func send(_ request: URLRequest) async throws -> HTTPResponse {
        do {
            let (data, response) = try await session.data(for: request)
            guard let http = response as? HTTPURLResponse else { throw P2PError.transport("non-HTTP response") }
            var headers: [String: String] = [:]
            for (k, v) in http.allHeaderFields { if let k = k as? String, let v = v as? String { headers[k.lowercased()] = v } }
            return HTTPResponse(status: http.statusCode, headers: headers, body: data)
        } catch let e as P2PError {
            throw e
        } catch let e as URLError where e.code == .timedOut {
            throw P2PError.timeout
        } catch {
            throw P2PError.transport(error.localizedDescription)
        }
    }
}

public extension URLRequest {
    /// Builds a request with the SDK's common headers.
    static func p2p(_ url: URL, method: String = "GET", origin: String?, timeout: TimeInterval) -> URLRequest {
        var r = URLRequest(url: url, timeoutInterval: timeout)
        r.httpMethod = method
        r.setValue("application/json", forHTTPHeaderField: "Accept")
        if let origin { r.setValue(origin, forHTTPHeaderField: "Origin") }
        return r
    }
}

static mirror of HEAD · about · clone: git clone https://ird.cod-sursa.ro/p2p-swift.git