Преглед изворни кода

[/login] demo endpoints work again ( fixed percent encoding -> UTF8 )
Changed HttpRquest::body's type to [UInt8].

Damian Kołakowski пре 10 година
родитељ
комит
30882a0400

+ 22 - 0
Sources/Swifter/DemoServer.swift

@@ -39,6 +39,28 @@ public func demoServer(publicDir: String?) -> HttpServer {
         return .OK(.Html("<h3>Address: \(r.address)</h3><h3>Url:</h3> \(r.url)<h3>Method: \(r.method)</h3><h3>Headers:</h3>\(headersInfo)<h3>Query:</h3>\(queryParamsInfo)<h3>Path params:</h3>\(pathParamsInfo)"))
         return .OK(.Html("<h3>Address: \(r.address)</h3><h3>Url:</h3> \(r.url)<h3>Method: \(r.method)</h3><h3>Headers:</h3>\(headersInfo)<h3>Query:</h3>\(queryParamsInfo)<h3>Path params:</h3>\(pathParamsInfo)"))
     }
     }
     
     
+    server["/login"] = { r in
+        switch r.method.uppercaseString {
+        case "GET":
+            if let rootDir = publicDir {
+                if let html = NSData(contentsOfFile:"\(rootDir)/login.html") {
+                    var array = [UInt8](count: html.length, repeatedValue: 0)
+                    html.getBytes(&array, length: html.length)
+                    return HttpResponse.RAW(200, "OK", nil, array)
+                } else {
+                    return .NotFound
+                }
+            }
+        case "POST":
+            let formFields = r.parseForm()
+            return HttpResponse.OK(.Html(formFields.map({ "\($0.0) = \($0.1)" }).joinWithSeparator("<br>")))
+        default:
+            return .NotFound
+        }
+        return .NotFound
+
+    }
+    
     server["/demo"] = { r in
     server["/demo"] = { r in
         return .OK(.Html("<center><h2>Hello Swift</h2><img src=\"https://devimages.apple.com.edgekey.net/swift/images/swift-hero_2x.png\"/><br></center>"))
         return .OK(.Html("<center><h2>Hello Swift</h2><img src=\"https://devimages.apple.com.edgekey.net/swift/images/swift-hero_2x.png\"/><br></center>"))
     }
     }

+ 3 - 3
Sources/Swifter/HttpParser.swift

@@ -49,15 +49,15 @@ class HttpParser {
         }
         }
     }
     }
     
     
