0001 #if os(Linux) 0002 import Glibc 0003 #else 0004 import Darwin.C 0005 #endif 0006 0007 import Nest 0008 import Inquiline 0009 0010 0011 enum HTTPParserError: ErrorType { 0012 case BadSyntax
HTTPParser.swift:72 guard let result = findResult else { throw HTTPParserError.Incomplete }HTTPParser.swift:76 throw HTTPParserError.InternalHTTPParser.swift:93 throw HTTPParserError.BadSyntax(requestLine)HTTPParser.swift:102 throw HTTPParserError.BadVersion(version)HTTPParser.swift:131 guard bytes.count >= contentLength else { throw HTTPParserError.Incomplete }HTTPParser.swift:137 throw HTTPParserError.InternalSynchronousWorker.swift:143 } catch let error as HTTPParserError {(String) 0013 case BadVersion
HTTPParser.swift:19 case let .BadSyntax(syntax):HTTPParser.swift:93 throw HTTPParserError.BadSyntax(requestLine)(String) 0014 case Incomplete
HTTPParser.swift:21 case let .BadVersion(version):HTTPParser.swift:102 throw HTTPParserError.BadVersion(version)0015 case Internal
HTTPParser.swift:23 case .Incomplete:HTTPParser.swift:72 guard let result = findResult else { throw HTTPParserError.Incomplete }HTTPParser.swift:131 guard bytes.count >= contentLength else { throw HTTPParserError.Incomplete }0016 0017 func response() -> ResponseType { 0018 switch self { 0019 case let .BadSyntax(syntax): 0020 return Response(.BadRequest, contentType: "text/plain", body: "Bad Syntax (\(syntax))") 0021 case let .BadVersion(version): 0022 return Response(.BadRequest, contentType: "text/plain", body: "Bad Version (\(version))") 0023 case .Incomplete: 0024 return Response(.BadRequest, contentType: "text/plain", body: "Incomplete HTTP Request") 0025 case .Internal: 0026 return Response(.InternalServerError, contentType: "text/plain", body: "Internal Server Error") 0027 } 0028 } 0029 } 0030 0031 class HTTPParser
HTTPParser.swift:25 case .Internal:HTTPParser.swift:76 throw HTTPParserError.InternalHTTPParser.swift:137 throw HTTPParserError.Internal{ 0032 let socket
SynchronousWorker.swift:135 let parser = HTTPParser(socket: client): Socket 0033 0034 init
HTTPParser.swift:35 self.socket = socketHTTPParser.swift:48 let bytes = try socket.read(nextSize)(socket: Socket) { 0035 self.socket = socket 0036 } 0037 0038 // Repeatedly read the socket, calling the predicate with the accumulated 0039 // buffer to determine how many bytes to attempt to read next. 0040 // Stops reading and returns the buffer when the predicate returns 0. 0041 func readWhile
SynchronousWorker.swift:135 let parser = HTTPParser(socket: client)(predicate: [CChar] -> Int) throws -> [CChar] { 0042 var buffer: [CChar] = [] 0043 0044 while true { 0045 let nextSize = predicate(buffer) 0046 guard nextSize > 0 else { break } 0047 0048 let bytes = try socket.read(nextSize) 0049 guard !bytes.isEmpty else { break } 0050 0051 buffer += bytes 0052 } 0053 0054 return buffer 0055 } 0056 0057 // Read the socket until we find \r\n\r\n 0058 // returning string before and chars after 0059 func readHeaders
HTTPParser.swift:63 try readWhile({ bytes inHTTPParser.swift:83 return try readWhile({ bytes in min(maxLength-bytes.count, 512) })() throws -> (String, [CChar]) { 0060 var findResult: (top: [CChar], bottom: [CChar])? 0061 0062 let crln: [CChar] = [13, 10, 13, 10] 0063 try readWhile({ bytes in 0064 if let (top, bottom) = bytes.find(crln) { 0065 findResult = (top, bottom) 0066 return 0 0067 } else { 0068 return 512 0069 } 0070 }) 0071 0072 guard let result = findResult else { throw HTTPParserError.Incomplete } 0073 0074 guard let headers = String.fromCString(result.top + [0]) else { 0075 print("[worker] Failed to decode data from client") 0076 throw HTTPParserError.Internal 0077 } 0078 0079 return (headers, result.bottom) 0080 } 0081 0082 func readBody(maxLength maxLength: Int) throws -> [CChar] { 0083 return try readWhile({ bytes in min(maxLength-bytes.count, 512) }) 0084 } 0085 0086 func parse() throws -> RequestType { 0087 let (top, startOfBody) = try readHeaders() 0088 var components = top.split("\r\n") 0089 let requestLine = components.removeFirst() 0090 components.removeLast() 0091 let requestComponents = requestLine.split(" ") 0092 if requestComponents.count != 3 { 0093 throw HTTPParserError.BadSyntax(requestLine) 0094 } 0095 0096 let method = requestComponents[0] 0097 // TODO path should be un-quoted 0098 let path = requestComponents[1] 0099 let version = requestComponents[2] 0100 0101 if !version.hasPrefix("HTTP/1") { 0102 throw HTTPParserError.BadVersion(version) 0103 } 0104 0105 var request = Request(method: method, path: path, headers: parseHeaders(components)) 0106 0107 if let contentLength = request.contentLength { 0108 let remainingContentLength = contentLength - startOfBody.count 0109 let bodyBytes = startOfBody + (try readBody(maxLength: remainingContentLength)) 0110 request.body = try parseBody(bodyBytes, contentLength: contentLength) 0111 } 0112 0113 return request 0114 } 0115 0116 func parseHeaders(headers: [String]) -> [Header] { 0117 return headers.map { $0.split(":", maxSeparator: 1) }.flatMap { 0118 if $0.count == 2 { 0119 if $0[1].characters.first == " " { 0120 let value = String($0[1].characters[$0[1].startIndex.successor()..<$0[1].endIndex]) 0121 return ($0[0], value) 0122 } 0123 return ($0[0], $0[1]) 0124 } 0125 0126 return nil 0127 } 0128 } 0129 0130 func parseBody(bytes: [CChar], contentLength: Int) throws -> String { 0131 guard bytes.count >= contentLength else { throw HTTPParserError.Incomplete } 0132 0133 let trimmedBytes = contentLength<bytes.count ? Array(bytes[0..<contentLength]) : bytes 0134 0135 guard let bodyString = String.fromCString(trimmedBytes + [0]) else { 0136 print("[worker] Failed to decode message body from client") 0137 throw HTTPParserError.Internal 0138 } 0139 return bodyString 0140 } 0141 } 0142 0143 0144 extension CollectionType where Generator.Element == CChar { 0145 func find
HTTPParser.swift:87 let (top, startOfBody) = try readHeaders()(characters: [CChar]) -> ([CChar], [CChar])? { 0146 var lhs: [CChar] = [] 0147 var rhs = Array(self) 0148 0149 while !rhs.isEmpty { 0150 let character = rhs.removeAtIndex(0) 0151 lhs.append(character) 0152 if lhs.hasSuffix(characters) { 0153 return (lhs, rhs) 0154 } 0155 } 0156 0157 return nil 0158 } 0159 0160 func hasSuffix
HTTPParser.swift:64 if let (top, bottom) = bytes.find(crln) {(characters: [CChar]) -> Bool { 0161 let chars = Array(self) 0162 if chars.count >= characters.count { 0163 let index = chars.count - characters.count 0164 return Array(chars[index..<chars.count]) == characters 0165 } 0166 0167 return false 0168 } 0169 } 0170 0171 0172 extension String { 0173 func split
HTTPParser.swift:152 if lhs.hasSuffix(characters) {(separator: String, maxSeparator: Int = Int.max) -> [String] { 0174 let scanner = Scanner(self) 0175 var components: [String] = [] 0176 var scans = 0 0177 0178 while !scanner.isEmpty && scans <= maxSeparator { 0179 components.append(scanner.scan(until: separator)) 0180 scans += 1 0181 } 0182 0183 return components 0184 } 0185 } 0186 0187 0188 class Scanner
HTTPParser.swift:88 var components = top.split("\r\n")HTTPParser.swift:91 let requestComponents = requestLine.split(" "){ 0189 var content
HTTPParser.swift:174 let scanner = Scanner(self): String 0190 0191 init
HTTPParser.swift:192 self.content = contentHTTPParser.swift:196 return content.characters.count == 0HTTPParser.swift:206 while !content.isEmpty {HTTPParser.swift:207 let character = content.characters.first!HTTPParser.swift:208 content = String(content.characters.dropFirst())HTTPParser.swift:208 content = String(content.characters.dropFirst())HTTPParser.swift:212 if content.hasPrefix(until) {HTTPParser.swift:213 let index = content.characters.startIndex.advancedBy(until.characters.count)HTTPParser.swift:214 content = String(content.characters[index..<content.characters.endIndex])HTTPParser.swift:214 content = String(content.characters[index..<content.characters.endIndex])HTTPParser.swift:214 content = String(content.characters[index..<content.characters.endIndex])(_ content: String) { 0192 self.content = content 0193 } 0194 0195 var isEmpty
HTTPParser.swift:174 let scanner = Scanner(self): Bool { 0196 return content.characters.count == 0 0197 } 0198 0199 func scan
HTTPParser.swift:178 while !scanner.isEmpty && scans <= maxSeparator {(until until: String) -> String { 0200 if until.isEmpty { 0201 return "" 0202 } 0203 0204 var characters: [Character] = [] 0205 0206 while !content.isEmpty { 0207 let character = content.characters.first! 0208 content = String(content.characters.dropFirst()) 0209 0210 characters.append(character) 0211 0212 if content.hasPrefix(until) { 0213 let index = content.characters.startIndex.advancedBy(until.characters.count) 0214 content = String(content.characters[index..<content.characters.endIndex]) 0215 break 0216 } 0217 } 0218 0219 return String(characters) 0220 } 0221 } 0222 0223 extension String { 0224 func hasPrefix
HTTPParser.swift:179 components.append(scanner.scan(until: separator))(prefix: String) -> Bool { 0225 let characters = utf16 0226 let prefixCharacters = prefix.utf16 0227 let start = characters.startIndex 0228 let prefixStart = prefixCharacters.startIndex 0229 0230 if characters.count < prefixCharacters.count { 0231 return false 0232 } 0233 0234 for idx in 0..<prefixCharacters.count { 0235 if characters[start.advancedBy(idx)] != prefixCharacters[prefixStart.advancedBy(idx)] { 0236 return false 0237 } 0238 } 0239 0240 return true 0241 } 0242 } 0243
HTTPParser.swift:101 if !version.hasPrefix("HTTP/1") {HTTPParser.swift:212 if content.hasPrefix(until) {