diff --git a/Sources/NIOHTTP1/HTTPTypes.swift b/Sources/NIOHTTP1/HTTPTypes.swift index ddc7c1430e..50009dff03 100644 --- a/Sources/NIOHTTP1/HTTPTypes.swift +++ b/Sources/NIOHTTP1/HTTPTypes.swift @@ -540,28 +540,37 @@ extension HTTPHeaders: RandomAccessCollection { } } -extension Character { +extension UTF8.CodeUnit { var isASCIIWhitespace: Bool { - return self == " " || self == "\t" || self == "\r" || self == "\n" || self == "\r\n" + switch self { + case UInt8(ascii: " "), + UInt8(ascii: "\t"), + UInt8(ascii: "\r"), + UInt8(ascii: "\n"): + return true + + default: + return false + } } } extension String { func trimASCIIWhitespace() -> Substring { - return self.dropFirst(0).trimWhitespace() + return Substring(self).trimWhitespace() } } -private extension Substring { - func trimWhitespace() -> Substring { - var me = self - while me.first?.isASCIIWhitespace == .some(true) { - me = me.dropFirst() - } - while me.last?.isASCIIWhitespace == .some(true) { - me = me.dropLast() +extension Substring { + fileprivate func trimWhitespace() -> Substring { + guard let firstNonWhitespace = self.utf8.firstIndex(where: { !$0.isASCIIWhitespace }) else { + // The whole substring is ASCII whitespace. + return Substring() } - return me + + // There must be at least one non-ascii whitespace character, so banging here is safe. + let lastNonWhitespace = self.utf8.lastIndex(where: { !$0.isASCIIWhitespace })! + return Substring(self.utf8[firstNonWhitespace...lastNonWhitespace]) } }