0001    //
0002    //  HttpResponse.swift
0003    //  Swifter
0004    //
0005    //  Copyright (c) 2014-2016 Damian KoĊ‚akowski. All rights reserved.
0006    //
0007    
0008    import Foundation
0009    
0010    public enum SerializationError
HttpResponse.swift:32
                    throw SerializationError.InvalidObject
: ErrorType { 0011 case InvalidObject
HttpResponse.swift:32
                    throw SerializationError.InvalidObject
0012 case NotSupported 0013 } 0014 0015 public protocol HttpResponseBodyWriter
HttpResponse.swift:27
    func content() -> (Int, (HttpResponseBodyWriter throws -> Void)?) {
HttpResponse.swift:73
    case RAW(Int, String, [String:String]?, (HttpResponseBodyWriter -> Void)? )
HttpResponse.swift:133
    func content() -> (length: Int, write: (HttpResponseBodyWriter throws -> Void)?) {
HttpServerIO.swift:85
    private struct InnerWriteContext: HttpResponseBodyWriter {
{ 0016 func write
DemoServer.swift:55
            return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
DemoServer.swift:72
            return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
DemoServer.swift:87
        return HttpResponse.RAW(200, "OK", ["XXX-Custom-Header": "value"], { $0.write([UInt8]("test".utf8)) })
DemoServer.swift:112
                w.write([UInt8]("[chunk \(i)]".utf8));
HttpHandlers+Files.swift:70
                    return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
HttpHandlers+Files.swift:86
                return HttpResponse.RAW(206, "Partial Content", headers, { $0.write(content) })
HttpHandlers+Files.swift:90
                return HttpResponse.RAW(200, "OK", nil, { $0.write(content) })
HttpHandlers+Files.swift:120
                    return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
HttpResponse.swift:37
                    $0.write(data)
HttpResponse.swift:42
                    $0.write(data)
HttpResponse.swift:48
                    $0.write(data)
HttpResponse.swift:54
                    $0.write(data)
HttpResponse.swift:60
                $0.write(data)
(data: [UInt8]) 0017 func write
HttpHandlers+Files.swift:24
                    writer.write(buffer[0..<count])
(data: ArraySlice<UInt8>) 0018 } 0019 0020 public enum HttpResponseBody
HttpResponse.swift:69
    case OK(HttpResponseBody), Created, Accepted
HttpResponse.swift:71
    case BadRequest(HttpResponseBody?), Unauthorized, Forbidden, NotFound
{ 0021 0022 case Json
DemoServer.swift:92
        return .OK(.Json(jsonObject))
HttpResponse.swift:30
            case .Json(let object):
HttpResponse.swift:116
            case .Json(_)   : headers["Content-Type"] = "application/json"
(AnyObject) 0023 case Html
DemoServer.swift:30
        return .OK(.Html(listPage))
DemoServer.swift:33
    server["/magic"] = { .OK(.Html("You asked for " + $0.path)) }
DemoServer.swift:48
        return .OK(.Html("<h3>Address: \(r.address)</h3><h3>Url:</h3> \(r.path)<h3>Method:</h3>\(r.method)<h3>Headers:</h3>\(headersInfo)<h3>Query:</h3>\(queryParamsInfo)<h3>Path params:</h3>\(pathParamsInfo)"))
DemoServer.swift:65
        return HttpResponse.OK(.Html(response))
DemoServer.swift:79
        return HttpResponse.OK(.Html(formFields.map({ "\($0.0) = \($0.1)" }).joinWithSeparator("<br>")))
DemoServer.swift:83
        return .OK(.Html("<center><h2>Hello Swift</h2><img src=\"https://devimages.apple.com.edgekey.net/swift/images/swift-hero_2x.png\"/><br></center>"))
DemoServer.swift:102
        return .OK(.Html(longResponse))
DemoServer.swift:106
        return .OK(.Html(r.path))
HttpHandlers+Files.swift:112
                    return HttpResponse.OK(.Html(response))
HttpResponse.swift:44
            case .Html(let body):
HttpResponse.swift:117
            case .Html(_)   : headers["Content-Type"] = "text/html"
(String) 0024 case Text
HttpHandlers+Files.swift:49
                    return .BadRequest(.Text("Invalid value of 'Range' header: \(r.headers["range"])"))
HttpHandlers+Files.swift:61
                    return .BadRequest(.Text("Invalid value of 'Range' header: \(r.headers["range"])"))
HttpHandlers+WebSockets.swift:17
                return .BadRequest(.Text("Invalid value of 'Upgrade' header: \(r.headers["upgrade"])"))
HttpHandlers+WebSockets.swift:20
                return .BadRequest(.Text("Invalid value of 'Connection' header: \(r.headers["connection"])"))
HttpHandlers+WebSockets.swift:23
                return .BadRequest(.Text("Invalid value of 'Sec-Websocket-Key' header: \(r.headers["sec-websocket-key"])"))
HttpResponse.swift:39
            case .Text(let body):
(String) 0025 case Custom
HttpResponse.swift:50
            case .Custom(let object, let closure):
(Any, (Any) throws -> String) 0026 0027 func content
HttpResponse.swift:135
        case .OK(let body)             : return body.content()
HttpResponse.swift:136
        case .BadRequest(let body)     : return body?.content() ?? (-1, nil)
() -> (Int, (HttpResponseBodyWriter throws -> Void)?) { 0028 do { 0029 switch self { 0030 case .Json(let object): 0031 guard NSJSONSerialization.isValidJSONObject(object) else { 0032 throw SerializationError.InvalidObject 0033 } 0034 let json = try NSJSONSerialization.dataWithJSONObject(object, options: NSJSONWritingOptions.PrettyPrinted) 0035 let data = Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>(json.bytes), count: json.length)) 0036 return (data.count, { 0037 $0.write(data) 0038 }) 0039 case .Text(let body): 0040 let data = [UInt8](body.utf8) 0041 return (data.count, { 0042 $0.write(data) 0043 }) 0044 case .Html(let body): 0045 let serialised = "<html><meta charset=\"UTF-8\"><body>\(body)</body></html>" 0046 let data = [UInt8](serialised.utf8) 0047 return (data.count, { 0048 $0.write(data) 0049 }) 0050 case .Custom(let object, let closure): 0051 let serialised = try closure(object) 0052 let data = [UInt8](serialised.utf8) 0053 return (data.count, { 0054 $0.write(data) 0055 }) 0056 } 0057 } catch { 0058 let data = [UInt8]("Serialisation error: \(error)".utf8) 0059 return (data.count, { 0060 $0.write(data) 0061 }) 0062 } 0063 } 0064 } 0065 0066 public enum HttpResponse
DemoServer.swift:55
            return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
DemoServer.swift:65
        return HttpResponse.OK(.Html(response))
DemoServer.swift:72
            return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
DemoServer.swift:79
        return HttpResponse.OK(.Html(formFields.map({ "\($0.0) = \($0.1)" }).joinWithSeparator("<br>")))
DemoServer.swift:87
        return HttpResponse.RAW(200, "OK", ["XXX-Custom-Header": "value"], { $0.write([UInt8]("test".utf8)) })
DemoServer.swift:110
        return HttpResponse.RAW(200, "OK", nil, { w in
HttpHandlers+Files.swift:12
    public class func shareFilesFromDirectory(directoryPath: String) -> (HttpRequest -> HttpResponse) {
HttpHandlers+Files.swift:33
    public class func directory(dir: String) -> (HttpRequest -> HttpResponse) {
HttpHandlers+Files.swift:37
                return HttpResponse.NotFound
HttpHandlers+Files.swift:43
                return HttpResponse.NotFound
HttpHandlers+Files.swift:70
                    return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
HttpHandlers+Files.swift:77
                    return HttpResponse.RAW(416, "Requested range not satisfiable", nil, nil)
HttpHandlers+Files.swift:86
                return HttpResponse.RAW(206, "Partial Content", headers, { $0.write(content) })
HttpHandlers+Files.swift:90
                return HttpResponse.RAW(200, "OK", nil, { $0.write(content) })
HttpHandlers+Files.swift:95
    public class func directoryBrowser(dir: String) -> (HttpRequest -> HttpResponse) {
HttpHandlers+Files.swift:98
                return HttpResponse.NotFound
HttpHandlers+Files.swift:104
                return HttpResponse.NotFound
HttpHandlers+Files.swift:112
                    return HttpResponse.OK(.Html(response))
HttpHandlers+Files.swift:114
                    return HttpResponse.NotFound
HttpHandlers+Files.swift:120
                    return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
HttpHandlers+Files.swift:122
                return HttpResponse.NotFound
HttpHandlers+WebSockets.swift:14
        _ binary: ((WebSocketSession, [UInt8]) -> Void)?) -> (HttpRequest -> HttpResponse) {
HttpHandlers+WebSockets.swift:43
            return HttpResponse.SwitchProtocols(headers, protocolSessionClosure)
HttpResponse.swift:161
func ==(inLeft: HttpResponse, inRight: HttpResponse) -> Bool {
HttpResponse.swift:161
func ==(inLeft: HttpResponse, inRight: HttpResponse) -> Bool {
HttpRouter.swift:14
        var handler: (HttpRequest -> HttpResponse)? = nil
HttpRouter.swift:38
    public func register(method: String?, path: String, handler: (HttpRequest -> HttpResponse)?) {
HttpRouter.swift:49
    public func route(method: String?, path: String) -> ([String: String], HttpRequest -> HttpResponse)? {
HttpRouter.swift:79
    private func findHandler(inout node: Node, inout params: [String: String], inout generator: IndexingGenerator<[String]>) -> (HttpRequest -> HttpResponse)? {
HttpServer.swift:46
    override public func dispatch(method: String, path: String) -> ([String:String], HttpRequest -> HttpResponse) {
HttpServerIO.swift:50
    public func dispatch(method: String, path: String) -> ([String: String], HttpRequest -> HttpResponse) {
HttpServerIO.swift:51
        return ([:], { _ in HttpResponse.NotFound })
HttpServerIO.swift:99
    private func respond(socket: Socket, response: HttpResponse, keepAlive: Bool) throws -> Bool {
{ 0067 0068 case SwitchProtocols
HttpHandlers+WebSockets.swift:43
            return HttpResponse.SwitchProtocols(headers, protocolSessionClosure)
HttpResponse.swift:77
        case .SwitchProtocols(_, _)   : return 101
HttpResponse.swift:93
        case .SwitchProtocols(_, _)    : return "Switching Protocols"
HttpResponse.swift:110
        case .SwitchProtocols(let switchHeaders, _):
HttpResponse.swift:144
        case SwitchProtocols(_, let handler) : return handler
([String: String], Socket -> Void) 0069 case OK
DemoServer.swift:30
        return .OK(.Html(listPage))
DemoServer.swift:33
    server["/magic"] = { .OK(.Html("You asked for " + $0.path)) }
DemoServer.swift:48
        return .OK(.Html("<h3>Address: \(r.address)</h3><h3>Url:</h3> \(r.path)<h3>Method:</h3>\(r.method)<h3>Headers:</h3>\(headersInfo)<h3>Query:</h3>\(queryParamsInfo)<h3>Path params:</h3>\(pathParamsInfo)"))
DemoServer.swift:65
        return HttpResponse.OK(.Html(response))
DemoServer.swift:79
        return HttpResponse.OK(.Html(formFields.map({ "\($0.0) = \($0.1)" }).joinWithSeparator("<br>")))
DemoServer.swift:83
        return .OK(.Html("<center><h2>Hello Swift</h2><img src=\"https://devimages.apple.com.edgekey.net/swift/images/swift-hero_2x.png\"/><br></center>"))
DemoServer.swift:92
        return .OK(.Json(jsonObject))
DemoServer.swift:102
        return .OK(.Html(longResponse))
DemoServer.swift:106
        return .OK(.Html(r.path))
HttpHandlers+Files.swift:112
                    return HttpResponse.OK(.Html(response))
HttpResponse.swift:78
        case .OK(_)                   : return 200
HttpResponse.swift:94
        case .OK(_)                    : return "OK"
HttpResponse.swift:114
        case .OK(let body):
HttpResponse.swift:135
        case .OK(let body)             : return body.content()
(HttpResponseBody), Created
HttpResponse.swift:79
        case .Created                 : return 201
HttpResponse.swift:95
        case .Created                  : return "Created"
, Accepted
HttpResponse.swift:80
        case .Accepted                : return 202
HttpResponse.swift:96
        case .Accepted                 : return "Accepted"
0070 case MovedPermanently
DemoServer.swift:96
        return .MovedPermanently("http://www.google.com")
HttpResponse.swift:81
        case .MovedPermanently        : return 301
HttpResponse.swift:97
        case .MovedPermanently         : return "Moved Permanently"
HttpResponse.swift:120
        case .MovedPermanently(let location):
(String) 0071 case BadRequest
HttpHandlers+Files.swift:49
                    return .BadRequest(.Text("Invalid value of 'Range' header: \(r.headers["range"])"))
HttpHandlers+Files.swift:61
                    return .BadRequest(.Text("Invalid value of 'Range' header: \(r.headers["range"])"))
HttpHandlers+WebSockets.swift:17
                return .BadRequest(.Text("Invalid value of 'Upgrade' header: \(r.headers["upgrade"])"))
HttpHandlers+WebSockets.swift:20
                return .BadRequest(.Text("Invalid value of 'Connection' header: \(r.headers["connection"])"))
HttpHandlers+WebSockets.swift:23
                return .BadRequest(.Text("Invalid value of 'Sec-Websocket-Key' header: \(r.headers["sec-websocket-key"])"))
HttpResponse.swift:82
        case .BadRequest(_)           : return 400
HttpResponse.swift:98
        case .BadRequest(_)            : return "Bad Request"
HttpResponse.swift:136
        case .BadRequest(let body)     : return body?.content() ?? (-1, nil)
(HttpResponseBody?), Unauthorized
HttpResponse.swift:83
        case .Unauthorized            : return 401
HttpResponse.swift:99
        case .Unauthorized             : return "Unauthorized"
, Forbidden
HttpResponse.swift:84
        case .Forbidden               : return 403
HttpResponse.swift:100
        case .Forbidden                : return "Forbidden"
, NotFound
DemoServer.swift:57
        return .NotFound
DemoServer.swift:74
        return .NotFound
HttpHandlers+Files.swift:15
                return .NotFound
HttpHandlers+Files.swift:19
                return .NotFound
HttpHandlers+Files.swift:37
                return HttpResponse.NotFound
HttpHandlers+Files.swift:43
                return HttpResponse.NotFound
HttpHandlers+Files.swift:98
                return HttpResponse.NotFound
HttpHandlers+Files.swift:104
                return HttpResponse.NotFound
HttpHandlers+Files.swift:114
                    return HttpResponse.NotFound
HttpHandlers+Files.swift:122
                return HttpResponse.NotFound
HttpResponse.swift:85
        case .NotFound                : return 404
HttpResponse.swift:101
        case .NotFound                 : return "Not Found"
HttpServerIO.swift:51
        return ([:], { _ in HttpResponse.NotFound })
0072 case InternalServerError
HttpResponse.swift:86
        case .InternalServerError     : return 500
HttpResponse.swift:102
        case .InternalServerError      : return "Internal Server Error"
0073 case RAW
DemoServer.swift:55
            return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
DemoServer.swift:72
            return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
DemoServer.swift:87
        return HttpResponse.RAW(200, "OK", ["XXX-Custom-Header": "value"], { $0.write([UInt8]("test".utf8)) })
DemoServer.swift:110
        return HttpResponse.RAW(200, "OK", nil, { w in
HttpHandlers+Files.swift:21
            return .RAW(200, "OK", [:], { writer in
HttpHandlers+Files.swift:70
                    return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
HttpHandlers+Files.swift:77
                    return HttpResponse.RAW(416, "Requested range not satisfiable", nil, nil)
HttpHandlers+Files.swift:86
                return HttpResponse.RAW(206, "Partial Content", headers, { $0.write(content) })
HttpHandlers+Files.swift:90
                return HttpResponse.RAW(200, "OK", nil, { $0.write(content) })
HttpHandlers+Files.swift:120
                    return HttpResponse.RAW(200, "OK", nil, { $0.write(array) })
HttpResponse.swift:87
        case .RAW(let code, _ , _, _) : return code
HttpResponse.swift:103
        case .RAW(_, let phrase, _, _) : return phrase
HttpResponse.swift:122
        case .RAW(_, _, let rawHeaders, _):
HttpResponse.swift:137
        case .RAW(_, _, _, let writer) : return (-1, writer)
(Int, String, [String:String]?, (HttpResponseBodyWriter -> Void)? ) 0074 0075 func statusCode
HttpResponse.swift:162
    return inLeft.statusCode() == inRight.statusCode()
HttpResponse.swift:162
    return inLeft.statusCode() == inRight.statusCode()
HttpServerIO.swift:100
        try socket.writeUTF8("HTTP/1.1 \(response.statusCode()) \(response.reasonPhrase())\r\n")
() -> Int { 0076 switch self { 0077 case .SwitchProtocols(_, _) : return 101 0078 case .OK(_) : return 200 0079 case .Created : return 201 0080 case .Accepted : return 202 0081 case .MovedPermanently : return 301 0082 case .BadRequest(_) : return 400 0083 case .Unauthorized : return 401 0084 case .Forbidden : return 403 0085 case .NotFound : return 404 0086 case .InternalServerError : return 500 0087 case .RAW(let code, _ , _, _) : return code 0088 } 0089 } 0090 0091 func reasonPhrase
HttpServerIO.swift:100
        try socket.writeUTF8("HTTP/1.1 \(response.statusCode()) \(response.reasonPhrase())\r\n")
() -> String { 0092 switch self { 0093 case .SwitchProtocols(_, _) : return "Switching Protocols" 0094 case .OK(_) : return "OK" 0095 case .Created : return "Created" 0096 case .Accepted : return "Accepted" 0097 case .MovedPermanently : return "Moved Permanently" 0098 case .BadRequest(_) : return "Bad Request" 0099 case .Unauthorized : return "Unauthorized" 0100 case .Forbidden : return "Forbidden" 0101 case .NotFound : return "Not Found" 0102 case .InternalServerError : return "Internal Server Error" 0103 case .RAW(_, let phrase, _, _) : return phrase 0104 } 0105 } 0106 0107 func headers
HttpServerIO.swift:112
        for (name, value) in response.headers() {
() -> [String: String] { 0108 var headers = ["Server" : "Swifter \(HttpServer.VERSION)"] 0109 switch self { 0110 case .SwitchProtocols(let switchHeaders, _): 0111 for (key, value) in switchHeaders { 0112 headers[key] = value 0113 } 0114 case .OK(let body): 0115 switch body { 0116 case .Json(_) : headers["Content-Type"] = "application/json" 0117 case .Html(_) : headers["Content-Type"] = "text/html" 0118 default:break 0119 } 0120 case .MovedPermanently(let location): 0121 headers["Location"] = location 0122 case .RAW(_, _, let rawHeaders, _): 0123 if let rawHeaders = rawHeaders { 0124 for (k, v) in rawHeaders { 0125 headers.updateValue(v, forKey: k) 0126 } 0127 } 0128 default:break 0129 } 0130 return headers 0131 } 0132 0133 func content
HttpServerIO.swift:102
        let content = response.content()
() -> (length: Int, write: (HttpResponseBodyWriter throws -> Void)?) { 0134 switch self { 0135 case .OK(let body) : return body.content() 0136 case .BadRequest(let body) : return body?.content() ?? (-1, nil) 0137 case .RAW(_, _, _, let writer) : return (-1, writer) 0138 default : return (-1, nil) 0139 } 0140 } 0141 0142 func socketSession
HttpServerIO.swift:70
            if let session = response.socketSession() {
() -> (Socket -> Void)? { 0143 switch self { 0144 case SwitchProtocols(_, let handler) : return handler 0145 default: return nil 0146 } 0147 } 0148 } 0149 0150 /** 0151 Makes it possible to compare handler responses with '==', but 0152 ignores any associated values. This should generally be what 0153 you want. E.g.: 0154 0155 let resp = handler(updatedRequest) 0156 if resp == .NotFound { 0157 print("Client requested not found: \(request.url)") 0158 } 0159 */ 0160 0161 func ==(inLeft: HttpResponse, inRight: HttpResponse) -> Bool { 0162 return inLeft.statusCode() == inRight.statusCode() 0163 } 0164 0165