-    private func readBody(socket: Socket, size: Int) throws -> String {
-        var body = ""
+    private func readBody(socket: Socket, size: Int) throws -> [UInt8] {
+        var body = [UInt8]()
         var counter = 0
         var counter = 0
         while counter < size {
         while counter < size {
             let c = socket.read()
             let c = socket.read()
             if c < 0 {
             if c < 0 {
                 throw HttpParserError.ReadBodyFailed(String.fromCString(UnsafePointer(strerror(errno))) ?? "Error: \(errno)")
                 throw HttpParserError.ReadBodyFailed(String.fromCString(UnsafePointer(strerror(errno))) ?? "Error: \(errno)")
             }
             }
-            body.append(UnicodeScalar(c))
+            body.append(UInt8(c))
             counter++
             counter++
         }
         }
         return body
         return body

+ 2 - 2
Sources/Swifter/HttpRequest.swift

@@ -12,13 +12,13 @@ public struct HttpRequest {
     public let urlParams: [(String, String)]
     public let urlParams: [(String, String)]
     public let method: String
     public let method: String
     public let headers: [String: String]
     public let headers: [String: String]
-    public let body: String?
+    public let body: [UInt8]?
     public var address: String?
     public var address: String?
     public var params: [String: String]
     public var params: [String: String]
     
     
     public func parseForm() -> [(String, String)] {
     public func parseForm() -> [(String, String)] {
         if let body = body {
         if let body = body {
-            return body.split("&").map { (param: String) -> (String, String) in
+            return UInt8ArrayToUTF8String(body).split("&").map { (param: String) -> (String, String) in
                 let tokens = param.split("=")
                 let tokens = param.split("=")
                 if tokens.count >= 2 {
                 if tokens.count >= 2 {
                     let key = tokens[0].replace("+", new: " ").removePercentEncoding()
                     let key = tokens[0].replace("+", new: " ").removePercentEncoding()

+ 4 - 10
Sources/Swifter/HttpResponse.swift

@@ -141,19 +141,13 @@ public enum HttpResponse {
     }
     }
     
     
     func headers() -> [String: String] {
     func headers() -> [String: String] {
-        var headers = [String:String]()
-        headers["Server"] = "Swifter \(HttpServer.VERSION)"
+        var headers = ["Server" : "Swifter \(HttpServer.VERSION)"]
         switch self {
         switch self {
         case .OK(let body):
         case .OK(let body):
             switch body {
             switch body {
             case .Json(_)   : headers["Content-Type"] = "application/json"
             case .Json(_)   : headers["Content-Type"] = "application/json"
             case .Plist(_)  : headers["Content-Type"] = "application/xml"
             case .Plist(_)  : headers["Content-Type"] = "application/xml"
             case .Xml(_)    : headers["Content-Type"] = "application/xml"
             case .Xml(_)    : headers["Content-Type"] = "application/xml"
-                // 'application/xml' or 'text/xml' ?
-                // From RFC: http://www.rfc-editor.org/rfc/rfc3023.txt - "If an XML document -- that is, the unprocessed,
-                // source XML document -- is readable by casual users, text/xml is preferable to application/xml.
-                // MIME user agents (and web user agents) that do not have explicit support for text/xml will treat it as text/plain,
-            // for example, by displaying the XML MIME entity as plain text.
             case .Html(_)   : headers["Content-Type"] = "text/html"
             case .Html(_)   : headers["Content-Type"] = "text/html"
             default:break
             default:break
             }
             }
@@ -171,9 +165,9 @@ public enum HttpResponse {
     
     
     func body() -> [UInt8]? {
     func body() -> [UInt8]? {
         switch self {
         switch self {
-        case .OK(let body)          : return body.data()
-        case .RAW(_, _, _, let data)  : return data
-        default                     : return nil
+        case .OK(let body)           : return body.data()
+        case .RAW(_, _, _, let data) : return data
+        default                      : return nil
         }
         }
     }
     }
 }
 }

+ 38 - 20
Sources/Swifter/String+Misc.swift

@@ -4,6 +4,8 @@
 //  Copyright (c) 2014 Damian Kołakowski. All rights reserved.
 //  Copyright (c) 2014 Damian Kołakowski. All rights reserved.
 //
 //
 
 
+import Foundation
+
 extension String {
 extension String {
 
 
     public func split(separator: Character) -> [String] {
     public func split(separator: Character) -> [String] {
@@ -25,56 +27,72 @@ extension String {
     
     
     public func removePercentEncoding() -> String {
     public func removePercentEncoding() -> String {
         var scalars = self.unicodeScalars
         var scalars = self.unicodeScalars
-        var buffer = [Character]()
+        var output = ""
+        var bytesBuffer = [UInt8]()
         while let scalar = scalars.popFirst() {
         while let scalar = scalars.popFirst() {
-            guard scalar.isASCII() else {
-                buffer.append(Character(scalar))
-                continue
-            }
             if scalar == "%" {
             if scalar == "%" {
                 let first = scalars.popFirst()
                 let first = scalars.popFirst()
                 let secon = scalars.popFirst()
                 let secon = scalars.popFirst()
                 if let first = unicodeScalarToUInt32Hex(first), secon = unicodeScalarToUInt32Hex(secon) {
                 if let first = unicodeScalarToUInt32Hex(first), secon = unicodeScalarToUInt32Hex(secon) {
-                    buffer.append(Character(UnicodeScalar(first*16+secon)))
+                    bytesBuffer.append(first*16+secon)
                 } else {
                 } else {
-                    if let first = first {
-                        buffer.append(Character(first))
-                    }
-                    if let secon = secon {
-                        buffer.append(Character(secon))
+                    if !bytesBuffer.isEmpty {
+                        output.appendContentsOf(UInt8ArrayToUTF8String(bytesBuffer))
+                        bytesBuffer.removeAll()
                     }
                     }
+                    if let first = first { output.append(Character(first)) }
+                    if let secon = secon { output.append(Character(secon)) }
                 }
                 }
             } else {
             } else {
-                buffer.append(Character(scalar))
+                if !bytesBuffer.isEmpty {
+                    output.appendContentsOf(UInt8ArrayToUTF8String(bytesBuffer))
+                    bytesBuffer.removeAll()
+                }
+                output.append(Character(scalar))
             }
             }
         }
         }
-        return String(buffer)
+        if !bytesBuffer.isEmpty {
+            output.appendContentsOf(UInt8ArrayToUTF8String(bytesBuffer))
+            bytesBuffer.removeAll()
+        }
+        return output
     }
     }
     
     
-    private func unicodeScalarToUInt32Whitespace(x: UnicodeScalar?) -> UInt32? {
+    private func unicodeScalarToUInt32Whitespace(x: UnicodeScalar?) -> UInt8? {
         if let x = x {
         if let x = x {
             if x.value >= 9 && x.value <= 13 {
             if x.value >= 9 && x.value <= 13 {
-                return x.value
+                return UInt8(x.value)
             }
             }
             if x.value == 32 {
             if x.value == 32 {
-                return x.value
+                return UInt8(x.value)
             }
             }
         }
         }
         return nil
         return nil
     }
     }
     
     
-    private func unicodeScalarToUInt32Hex(x: UnicodeScalar?) -> UInt32? {
+    private func unicodeScalarToUInt32Hex(x: UnicodeScalar?) -> UInt8? {
         if let x = x {
         if let x = x {
             if x.value >= 48 && x.value <= 57 {
             if x.value >= 48 && x.value <= 57 {
-                return x.value - 48
+                return UInt8(x.value) - 48
             }
             }
             if x.value >= 97 && x.value <= 102 {
             if x.value >= 97 && x.value <= 102 {
-                return x.value - 97
+                return UInt8(x.value) - 87
             }
             }
             if x.value >= 65 && x.value <= 70 {
             if x.value >= 65 && x.value <= 70 {
-                return x.value - 65
+                return UInt8(x.value) - 55
             }
             }
         }
         }
         return nil
         return nil
     }
     }
 }
 }
+
+public func UInt8ArrayToUTF8String(array: [UInt8]) -> String {
+    #if os(Linux)
+        return String(data: NSData(bytes: array, length: array.count), encoding: NSUTF8StringEncoding)
+    #else
+        if let s = String(data: NSData(bytes: array, length: array.count), encoding: NSUTF8StringEncoding) {
+            return s
+        }
+        return ""
+    #endif
+}

BIN
Swifter.xcodeproj/project.xcworkspace/xcuserdata/damiankolakowski.xcuserdatad/UserInterfaceState.xcuserstate


+ 103 - 7
Swifter.xcodeproj/xcuserdata/damiankolakowski.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -789,7 +789,7 @@
             ignoreCount = "0"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             continueAfterRunningActions = "No"
             filePath = "Sources/Swifter/String+Misc.swift"
             filePath = "Sources/Swifter/String+Misc.swift"
-            timestampString = "471209479.941914"
+            timestampString = "471609551.445269"
             startingColumnNumber = "9223372036854775807"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "35"
             startingLineNumber = "35"
@@ -805,11 +805,11 @@
             ignoreCount = "0"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             continueAfterRunningActions = "No"
             filePath = "Sources/Swifter/String+Misc.swift"
             filePath = "Sources/Swifter/String+Misc.swift"
-            timestampString = "471209479.941914"
+            timestampString = "471608201.621684"
             startingColumnNumber = "9223372036854775807"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "20"
-            endingLineNumber = "20"
+            startingLineNumber = "22"
+            endingLineNumber = "22"
             landmarkName = "trim()"
             landmarkName = "trim()"
             landmarkType = "5">
             landmarkType = "5">
          </BreakpointContent>
          </BreakpointContent>
@@ -826,7 +826,7 @@
             endingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "22"
             startingLineNumber = "22"
             endingLineNumber = "22"
             endingLineNumber = "22"
-            landmarkName = "select(_:)"
+            landmarkName = "unregister(_:)"
             landmarkType = "5">
             landmarkType = "5">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>
@@ -842,7 +842,7 @@
             endingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "23"
             startingLineNumber = "23"
             endingLineNumber = "23"
             endingLineNumber = "23"
-            landmarkName = "select(_:)"
+            landmarkName = "unregister(_:)"
             landmarkType = "5">
             landmarkType = "5">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>
@@ -897,7 +897,7 @@
       <BreakpointProxy
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
          <BreakpointContent
-            shouldBeEnabled = "Yes"
+            shouldBeEnabled = "No"
             ignoreCount = "0"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             continueAfterRunningActions = "No"
             filePath = "Sources/Swifter/HttpHandlers.swift"
             filePath = "Sources/Swifter/HttpHandlers.swift"
@@ -910,5 +910,101 @@
             landmarkType = "5">
             landmarkType = "5">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Sources/Swifter/HttpRequest.swift"
+            timestampString = "471608201.621684"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "24"
+            endingLineNumber = "24"
+            landmarkName = "parseForm()"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Sources/Swifter/String+Misc.swift"
+            timestampString = "471608190.467091"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "33"
+            endingLineNumber = "33"
+            landmarkName = "removePercentEncoding()"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Sources/Swifter/String+Misc.swift"
+            timestampString = "471608757.657852"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "39"
+            endingLineNumber = "39"
+            landmarkName = "removePercentEncoding()"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Sources/Swifter/String+Misc.swift"
+            timestampString = "471609952.957396"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "47"
+            endingLineNumber = "47"
+            landmarkName = "removePercentEncoding()"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Sources/Swifter/String+Misc.swift"
+            timestampString = "471609952.957396"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "47"
+            endingLineNumber = "47"
+            landmarkName = "removePercentEncoding()"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Sources/Swifter/String+Misc.swift"
+            timestampString = "471609707.295751"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "40"
+            endingLineNumber = "40"
+            landmarkName = "removePercentEncoding()"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
    </Breakpoints>
 </Bucket>
 </Bucket>