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

Added safeguards to url parameter encoding when extracting the url request’s url.

Christian Noon пре 9 година
родитељ
комит
8ce9088184
3 измењених фајлова са 25 додато и 5 уклоњено
  1. 6 0
      Source/AFError.swift
  2. 9 5
      Source/ParameterEncoding.swift
  3. 10 0
      Tests/AFError+AlamofireTests.swift

+ 6 - 0
Source/AFError.swift

@@ -34,11 +34,13 @@ import Foundation
 public enum AFError: Error {
     /// The underlying reason the parameter encoding error occurred.
     ///
+    /// - missingURL:                 The URL request did not have a URL to encode.
     /// - jsonEncodingFailed:         JSON serialization failed with an underlying system error during the
     ///                               encoding process.
     /// - propertyListEncodingFailed: Property list serialization failed with an underlying system error during 
     ///                               encoding process.
     public enum ParameterEncodingFailureReason {
+        case missingURL
         case jsonEncodingFailed(error: Error)
         case propertyListEncodingFailed(error: Error)
     }
@@ -234,6 +236,8 @@ extension AFError.ParameterEncodingFailureReason {
         switch self {
         case .jsonEncodingFailed(let error), .propertyListEncodingFailed(let error):
             return error
+        default:
+            return nil
         }
     }
 }
@@ -332,6 +336,8 @@ extension AFError: LocalizedError {
 extension AFError.ParameterEncodingFailureReason {
     var localizedDescription: String {
         switch self {
+        case .missingURL:
+            return "URL request to encode was missing a URL"
         case .jsonEncodingFailed(let error):
             return "JSON could not be encoded because of error:\n\(error.localizedDescription)"
         case .propertyListEncodingFailed(let error):

+ 9 - 5
Source/ParameterEncoding.swift

@@ -125,11 +125,15 @@ public struct URLEncoding: ParameterEncoding {
 
         guard let parameters = parameters else { return urlRequest }
 
-        if let method = HTTPMethod(rawValue: urlRequest.httpMethod!), encodesParametersInURL(with: method) {
-            if var URLComponents = URLComponents(url: urlRequest.url!, resolvingAgainstBaseURL: false), !parameters.isEmpty {
-                let percentEncodedQuery = (URLComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters)
-                URLComponents.percentEncodedQuery = percentEncodedQuery
-                urlRequest.url = URLComponents.url
+        if let method = HTTPMethod(rawValue: urlRequest.httpMethod ?? "GET"), encodesParametersInURL(with: method) {
+            guard let url = urlRequest.url else {
+                throw AFError.parameterEncodingFailed(reason: .missingURL)
+            }
+
+            if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty {
+                let percentEncodedQuery = (urlComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters)
+                urlComponents.percentEncodedQuery = percentEncodedQuery
+                urlRequest.url = urlComponents.url
             }
         } else {
             if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {

+ 10 - 0
Tests/AFError+AlamofireTests.swift

@@ -28,6 +28,11 @@ extension AFError {
 
     // ParameterEncodingFailureReason
 
+    var isMissingURLFailed: Bool {
+        if case let .parameterEncodingFailed(reason) = self, reason.isMissingURL { return true }
+        return false
+    }
+
     var isJSONEncodingFailed: Bool {
         if case let .parameterEncodingFailed(reason) = self, reason.isJSONEncodingFailed { return true }
         return false
@@ -173,6 +178,11 @@ extension AFError {
 // MARK: -
 
 extension AFError.ParameterEncodingFailureReason {
+    var isMissingURL: Bool {
+        if case .missingURL = self { return true }
+        return false
+    }
+
     var isJSONEncodingFailed: Bool {
         if case .jsonEncodingFailed = self { return true }
         return false