0001    /*
0002     The MIT License (MIT)
0003    
0004     Copyright (c) 2015 Shun Takebayashi
0005    
0006     Permission is hereby granted, free of charge, to any person obtaining a copy
0007     of this software and associated documentation files (the "Software"), to deal
0008     in the Software without restriction, including without limitation the rights
0009     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0010     copies of the Software, and to permit persons to whom the Software is
0011     furnished to do so, subject to the following conditions:
0012    
0013     The above copyright notice and this permission notice shall be included in all
0014     copies or substantial portions of the Software.
0015    
0016     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0017     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0018     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0019     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0020     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0021     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0022     SOFTWARE.
0023    */
0024    
0025    public struct HTTPRequest
HTTPRequest.swift:57
        static func parse<R: Reader where R.Entry == Int8>(reader: R) throws -> HTTPRequest {
HTTPRequest.swift:108
            return HTTPRequest(method: parsedMethod, path: parsedPath, version: parsedVersion, headers: headers, body: body)
HTTPServer.swift:31
public typealias HTTPHandler = (HTTPRequest, HTTPResponseWriter) throws -> ()
HTTPServer.swift:65
                try handler(HTTPRequest.Parser.parse(reader), writer)
{ 0026 0027 public let method
HTTPRequest.swift:34
        self.method = method
: String 0028 public let path
HTTPRequest.swift:35
        self.path = path
: String 0029 public let proto
HTTPRequest.swift:36
        self.proto = version
: String 0030 public let headers
HTTPRequest.swift:37
        self.headers = headers
: [String: String] 0031 public let body
HTTPRequest.swift:38
        self.body = body
: [Int8] 0032 0033 init
HTTPRequest.swift:108
            return HTTPRequest(method: parsedMethod, path: parsedPath, version: parsedVersion, headers: headers, body: body)
(method: String, path: String, version: String, headers: [String: String], body: [Int8]) { 0034 self.method = method 0035 self.path = path 0036 self.proto = version 0037 self.headers = headers 0038 self.body = body 0039 } 0040 0041 0042 class Parser
HTTPServer.swift:65
                try handler(HTTPRequest.Parser.parse(reader), writer)
{ 0043 0044 static let CRLF
HTTPRequest.swift:70
                let str = (String.fromCString(bytes) ?? "").trimRight(CRLF)
= Character("\r\n") 0045 0046 enum Mode
HTTPRequest.swift:59
            var mode = Mode.First
{ 0047 case First
HTTPRequest.swift:59
            var mode = Mode.First
HTTPRequest.swift:72
                case .First:
0048 case Header
HTTPRequest.swift:77
                    mode = .Header
HTTPRequest.swift:78
                case .Header:
0049 case Empty
HTTPRequest.swift:80
                        mode = .Empty
HTTPRequest.swift:88
                case .Empty:
0050 case Body
HTTPRequest.swift:89
                    mode = .Body
HTTPRequest.swift:91
                case .Body:
0051 } 0052 0053 enum ParserError
HTTPRequest.swift:97
                throw ParserError.InvalidRequest(details: "Missing HTTP request method")
HTTPRequest.swift:101
                throw ParserError.InvalidRequest(details: "Missing HTTP request path")
HTTPRequest.swift:105
                throw ParserError.InvalidRequest(details: "Missing HTTP request version")
: ErrorType { 0054 case InvalidRequest
HTTPRequest.swift:97
                throw ParserError.InvalidRequest(details: "Missing HTTP request method")
HTTPRequest.swift:101
                throw ParserError.InvalidRequest(details: "Missing HTTP request path")
HTTPRequest.swift:105
                throw ParserError.InvalidRequest(details: "Missing HTTP request version")
HTTPServer.swift:73
            catch let HTTPRequest.Parser.ParserError.InvalidRequest(details: details) {
(details: String) 0055 } 0056 0057 static func parse
HTTPServer.swift:65
                try handler(HTTPRequest.Parser.parse(reader), writer)
<R: Reader where R.Entry == Int8>(reader: R) throws -> HTTPRequest { 0058 let bufferedReader = BufferedReader(reader: reader) 0059 var mode = Mode.First 0060 0061 var method: String? 0062 var path: String? 0063 var version: String? 0064 var headers = [String: String]() 0065 var body = [Int8]() 0066 0067 while let line = try bufferedReader.read() { 0068 var bytes = line 0069 bytes.append(0) 0070 let str = (String.fromCString(bytes) ?? "").trimRight(CRLF) 0071 switch mode { 0072 case .First: 0073 let fields = str.characters.split(" ", maxSplit: 3, allowEmptySlices: true) 0074 method = String(fields[0]) 0075 path = String(fields[1]) 0076 version = String(fields[2]) 0077 mode = .Header 0078 case .Header: 0079 if str.isEmpty { 0080 mode = .Empty 0081 } 0082 else { 0083 let field = str.characters.split(":", maxSplit: 2, allowEmptySlices: true) 0084 let name = String(field[0]) 0085 let value = String(field[1]).trimLeft(" ", maxCount: 1) 0086 headers[name] = value 0087 } 0088 case .Empty: 0089 mode = .Body 0090 fallthrough 0091 case .Body: 0092 body.appendContentsOf(line) 0093 } 0094 } 0095 0096 guard let parsedMethod = method else { 0097 throw ParserError.InvalidRequest(details: "Missing HTTP request method") 0098 } 0099 0100 guard let parsedPath = path else { 0101 throw ParserError.InvalidRequest(details: "Missing HTTP request path") 0102 } 0103 0104 guard let parsedVersion = version else { 0105 throw ParserError.InvalidRequest(details: "Missing HTTP request version") 0106 } 0107 0108 return HTTPRequest(method: parsedMethod, path: parsedPath, version: parsedVersion, headers: headers, body: body) 0109 } 0110 0111 } 0112 0113 } 0114 0115