0001 // 0002 // HttpRequest.swift 0003 // Swifter 0004 // 0005 // Copyright (c) 2014-2016 Damian KoĊakowski. All rights reserved. 0006 // 0007 0008 import Foundation 0009 0010 public class HttpRequest{ 0011 0012 public var path
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:95 public class func directoryBrowser(dir: String) -> (HttpRequest -> HttpResponse) {HttpHandlers+WebSockets.swift:14 _ binary: ((WebSocketSession, [UInt8]) -> Void)?) -> (HttpRequest -> HttpResponse) {HttpParser.swift:22 public func readHttpRequest(socket: Socket) throws -> HttpRequest {HttpParser.swift:28 let request = HttpRequest()HttpRequest.swift:129 if value > HttpRequest.CR {HttpRequest.swift:132 if value == HttpRequest.NL {HttpRequest.swift:151 if body.last == HttpRequest.NL {HttpRequest.swift:153 if body.last == HttpRequest.CR {HttpRouter.swift:14 var handler: (HttpRequest -> HttpResponse)? = nilHttpRouter.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) {: String = "" 0013 public var queryParams
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:106 return .OK(.Html(r.path))HttpHandlers+Files.swift:110 response += files.map({ "<tr><td><a href=\"\(r.path)/\($0)\">\($0)</a></td></tr>"}).joinWithSeparator("")HttpParser.swift:30 request.path = statusLineTokens[1]HttpParser.swift:31 request.queryParams = extractQueryParams(request.path)HttpServerIO.swift:59 let (params, handler) = self.dispatch(request.method, path: request.path): [(String, String)] = [] 0014 public var method
DemoServer.swift:41 for (name, value) in r.queryParams {HttpParser.swift:31 request.queryParams = extractQueryParams(request.path): String = "" 0015 public var headers
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)"))HttpParser.swift:29 request.method = statusLineTokens[0]HttpServerIO.swift:59 let (params, handler) = self.dispatch(request.method, path: request.path): [String: String] = [:] 0016 public var body
DemoServer.swift:37 for (name, value) in r.headers {HttpHandlers+Files.swift:46 if let rangeHeader = r.headers["range"] {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:22 guard let secWebSocketKey = r.headers["sec-websocket-key"] else {HttpHandlers+WebSockets.swift:23 return .BadRequest(.Text("Invalid value of 'Sec-Websocket-Key' header: \(r.headers["sec-websocket-key"])"))HttpParser.swift:32 request.headers = try readHeaders(socket)HttpParser.swift:33 if let contentLength = request.headers["content-length"], let contentLengthValue = Int(contentLength) {HttpRequest.swift:21 guard let headerValue = headers[headerName] else {HttpRequest.swift:28 guard let contentTypeHeader = headers["content-type"] else {HttpRequest.swift:76 guard let contentTypeHeader = headers["content-type"] else {HttpServerIO.swift:63 var keepConnection = parser.supportsKeepAlive(request.headers): [UInt8] = [] 0017 public var address
HttpParser.swift:34 request.body = try readBody(socket, size: contentLengthValue)HttpRequest.swift:35 return String.fromUInt8(body).split("&").map { param -> (String, String) inHttpRequest.swift:91 return parseMultiPartFormData(body, boundary: "--\(boundary)"): String? = "" 0018 public var params
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)"))HttpServerIO.swift:60 request.address = address: [String: String] = [:] 0019 0020 public func hasTokenForHeader
DemoServer.swift:45 for token in r.params {HttpHandlers+Files.swift:14 guard let fileRelativePath = r.params.first else {HttpHandlers+Files.swift:36 guard let localPath = r.params.first else {HttpHandlers+Files.swift:97 guard let (_, value) = r.params.first else {HttpServerIO.swift:61 request.params = params;(headerName: String, token: String) -> Bool { 0021 guard let headerValue = headers[headerName] else { 0022 return false 0023 } 0024 return headerValue.split(",").filter({ $0.trim().lowercaseString == token }).count > 0 0025 } 0026 0027 public func parseUrlencodedForm
HttpHandlers+WebSockets.swift:16 guard r.hasTokenForHeader("upgrade", token: "websocket") else {HttpHandlers+WebSockets.swift:19 guard r.hasTokenForHeader("connection", token: "upgrade") else {() -> [(String, String)] { 0028 guard let contentTypeHeader = headers["content-type"] else { 0029 return [] 0030 } 0031 let contentTypeHeaderTokens = contentTypeHeader.split(";").map { $0.trim() } 0032 guard let contentType = contentTypeHeaderTokens.first where contentType == "application/x-www-form-urlencoded" else { 0033 return [] 0034 } 0035 return String.fromUInt8(body).split("&").map { param -> (String, String) in 0036 let tokens = param.split("=") 0037 if let name = tokens.first, value = tokens.last where tokens.count == 2 { 0038 return (name.replace("+", " ").removePercentEncoding(), 0039 value.replace("+", " ").removePercentEncoding()) 0040 } 0041 return ("","") 0042 } 0043 } 0044 0045 public struct MultiPart
DemoServer.swift:78 let formFields = r.parseUrlencodedForm(){ 0046 0047 public let headers
HttpRequest.swift:75 public func parseMultiPartFormData() -> [MultiPart] {HttpRequest.swift:96 private func parseMultiPartFormData(data: [UInt8], boundary: String) -> [MultiPart] {HttpRequest.swift:98 var result = [MultiPart]()HttpRequest.swift:105 private func nextMultiPart(inout generator: IndexingGenerator<[UInt8]>, boundary: String, isFirst: Bool) -> MultiPart? {HttpRequest.swift:123 return MultiPart(headers: headers, body: body): [String: String] 0048 public let body
HttpRequest.swift:59 return headers.reduce([String]()) { (combined, header: (key: String, value: String)) -> [String] in: [UInt8] 0049 0050 public var name
DemoServer.swift:63 response += "Name: \(multipart.name) File name: \(multipart.fileName) Size: \(multipart.body.count)<br>": String? { 0051 return valueFor("content-disposition", parameter: "name")?.unquote() 0052 } 0053 0054 public var fileName
DemoServer.swift:63 response += "Name: \(multipart.name) File name: \(multipart.fileName) Size: \(multipart.body.count)<br>": String? { 0055 return valueFor("content-disposition", parameter: "filename")?.unquote() 0056 } 0057 0058 private func valueFor
DemoServer.swift:63 response += "Name: \(multipart.name) File name: \(multipart.fileName) Size: \(multipart.body.count)<br>"(headerName: String, parameter: String) -> String? { 0059 return headers.reduce([String]()) { (combined, header: (key: String, value: String)) -> [String] in 0060 guard header.key == headerName else { 0061 return combined 0062 } 0063 let headerValueParams = header.value.split(";").map { $0.trim() } 0064 return headerValueParams.reduce(combined, combine: { (results, token) -> [String] in 0065 let parameterTokens = token.split(1, separator: "=") 0066 if parameterTokens.first == parameter, let value = parameterTokens.last { 0067 return results + [value] 0068 } 0069 return results 0070 }) 0071 }.first 0072 } 0073 } 0074 0075 public func parseMultiPartFormData
HttpRequest.swift:51 return valueFor("content-disposition", parameter: "name")?.unquote()HttpRequest.swift:55 return valueFor("content-disposition", parameter: "filename")?.unquote()() -> [MultiPart] { 0076 guard let contentTypeHeader = headers["content-type"] else { 0077 return [] 0078 } 0079 let contentTypeHeaderTokens = contentTypeHeader.split(";").map { $0.trim() } 0080 guard let contentType = contentTypeHeaderTokens.first where contentType == "multipart/form-data" else { 0081 return [] 0082 } 0083 var boundary: String? = nil 0084 contentTypeHeaderTokens.forEach({ 0085 let tokens = $0.split("=") 0086 if let key = tokens.first where key == "boundary" && tokens.count == 2 { 0087 boundary = tokens.last 0088 } 0089 }) 0090 if let boundary = boundary where boundary.utf8.count > 0 { 0091 return parseMultiPartFormData(body, boundary: "--\(boundary)") 0092 } 0093 return [] 0094 } 0095 0096 private func parseMultiPartFormData
DemoServer.swift:62 for multipart in r.parseMultiPartFormData() {(data: [UInt8], boundary: String) -> [MultiPart] { 0097 var generator = data.generate() 0098 var result = [MultiPart]() 0099 while let part = nextMultiPart(&generator, boundary: boundary, isFirst: result.isEmpty) { 0100 result.append(part) 0101 } 0102 return result 0103 } 0104 0105 private func nextMultiPart
HttpRequest.swift:91 return parseMultiPartFormData(body, boundary: "--\(boundary)")(inout generator: IndexingGenerator<[UInt8]>, boundary: String, isFirst: Bool) -> MultiPart? { 0106 if isFirst { 0107 guard nextMultiPartLine(&generator) == boundary else { 0108 return nil 0109 } 0110 } else { 0111 nextMultiPartLine(&generator) 0112 } 0113 var headers = [String: String]() 0114 while let line = nextMultiPartLine(&generator) where !line.isEmpty { 0115 let tokens = line.split(":") 0116 if let name = tokens.first, value = tokens.last where tokens.count == 2 { 0117 headers[name.lowercaseString] = value.trim() 0118 } 0119 } 0120 guard let body = nextMultiPartBody(&generator, boundary: boundary) else { 0121 return nil 0122 } 0123 return MultiPart(headers: headers, body: body) 0124 } 0125 0126 private func nextMultiPartLine
HttpRequest.swift:99 while let part = nextMultiPart(&generator, boundary: boundary, isFirst: result.isEmpty) {(inout generator: IndexingGenerator<[UInt8]>) -> String? { 0127 var result = String() 0128 while let value = generator.next() { 0129 if value > HttpRequest.CR { 0130 result.append(Character(UnicodeScalar(value))) 0131 } 0132 if value == HttpRequest.NL { 0133 break 0134 } 0135 } 0136 return result 0137 } 0138 0139 static let CR
HttpRequest.swift:107 guard nextMultiPartLine(&generator) == boundary else {HttpRequest.swift:111 nextMultiPartLine(&generator)HttpRequest.swift:114 while let line = nextMultiPartLine(&generator) where !line.isEmpty {= UInt8(13) 0140 static let NL
HttpRequest.swift:129 if value > HttpRequest.CR {HttpRequest.swift:153 if body.last == HttpRequest.CR {= UInt8(10) 0141 0142 private func nextMultiPartBody
HttpRequest.swift:132 if value == HttpRequest.NL {HttpRequest.swift:151 if body.last == HttpRequest.NL {(inout generator: IndexingGenerator<[UInt8]>, boundary: String) -> [UInt8]? { 0143 var body = [UInt8]() 0144 let boundaryArray = [UInt8](boundary.utf8) 0145 var matchOffset = 0; 0146 while let x = generator.next() { 0147 matchOffset = ( x == boundaryArray[matchOffset] ? matchOffset + 1 : 0 ) 0148 body.append(x) 0149 if matchOffset == boundaryArray.count { 0150 body.removeRange(Range<Int>(body.count-matchOffset ..< body.count)) 0151 if body.last == HttpRequest.NL { 0152 body.removeLast() 0153 if body.last == HttpRequest.CR { 0154 body.removeLast() 0155 } 0156 } 0157 return body 0158 } 0159 } 0160 return nil 0161 } 0162 } 0163
HttpRequest.swift:120 guard let body = nextMultiPartBody(&generator, boundary: boundary) else {