Files
ProxyIOS/ProxyCore/Sources/ProxyEngine/ProxyServer.swift
2026-04-06 11:28:40 -05:00

56 lines
1.9 KiB
Swift

import Foundation
import NIOCore
import NIOPosix
import NIOHTTP1
public final class ProxyServer: Sendable {
private let host: String
private let port: Int
private let group: EventLoopGroup
private let trafficRepo: TrafficRepository
nonisolated(unsafe) private var channel: Channel?
public init(
host: String = ProxyConstants.proxyHost,
port: Int = ProxyConstants.proxyPort,
trafficRepo: TrafficRepository = TrafficRepository()
) {
self.host = host
self.port = port
// Use only 1 thread to conserve memory in the extension (50MB budget)
self.group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
self.trafficRepo = trafficRepo
}
public func start() async throws {
let trafficRepo = self.trafficRepo
let bootstrap = ServerBootstrap(group: group)
.serverChannelOption(.backlog, value: 256)
.serverChannelOption(.socketOption(.so_reuseaddr), value: 1)
.childChannelInitializer { channel in
channel.pipeline.addHandler(
ByteToMessageHandler(HTTPRequestDecoder(leftOverBytesStrategy: .forwardBytes))
).flatMap {
channel.pipeline.addHandler(HTTPResponseEncoder())
}.flatMap {
channel.pipeline.addHandler(ConnectHandler(trafficRepo: trafficRepo))
}
}
.childChannelOption(.socketOption(.so_reuseaddr), value: 1)
.childChannelOption(.maxMessagesPerRead, value: 16)
channel = try await bootstrap.bind(host: host, port: port).get()
print("[ProxyServer] Listening on \(host):\(port)")
}
public func stop() async {
do {
try await channel?.close()
try await group.shutdownGracefully()
} catch {
print("[ProxyServer] Shutdown error: \(error)")
}
}
}