0001 // RequestParser.swift 0002 // 0003 // The MIT License (MIT) 0004 // 0005 // Copyright (c) 2015 Zewo 0006 // 0007 // Permission is hereby granted, free of charge, to any person obtaining a copy 0008 // of this software and associated documentation files (the "Software"), to deal 0009 // in the Software without restriction, including without limitation the rights 0010 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 0011 // copies of the Software, and to permit persons to whom the Software is 0012 // furnished to do so, subject to the following conditions: 0013 // 0014 // The above copyright notice and this permission notice shall be included in all 0015 // copies or substantial portions of the Software. 0016 // 0017 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0018 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0019 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0020 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 0021 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 0022 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 0023 // SOFTWARE. 0024 0025 import CHTTPParser 0026 @_exported import URI 0027 @_exported import Data 0028 @_exported import String 0029 0030 typealias RequestContext= UnsafeMutablePointer<RequestParserContext> 0031 0032 struct RequestParserContext
RequestParser.swift:66 let context: RequestContextRequestParser.swift:71 context = RequestContext.alloc(1)RequestParser.swift:121 return RequestContext(parser.memory.data).withMemory {RequestParser.swift:132 return RequestContext(parser.memory.data).withMemory {RequestParser.swift:147 return RequestContext(parser.memory.data).withMemory {RequestParser.swift:172 return RequestContext(parser.memory.data).withMemory {RequestParser.swift:196 RequestContext(parser.memory.data).withMemory {RequestParser.swift:204 return RequestContext(parser.memory.data).withMemory {{ 0033 var method
RequestParser.swift:30 typealias RequestContext = UnsafeMutablePointer<RequestParserContext>RequestParser.swift:72 context.initialize(RequestParserContext { request in: Method! = nil 0034 var uri: URI! = nil 0035 var version
RequestParser.swift:173 $0.method = Method(code: Int(parser.memory.method))RequestParser.swift:217 $0.method = nil: (major: Int, minor: Int) = (0, 0) 0036 var headers
RequestParser.swift:174 $0.version = (Int(parser.memory.http_major), Int(parser.memory.http_minor))RequestParser.swift:219 $0.version = (0, 0): Headers = [:] 0037 var cookies
RequestParser.swift:163 let previousHeaderValue = $0.headers[headerName] ?? ""RequestParser.swift:220 $0.headers = [:]: Cookies = [] 0038 var body: Data = [] 0039 0040 var buildingCookieValue
RequestParser.swift:182 $0.cookies = cookiesRequestParser.swift:221 $0.cookies = []= "" 0041 var currentURI
RequestParser.swift:137 if $0.buildingCookieValue != "" {RequestParser.swift:138 $0.buildingCookieValue = ""RequestParser.swift:180 if $0.buildingCookieValue != "" {RequestParser.swift:181 if let cookies = try? Cookie.parseCookie($0.buildingCookieValue) {RequestParser.swift:186 $0.buildingCookieValue = ""= "" 0042 var buildingHeaderField
RequestParser.swift:188 $0.currentURI = ""= "" 0043 var currentHeaderField
RequestParser.swift:148 if $0.buildingHeaderField != "" {RequestParser.swift:149 $0.currentHeaderField = $0.buildingHeaderFieldRequestParser.swift:152 $0.buildingHeaderField = ""RequestParser.swift:189 $0.buildingHeaderField = ""= "" 0044 var completion
RequestParser.swift:149 $0.currentHeaderField = $0.buildingHeaderFieldRequestParser.swift:153 let headerField = $0.currentHeaderFieldRequestParser.swift:190 $0.currentHeaderField = "": Request -> Void 0045 0046 init
RequestParser.swift:47 self.completion = completion(completion: Request -> Void) { 0047 self.completion = completion 0048 } 0049 } 0050 0051 var requestSettings
RequestParser.swift:72 context.initialize(RequestParserContext { request in: http_parser_settings = { 0052 var settings = http_parser_settings() 0053 http_parser_settings_init(&settings) 0054 0055 settings.on_url = onRequestURL 0056 settings.on_header_field = onRequestHeaderField 0057 settings.on_header_value = onRequestHeaderValue 0058 settings.on_headers_complete = onRequestHeadersComplete 0059 settings.on_body = onRequestBody 0060 settings.on_message_complete = onRequestMessageComplete 0061 0062 return settings 0063 }() 0064 0065 public final class RequestParser
RequestParser.swift:96 let bytesParsed = http_parser_execute(&parser, &requestSettings, buffer, data.count): RequestParserType { 0066 let context
RequestParser.swift:114 extension RequestParser {: RequestContext 0067 var parser
RequestParser.swift:71 context = RequestContext.alloc(1)RequestParser.swift:72 context.initialize(RequestParserContext { request inRequestParser.swift:80 context.destroy()RequestParser.swift:81 context.dealloc(1)RequestParser.swift:86 parser.data = UnsafeMutablePointer<Void>(context)= http_parser() 0068 var request
RequestParser.swift:85 http_parser_init(&parser, HTTP_REQUEST)RequestParser.swift:86 parser.data = UnsafeMutablePointer<Void>(context)RequestParser.swift:100 let errorName = http_errno_name(http_errno(parser.http_errno))RequestParser.swift:101 let errorDescription = http_errno_description(http_errno(parser.http_errno)): Request? 0069 0070 public init() { 0071 context = RequestContext.alloc(1) 0072 context.initialize(RequestParserContext { request in 0073 self.request = request 0074 }) 0075 0076 resetParser() 0077 } 0078 0079 deinit { 0080 context.destroy() 0081 context.dealloc(1) 0082 } 0083 0084 func resetParser
RequestParser.swift:73 self.request = requestRequestParser.swift:90 defer { request = nil }RequestParser.swift:106 if request != nil {() { 0085 http_parser_init(&parser, HTTP_REQUEST) 0086 parser.data = UnsafeMutablePointer<Void>(context) 0087 } 0088 0089 public func parse
RequestParser.swift:76 resetParser()RequestParser.swift:99 resetParser()RequestParser.swift:107 resetParser()(data: Data) throws -> Request? { 0090 defer { request = nil } 0091 0092 let buffer = data.withUnsafeBufferPointer { 0093 UnsafeMutablePointer<Int8>($0.baseAddress) 0094 } 0095 0096 let bytesParsed = http_parser_execute(&parser, &requestSettings, buffer, data.count) 0097 0098 if bytesParsed != data.count { 0099 resetParser() 0100 let errorName = http_errno_name(http_errno(parser.http_errno)) 0101 let errorDescription = http_errno_description(http_errno(parser.http_errno)) 0102 let error = ParseError(description: "\(String.fromCString(errorName)!): \(String.fromCString(errorDescription)!)") 0103 throw error 0104 } 0105 0106 if request != nil { 0107 resetParser() 0108 } 0109 0110 return request 0111 } 0112 } 0113 0114 extension RequestParser { 0115 public func parse(convertible: DataConvertible) throws -> Request? { 0116 return try parse(convertible.data) 0117 } 0118 } 0119 0120 func onRequestURL
RequestParser.swift:115 public func parse(convertible: DataConvertible) throws -> Request? {(parser: Parser, data: UnsafePointer<Int8>, length: Int) -> Int32 { 0121 return RequestContext(parser.memory.data).withMemory { 0122 guard let uri = String(pointer: data, length: length) else { 0123 return 1 0124 } 0125 0126 $0.currentURI += uri 0127 return 0 0128 } 0129 } 0130 0131 func onRequestHeaderField
RequestParser.swift:55 settings.on_url = onRequestURL(parser: Parser, data: UnsafePointer<Int8>, length: Int) -> Int32 { 0132 return RequestContext(parser.memory.data).withMemory { 0133 guard let headerField = String(pointer: data, length: length) else { 0134 return 1 0135 } 0136 0137 if $0.buildingCookieValue != "" { 0138 $0.buildingCookieValue = "" 0139 } 0140 0141 $0.buildingHeaderField += headerField 0142 return 0 0143 } 0144 } 0145 0146 func onRequestHeaderValue
RequestParser.swift:56 settings.on_header_field = onRequestHeaderField(parser: Parser, data: UnsafePointer<Int8>, length: Int) -> Int32 { 0147 return RequestContext(parser.memory.data).withMemory { 0148 if $0.buildingHeaderField != "" { 0149 $0.currentHeaderField = $0.buildingHeaderField 0150 } 0151 0152 $0.buildingHeaderField = "" 0153 let headerField = $0.currentHeaderField 0154 0155 guard let headerValue = String(pointer: data, length: length) else { 0156 return 1 0157 } 0158 0159 if headerField == "Cookie" { 0160 $0.buildingCookieValue += headerValue 0161 } else { 0162 let headerName = HeaderName(headerField) 0163 let previousHeaderValue = $0.headers[headerName] ?? "" 0164 $0.headers[headerName] = previousHeaderValue + headerValue 0165 } 0166 0167 return 0 0168 } 0169 } 0170 0171 func onRequestHeadersComplete
RequestParser.swift:57 settings.on_header_value = onRequestHeaderValue(parser: Parser) -> Int32 { 0172 return RequestContext(parser.memory.data).withMemory { 0173 $0.method = Method(code: Int(parser.memory.method)) 0174 $0.version = (Int(parser.memory.http_major), Int(parser.memory.http_minor)) 0175 0176 guard let uri = try? URI(string: $0.currentURI) else { 0177 return 1 0178 } 0179 0180 if $0.buildingCookieValue != "" { 0181 if let cookies = try? Cookie.parseCookie($0.buildingCookieValue) { 0182 $0.cookies = cookies 0183 } 0184 } 0185 0186 $0.buildingCookieValue = "" 0187 $0.uri = uri 0188 $0.currentURI = "" 0189 $0.buildingHeaderField = "" 0190 $0.currentHeaderField = "" 0191 return 0 0192 } 0193 } 0194 0195 func onRequestBody
RequestParser.swift:58 settings.on_headers_complete = onRequestHeadersComplete(parser: Parser, data: UnsafePointer<Int8>, length: Int) -> Int32 { 0196 RequestContext(parser.memory.data).withMemory { 0197 $0.body += Data(pointer: data, length: length) 0198 } 0199 0200 return 0 0201 } 0202 0203 func onRequestMessageComplete
RequestParser.swift:59 settings.on_body = onRequestBody(parser: Parser) -> Int32 { 0204 return RequestContext(parser.memory.data).withMemory { 0205 let request = Request( 0206 method: $0.method, 0207 uri: $0.uri, 0208 version: $0.version, 0209 headers: $0.headers, 0210 cookies: $0.cookies, 0211 body: .Buffer($0.body), 0212 upgrade: nil 0213 ) 0214 0215 $0.completion(request) 0216 0217 $0.method = nil 0218 $0.uri = nil 0219 $0.version = (0, 0) 0220 $0.headers = [:] 0221 $0.cookies = [] 0222 $0.body = [] 0223 return 0 0224 } 0225 } 0226
RequestParser.swift:60 settings.on_message_complete = onRequestMessageComplete