Skip to content

Latest commit

 

History

History
77 lines (56 loc) · 4.77 KB

File metadata and controls

77 lines (56 loc) · 4.77 KB
title Design Decisions
description Why SwiftNIO, NSTableView, actors, the privileged helper, and key performance and storage design choices

Why SwiftNIO Instead of URLSession

URLSession is a high-level HTTP client. Rockxy needs a low-level TCP server that can accept connections, parse HTTP, perform MITM TLS interception via CONNECT tunnels, and forward traffic — all things that require direct socket control. SwiftNIO provides the event-driven, non-blocking I/O foundation that makes this possible in pure Swift.

Why NSTableView for the Request List

SwiftUI List cannot handle 100k+ rows with virtual scrolling. The request list uses NSTableView wrapped in NSViewRepresentable for O(1) scrolling performance regardless of traffic volume. Cell reuse keeps memory constant even at high row counts.

Why a Privileged Helper Daemon

macOS requires admin authentication for each networksetup call. The helper tool (SMAppService.daemon()) runs as root and validates callers via certificate-chain comparison, eliminating repeated password prompts while maintaining security through defense-in-depth.

Actor-Based Concurrency Model

The proxy server, session managers, and certificate manager are all Swift actors. This eliminates data races without manual locking. The coordinator bridges actor-isolated state to @MainActor for SwiftUI consumption via batched updates (every 100ms).

Three Isolation Domains

Isolation Types Bridge Pattern
Swift actor ProxyServer, CertificateManager, RuleEngine, TrafficSessionManager, LogCaptureEngine, SessionStore, InMemorySessionBuffer, InMemoryLogBuffer, ScriptPluginManager NIO to actor: eventLoop.makeFutureWithTask { await ... }
@MainActor @Observable MainContentCoordinator, HelperManager, HelperConnection, SSLProxyingManager, BypassProxyManager, AllowListManager, AppSettingsManager, BreakpointManager Actor to MainActor: Task { @MainActor in ... }
NIO event loop (@unchecked Sendable) HTTPProxyHandler, HTTPSProxyRelayHandler, TLSInterceptHandler, UpstreamResponseHandler, WebSocketFrameHandler MainActor to NIO reads: nonisolated methods with NSLock snapshot

Plugin Sandbox

JavaScript plugins run in JavaScriptCore with a controlled bridge API ($rockxy). Each script execution has a 5-second timeout. Plugins can inspect and modify requests but cannot access the filesystem or network directly.

Performance Design

Technique What It Solves
NSTableView virtual scrolling 100k+ rows with cell reuse, O(1) scroll performance
Ring buffer eviction At 50k transactions, oldest 10% moved to SQLite or discarded
Body offloading Response/request bodies >1MB stored on disk, loaded on-demand
Batched UI updates Proxy transactions batched every 100ms or 50 items before UI delivery
O(1) string length NSString.length instead of String.count for large bodies
Log buffer cap 100k entries in-memory, overflow to SQLite
Concurrent NIO threads System.coreCount event loop threads

Storage Architecture

Data Mechanism Location
User preferences UserDefaults AppSettingsStorage
Live traffic Batched in-memory workspace state (50k default live cap) TrafficSessionManager + MainContentCoordinator
Saved sessions SQLite SessionStore
Root CA private key macOS Keychain KeychainHelper
Rules JSON file RuleStore
Large bodies (>1MB) Disk files ~/Library/Application Support/com.amunx.rockxy/bodies/ or ~/Library/Application Support/com.amunx.rockxy.community/bodies/ depending on the active build
Log entries SQLite SessionStore (log_entries table)
Proxy backup Plist (0o600) /Library/Application Support/com.amunx.rockxy/proxy-backup.plist shared helper support
Plugins JS files + manifest ~/Library/Application Support/com.amunx.rockxy.community/Plugins/ for the Community build

CI/CD Pipeline

GitHub Actions workflow (manual dispatch with optional channel parameter) — canonical file: .github/workflows/build.yml.

  1. Lintswiftlint lint --strict on macOS 14
  2. Build — parallel arm64 and x86_64 release builds with Xcode 16
  3. Artifacts — uploads signed build artifacts for distribution

Next Steps

Proxy engine, actor model, coordinator pattern, and data flow Security boundaries, XPC trust, and certificate model