// // GeminiProtocol.swift // Gemini // // Created by Shadowfacts on 7/12/20. // import Network class GeminiProtocol: NWProtocolFramerImplementation { static let definition = NWProtocolFramer.Definition(implementation: GeminiProtocol.self) static let label = "Gemini" required init(framer: NWProtocolFramer.Instance) { } func start(framer: NWProtocolFramer.Instance) -> NWProtocolFramer.StartResult { return .ready } func wakeup(framer: NWProtocolFramer.Instance) { } func stop(framer: NWProtocolFramer.Instance) -> Bool { return true } func cleanup(framer: NWProtocolFramer.Instance) { } func handleInput(framer: NWProtocolFramer.Instance) -> Int { while true { var tempStatusCode: GeminiResponse.StatusCode? let parsedStatusCodeAndSpace = framer.parseInput(minimumIncompleteLength: 3, maximumLength: 3) { (buffer, isComplete) -> Int in guard let buffer = buffer, buffer.count == 3 else { return 0 } tempStatusCode = GeminiResponse.StatusCode(buffer) return 3 } guard parsedStatusCodeAndSpace, let statusCode = tempStatusCode else { return 3 } var tempMeta: String? // Minimum length is 2 bytes, spec does not say meta string is required let parsedMeta = framer.parseInput(minimumIncompleteLength: 2, maximumLength: 1024 + 2) { (buffer, isComplete) -> Int in guard let buffer = buffer, buffer.count >= 2 else { return 0 } let lastPossibleCRIndex = buffer.index(before: buffer.index(before: buffer.endIndex)) var index = buffer.startIndex var found = false while index <= lastPossibleCRIndex { // if buffer[index] == 13 && buffer[buffer.index(after: index)] == 10 { found = true break } index = buffer.index(after: index) } guard found else { fatalError("Didn't find in buffer. Meta string was longer than 1024 bytes") } tempMeta = String(bytes: buffer[..