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
RequestParser.swift:66
    let context: RequestContext
RequestParser.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 {
= UnsafeMutablePointer<RequestParserContext> 0031 0032 struct RequestParserContext
RequestParser.swift:30
typealias RequestContext = UnsafeMutablePointer<RequestParserContext>
RequestParser.swift:72
        context.initialize(RequestParserContext { request in
{ 0033 var method
RequestParser.swift:173
        $0.method = Method(code: Int(parser.memory.method))
RequestParser.swift:217
        $0.method = nil
: Method! = nil 0034 var uri: URI! = nil 0035 var version
RequestParser.swift:174
        $0.version = (Int(parser.memory.http_major), Int(parser.memory.http_minor))
RequestParser.swift:219
        $0.version = (0, 0)
: (major: Int, minor: Int) = (0, 0) 0036 var headers
RequestParser.swift:163
            let previousHeaderValue = $0.headers[headerName] ?? ""
RequestParser.swift:220
        $0.headers = [:]
: Headers = [:] 0037 var cookies
RequestParser.swift:182
                $0.cookies = cookies
RequestParser.swift:221
        $0.cookies = []
: Cookies = [] 0038 var body: Data = [] 0039 0040 var buildingCookieValue
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 = ""
= "" 0041 var currentURI
RequestParser.swift:188
        $0.currentURI = ""
= "" 0042 var buildingHeaderField
RequestParser.swift:148
        if $0.buildingHeaderField != "" {
RequestParser.swift:149
            $0.currentHeaderField = $0.buildingHeaderField
RequestParser.swift:152
        $0.buildingHeaderField = ""
RequestParser.swift:189
        $0.buildingHeaderField = ""
= "" 0043 var currentHeaderField
RequestParser.swift:149
            $0.currentHeaderField = $0.buildingHeaderField
RequestParser.swift:153
        let headerField = $0.currentHeaderField
RequestParser.swift:190
        $0.currentHeaderField = ""
= "" 0044 var completion
RequestParser.swift:47
        self.completion = completion
: Request -> Void 0045 0046 init
RequestParser.swift:72
        context.initialize(RequestParserContext { request in
(completion: Request -> Void) { 0047 self.completion = completion 0048 } 0049 } 0050 0051 var requestSettings
RequestParser.swift:96
        let bytesParsed = http_parser_execute(&parser, &requestSettings, buffer, data.count)
: 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:114
extension RequestParser {
: RequestParserType { 0066 let context
RequestParser.swift:71
        context = RequestContext.alloc(1)
RequestParser.swift:72
        context.initialize(RequestParserContext { request in
RequestParser.swift:80
        context.destroy()
RequestParser.swift:81
        context.dealloc(1)
RequestParser.swift:86
        parser.data = UnsafeMutablePointer<Void>(context)
: RequestContext 0067 var parser
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))
= http_parser() 0068 var request
RequestParser.swift:73
            self.request = request
RequestParser.swift:90
        defer { request = nil }
RequestParser.swift:106
        if request != nil {
: 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:76
        resetParser()
RequestParser.swift:99
            resetParser()
RequestParser.swift:107
            resetParser()
() { 0085 http_parser_init(&parser, HTTP_REQUEST) 0086 parser.data = UnsafeMutablePointer<Void>(context) 0087 } 0088 0089 public func parse
RequestParser.swift:115
    public func parse(convertible: DataConvertible) throws -> Request? {
(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:55
    settings.on_url              = onRequestURL
(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:56
    settings.on_header_field     = onRequestHeaderField
(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:57
    settings.on_header_value     = onRequestHeaderValue
(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:58
    settings.on_headers_complete = onRequestHeadersComplete
(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:59
    settings.on_body             = onRequestBody
(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:60
    settings.on_message_complete = onRequestMessageComplete
(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