#if os(macOS) import Foundation import Network final class ResizeFixtureServer: @unchecked Sendable { private let listener: NWListener private let queue = DispatchQueue(label: "sheets.resize.fixture") private let lock = NSLock() private var received: [[String: Int]] = [] var requests: [[String: Int]] { lock.withLock { received } } init() throws { listener = try NWListener(using: .tcp, on: .any) } func start() async throws -> URL { listener.newConnectionHandler = { [weak self] connection in guard let self else { return } connection.start(queue: self.queue) self.read(connection, buffer: Data()) } return try await withCheckedThrowingContinuation { continuation in listener.stateUpdateHandler = { [weak self] state in guard let self else { return } switch state { case .ready: self.listener.stateUpdateHandler = nil continuation.resume(returning: URL(string: "http://127.0.0.1:\(self.listener.port!.rawValue)")!) case .failed(let error): self.listener.stateUpdateHandler = nil continuation.resume(throwing: error) default: break } } listener.start(queue: queue) } } func stop() { listener.cancel() } private func read(_ connection: NWConnection, buffer: Data) { connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { [weak self] data, _, complete, error in guard let self, let data, error == nil else { connection.cancel(); return } var bytes = buffer; bytes.append(data) guard let separator = bytes.range(of: Data("\r\n\r\n".utf8)), let headers = String(data: bytes[..= length else { if !complete { self.read(connection, buffer: bytes) } else { connection.cancel() } return } let body = bytes.subdata(in: separator.upperBound..<(separator.upperBound + length)) guard let request = try? JSONDecoder().decode([String: Int].self, from: body), let size = request["size"] else { connection.cancel(); return } self.lock.withLock { self.received.append(request) } let axis = request["col"] == nil ? "rows" : "cols" let index = request["col"] ?? request["row"] ?? 0 let response = "{\"version\":0,\"cells\":[],\"sizes\":{\"\(axis)\":{\"\(index)\":\(size)}}}" let message = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: \(response.utf8.count)\r\nConnection: close\r\n\r\n\(response)" connection.send(content: Data(message.utf8), completion: .contentProcessed { _ in connection.cancel() }) } } } #endif