Damian Kołakowski 9 vuotta sitten
vanhempi
sitoutus
31ffd9b31f
2 muutettua tiedostoa jossa 41 lisäystä ja 12 poistoa
  1. 37 10
      Sources/HttpParser.swift
  2. 4 2
      XCode/SwifterTestsCommon/SwifterTestsHttpParser.swift

+ 37 - 10
Sources/HttpParser.swift

@@ -33,19 +33,46 @@ public class HttpParser {
     }
     
     private func extractQueryParams(_ url: String) -> [(String, String)] {
-        let tokens = url.components(separatedBy: "?")
-        guard let query = tokens.last, tokens.count >= 2 else {
+        guard let questionMark = url.characters.index(of: "?") else {
             return []
         }
-        return query.components(separatedBy: "&").reduce([(String, String)]()) { (c, s) -> [(String, String)] in
-            let tokens = s.components(separatedBy: "=")
-            let name = tokens.first?.removingPercentEncoding
-            let value = tokens.count > 1 ? (tokens.last?.removingPercentEncoding ?? "") : ""
-            if let nameFound = name {
-                return c + [(nameFound, value)]
-            }
-            return c
+        let queryStart = url.characters.index(after: questionMark)
+        guard url.endIndex > queryStart else {
+            return []
+        }
+        let query = String(url.characters[queryStart..<url.endIndex])
+        return query.components(separatedBy: "&")
+            .reduce([(String, String)]()) { (c, s) -> [(String, String)] in
+                guard let nameEndIndex = s.characters.index(of: "=") else {
+                    return c
+                }
+                guard let name = String(s.characters[s.startIndex..<nameEndIndex]).removingPercentEncoding else {
+                    return c
+                }
+                let valueStartIndex = s.index(nameEndIndex, offsetBy: 1)
+                guard valueStartIndex < s.endIndex else {
+                    return c + [(name, "")]
+                }
+                guard let value = String(s.characters[valueStartIndex..<s.endIndex]).removingPercentEncoding else {
+                    return c + [(name, "")]
+                }
+                return c + [(name, value)]
         }
+        
+        
+//        let tokens = url.components(separatedBy: "?")
+//        guard let query = tokens.last, tokens.count >= 2 else {
+//            return []
+//        }
+//        return query.components(separatedBy: "&").reduce([(String, String)]()) { (c, s) -> [(String, String)] in
+//            let tokens = s.components(separatedBy: "=")
+//            let name = tokens.first?.removingPercentEncoding
+//            let value = tokens.count > 1 ? (tokens.last?.removingPercentEncoding ?? "") : ""
+//            if let nameFound = name {
+//                return c + [(nameFound, value)]
+//            }
+//            return c
+//        }
     }
     
     private func readBody(_ socket: Socket, size: Int) throws -> [UInt8] {

+ 4 - 2
XCode/SwifterTestsCommon/SwifterTestsHttpParser.swift

@@ -89,9 +89,11 @@ class SwifterTestsHttpParser: XCTestCase {
             XCTAssert(false, "Parser should throw an error if request' body is too short.")
         } catch { }
         
-        var r = try? parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nContent-Length: 10\n\n1234567890"))
+        var r = try? parser.readHttpRequest(TestSocket("GET /open?link=https://www.youtube.com/watch?v=D2cUBG4PnOA HTTP/1.0\nContent-Length: 10\n\n1234567890"))
+        
+        XCTAssertEqual(r?.queryParams.filter({ $0.0 == "link"}).first?.1, "https://www.youtube.com/watch?v=D2cUBG4PnOA")
         XCTAssertEqual(r?.method, "GET", "Parser should extract HTTP method name from the status line.")
-        XCTAssertEqual(r?.path, "/", "Parser should extract HTTP path value from the status line.")
+        XCTAssertEqual(r?.path, "/open?link=https://www.youtube.com/watch?v=D2cUBG4PnOA", "Parser should extract HTTP path value from the status line.")
         XCTAssertEqual(r?.headers["content-length"], "10", "Parser should extract Content-Length header value.")
         
         r = try? parser.readHttpRequest(TestSocket("POST / HTTP/1.0\nContent-Length: 10\n\n1234567890"))