diff --git a/GeminiProtocol/GeminiDataTask.swift b/GeminiProtocol/GeminiDataTask.swift index 1442252..2bae8eb 100644 --- a/GeminiProtocol/GeminiDataTask.swift +++ b/GeminiProtocol/GeminiDataTask.swift @@ -79,6 +79,7 @@ public class GeminiDataTask { self.completion(.failure(.connectionError(error))) } else if let message = context?.protocolMetadata(definition: GeminiProtocol.definition) as? NWProtocolFramer.Message, let header = message.geminiResponseHeader { + guard isComplete else { fatalError() } let response = GeminiResponse(header: header, body: data) self.completion(.success(response)) } diff --git a/GeminiProtocol/GeminiProtocol.swift b/GeminiProtocol/GeminiProtocol.swift index b0f80a8..569b71f 100644 --- a/GeminiProtocol/GeminiProtocol.swift +++ b/GeminiProtocol/GeminiProtocol.swift @@ -88,12 +88,12 @@ class GeminiProtocol: NWProtocolFramerImplementation { let header = GeminiResponseHeader(status: statusCode, meta: meta) let message = NWProtocolFramer.Message(geminiResponseHeader: header) - // What does the return value of deliverInputNoCopy mean, you ask? Why, I have no idea - // It always returns true for a length of zero, so following the sample code and looping - // infinitely until it returns false causes an infinite loop. - // Additionally, calling deliverInput with an empty Data() causes an error inside Network.framework. - // So, we just ignore the result since it doesn't seem to cause any problems ¯\_(ツ)_/¯ + // Deliver all the input (the response body) to the client without copying. _ = framer.deliverInputNoCopy(length: statusCode.isSuccess ? .max : 0, message: message, isComplete: true) + // Just in case, set the framer to pass-through input so it never invokes this method again. + // todo: this should work according to an apple engineer, but the request seems to hang forever on a real device + // sometimes works fine when stepping through w/ debugger => race condition? +// framer.passThroughInput() return 0 }