1
0
Эх сурвалжийг харах

Added "name" and "filename" properties to Multipart class.

Damian Kołakowski 10 жил өмнө
parent
commit
01525e30d0

+ 5 - 2
Sources/DemoServer.swift

@@ -56,8 +56,11 @@ public func demoServer(publicDir: String?) -> HttpServer {
     }
     
     server.POST["/upload"] = { r in
-        let formFields = r.parseMultiPartFormData()
-        return HttpResponse.OK(.Html(formFields.map({ String.fromUInt8($0.body) }).joinWithSeparator("<br>")))
+        var response = ""
+        for multipart in r.parseMultiPartFormData() {
+            response += "Name: \(multipart.name) File name: \(multipart.fileName) Size: \(multipart.body.count)<br>"
+        }
+        return HttpResponse.OK(.Html(response))
     }
     
     server.GET["/login"] = { r in

+ 7 - 11
Sources/HttpParser.swift

@@ -37,15 +37,12 @@ class HttpParser {
         guard let query = url.split("?").last else {
             return []
         }
-        return query.split("&").map { (param: String) -> (String, String) in
-            let tokens = param.split("=")
-            guard let name = tokens.first else {
-                return ("", "")
+        return query.split("&").reduce([(String, String)]()) { (c, s) -> [(String, String)] in
+            let tokens = s.split(1, separator: "=")
+            if let name = tokens.first, value = tokens.last {
+                return c + [(name.removePercentEncoding(), value.removePercentEncoding())]
             }
-            guard let value = tokens.last where tokens.count > 1 else {
-                return (name.removePercentEncoding(), "")
-            }
-            return (name.removePercentEncoding(), value.removePercentEncoding())
+            return c
         }
     }
     
@@ -66,9 +63,8 @@ class HttpParser {
             if headerLine.isEmpty {
                 return requestHeaders
             }
-            let headerTokens = headerLine.split(":")
-            if let name = headerTokens.first where headerTokens.count >= 2 {
-                let value = headerTokens.dropFirst().joinWithSeparator(":")
+            let headerTokens = headerLine.split(1, separator: ":")
+            if let name = headerTokens.first, value = headerTokens.last {
                 requestHeaders[name.lowercaseString] = value.trim()
             }
         } while true

+ 25 - 0
Sources/HttpRequest.swift

@@ -35,8 +35,33 @@ public class HttpRequest {
     }
     
     public struct MultiPart {
+        
         public let headers: [String: String]
         public let body: [UInt8]
+        
+        public var name: String? {
+            return valueFor("content-disposition", parameterName: "name")
+        }
+        
+        public var fileName: String? {
+            return valueFor("content-disposition", parameterName: "filename")
+        }
+        
+        private func valueFor(headerName: String, parameterName: String) -> String? {
+            return headers.reduce([String]()) { (currentResults: [String], header: (key: String, value: String)) -> [String] in
+                guard header.key == headerName else {
+                    return currentResults
+                }
+                let headerValueParams = header.value.split(";").map { $0.trim() }
+                return headerValueParams.reduce(currentResults, combine: { (results:[String], token: String) -> [String] in
+                    let parameterTokens = token.split(1, separator: "=")
+                    if parameterTokens.first == parameterName, let value = parameterTokens.last {
+                        return results + [value]
+                    }
+                    return results
+                })
+            }.first
+        }
     }
     
     public func parseMultiPartFormData() -> [MultiPart] {

+ 4 - 0
Sources/String+Misc.swift

@@ -12,6 +12,10 @@ extension String {
         return self.characters.split { $0 == separator }.map(String.init)
     }
     
+    public func split(maxSplit: Int = Int.max, separator: Character) -> [String] {
+        return self.characters.split(maxSplit) { $0 == separator }.map(String.init)
+    }
+    
     public func replace(old: Character, new: Character) -> String {
         var buffer = [Character]()
         self.characters.forEach { buffer.append($0 == old ? new : $0) }

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


+ 80 - 0
Swifter.xcodeproj/xcuserdata/damiankolakowski.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -1502,5 +1502,85 @@
             landmarkType = "5">
          </BreakpointContent>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Sources/DemoServer.swift"
+            timestampString = "473259839.54395"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "58"
+            endingLineNumber = "58"
+            landmarkName = "demoServer(_:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Sources/HttpRequest.swift"
+            timestampString = "473259865.519181"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "51"
+            endingLineNumber = "51"
+            landmarkName = "valueFor(_:parameterName:)"
+            landmarkType = "5">
+            <Locations>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "Swifter.HttpRequest.MultiPart.(valueFor in _63BD12A9F49458E70E4764A8152B4E3A) (Swifter.HttpRequest.MultiPart)(Swift.String, parameterName : Swift.String) -&gt; Swift.Optional&lt;Swift.String&gt;"
+                  moduleName = "Swifter"
+                  usesParentBreakpointCondition = "Yes"
+                  urlString = "file:///Users/damiankolakowski/Desktop/swifter/Sources/HttpRequest.swift"
+                  timestampString = "473259865.536405"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "51"
+                  endingLineNumber = "51"
+                  offsetFromSymbolStart = "78">
+               </Location>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "Swifter.HttpRequest.MultiPart.((valueFor in _63BD12A9F49458E70E4764A8152B4E3A) (Swifter.HttpRequest.MultiPart) -&gt; (Swift.String, parameterName : Swift.String) -&gt; Swift.Optional&lt;Swift.String&gt;).(closure #1)"
+                  moduleName = "Swifter"
+                  usesParentBreakpointCondition = "Yes"
+                  urlString = "file:///Users/damiankolakowski/Desktop/swifter/Sources/HttpRequest.swift"
+                  timestampString = "473259865.536633"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "52"
+                  endingLineNumber = "52"
+                  offsetFromSymbolStart = "117">
+               </Location>
+            </Locations>
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Sources/HttpRequest.swift"
+            timestampString = "473259872.823604"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "52"
+            endingLineNumber = "52"
+            landmarkName = "valueFor(_:parameterName:)"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
 </Bucket>