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
HTTPParser.swift:72
    guard let result = findResult else { throw HTTPParserError.Incomplete }
HTTPParser.swift:76
        throw HTTPParserError.Internal
HTTPParser.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.Internal
SynchronousWorker.swift:143
    } catch let error as HTTPParserError {
: ErrorType { 0012 case BadSyntax
HTTPParser.swift:19
    case let .BadSyntax(syntax):
HTTPParser.swift:93
      throw HTTPParserError.BadSyntax(requestLine)
(String) 0013 case BadVersion
HTTPParser.swift:21
    case let .BadVersion(version):
HTTPParser.swift:102
      throw HTTPParserError.BadVersion(version)
(String) 0014 case Incomplete
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 }
0015 case Internal
HTTPParser.swift:25
    case .Internal:
HTTPParser.swift:76
        throw HTTPParserError.Internal
HTTPParser.swift:137
      throw HTTPParserError.Internal
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
SynchronousWorker.swift:135
    let parser = HTTPParser(socket: client)
{ 0032 let socket
HTTPParser.swift:35
    self.socket = socket
HTTPParser.swift:48
      let bytes = try socket.read(nextSize)
: Socket 0033 0034 init
SynchronousWorker.swift:135
    let parser = HTTPParser(socket: client)
(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
HTTPParser.swift:63
    try readWhile({ bytes in
HTTPParser.swift:83
    return try readWhile({ bytes in min(maxLength-bytes.count, 512) })
(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:87
    let (top, startOfBody) = try readHeaders()
() 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:64
      if let (top, bottom) = bytes.find(crln) {
(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:152
      if lhs.hasSuffix(characters) {
(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:88
    var components = top.split("\r\n")
HTTPParser.swift:91
    let requestComponents = requestLine.split(" ")
(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:174
    let scanner = Scanner(self)
{ 0189 var content
HTTPParser.swift:192
    self.content = content
HTTPParser.swift:196
    return content.characters.count == 0
HTTPParser.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])
: String 0190 0191 init
HTTPParser.swift:174
    let scanner = Scanner(self)
(_ content: String) { 0192 self.content = content 0193 } 0194 0195 var isEmpty
HTTPParser.swift:178
    while !scanner.isEmpty && scans <= maxSeparator {
: Bool { 0196 return content.characters.count == 0 0197 } 0198 0199 func scan
HTTPParser.swift:179
      components.append(scanner.scan(until: separator))
(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:101
    if !version.hasPrefix("HTTP/1") {
HTTPParser.swift:212
      if content.hasPrefix(until) {
(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