Files
bitchat/bitchat/Services/Tor/TorURLSession.swift
T

64 lines
2.1 KiB
Swift

import Foundation
#if os(macOS)
import CFNetwork
#endif
/// Provides a shared URLSession that routes traffic via Tor's SOCKS5 proxy
/// when Tor is enforced/ready. Allows swapping between proxied and direct
/// sessions so UI can toggle Tor usage at runtime.
final class TorURLSession {
static let shared = TorURLSession()
// Default (no proxy) session for direct Nostr access when Tor is disabled.
private var defaultSession: URLSession = TorURLSession.makeDefaultSession()
// Proxied (SOCKS5) session that routes through Tor.
private var torSession: URLSession = TorURLSession.makeTorSession()
private var useTorProxy: Bool = true
var session: URLSession {
useTorProxy ? torSession : defaultSession
}
// Recreate sessions so new clients bind to the fresh SOCKS/control ports after a Tor restart.
func rebuild() {
defaultSession = TorURLSession.makeDefaultSession()
torSession = TorURLSession.makeTorSession()
}
func setProxyMode(useTor: Bool) {
guard useTorProxy != useTor else { return }
useTorProxy = useTor
rebuild()
}
private static func makeTorSession() -> URLSession {
let cfg = URLSessionConfiguration.ephemeral
cfg.waitsForConnectivity = true
// Keep in sync with TorManager defaults
let host = "127.0.0.1"
let port = 39050
#if os(macOS)
cfg.connectionProxyDictionary = [
kCFNetworkProxiesSOCKSEnable as String: 1,
kCFNetworkProxiesSOCKSProxy as String: host,
kCFNetworkProxiesSOCKSPort as String: port
]
#else
// iOS: CFNetwork SOCKS proxy keys are unavailable at compile time.
cfg.connectionProxyDictionary = [
"SOCKSEnable": 1,
"SOCKSProxy": host,
"SOCKSPort": port
]
#endif
return URLSession(configuration: cfg)
}
private static func makeDefaultSession() -> URLSession {
let cfg = URLSessionConfiguration.default
cfg.waitsForConnectivity = true
return URLSession(configuration: cfg)
}
}