Selaa lähdekoodia

Reorganized Request extensions and MARKs to better group common logic.

Christian Noon 9 vuotta sitten
vanhempi
commit
ec1c23d0e7
1 muutettua tiedostoa jossa 139 lisäystä ja 133 poistoa
  1. 139 133
      Source/Request.swift

+ 139 - 133
Source/Request.swift

@@ -30,7 +30,7 @@ import Foundation
 */
 public class Request {
 
-    // MARK: - Properties
+    // MARK: Properties
 
     /// The delegate for the underlying task.
     public let delegate: TaskDelegate
@@ -53,7 +53,7 @@ public class Request {
     var startTime: CFAbsoluteTime?
     var endTime: CFAbsoluteTime?
 
-    // MARK: - Lifecycle
+    // MARK: Lifecycle
 
     init(session: URLSession, task: URLSessionTask) {
         self.session = session
@@ -72,7 +72,7 @@ public class Request {
         delegate.queue.addOperation { self.endTime = CFAbsoluteTimeGetCurrent() }
     }
 
-    // MARK: - Authentication
+    // MARK: Authentication
 
     /**
         Associates an HTTP Basic credential with the request.
@@ -125,7 +125,7 @@ public class Request {
         return ["Authorization": "Basic \(credential)"]
     }
 
-    // MARK: - Progress
+    // MARK: Progress
 
     /**
         Sets a closure to be called periodically during the lifecycle of the request as data is written to or read
@@ -173,7 +173,7 @@ public class Request {
         return self
     }
 
-    // MARK: - State
+    // MARK: State
 
     /**
         Resumes the request.
@@ -223,14 +223,130 @@ public class Request {
             userInfo: [Notification.Key.Task: task]
         )
     }
+}
+
+// MARK: - CustomStringConvertible
+
+extension Request: CustomStringConvertible {
+
+    /**
+        The textual representation used when written to an output stream, which includes the HTTP method and URL, as
+        well as the response status code if a response has been received.
+    */
+    public var description: String {
+        var components: [String] = []
+
+        if let HTTPMethod = request?.httpMethod {
+            components.append(HTTPMethod)
+        }
+
+        if let URLString = request?.url?.absoluteString {
+            components.append(URLString)
+        }
+
+        if let response = response {
+            components.append("(\(response.statusCode))")
+        }
+
+        return components.joined(separator: " ")
+    }
+}
+
+// MARK: - CustomDebugStringConvertible
+
+extension Request: CustomDebugStringConvertible {
+    func cURLRepresentation() -> String {
+        var components = ["$ curl -i"]
+
+        guard let request = self.request,
+              let URL = request.url,
+              let host = URL.host
+        else {
+            return "$ curl command could not be created"
+        }
+
+        if let httpMethod = request.httpMethod, httpMethod != "GET" {
+            components.append("-X \(httpMethod)")
+        }
+
+        if let credentialStorage = self.session.configuration.urlCredentialStorage {
+            let protectionSpace = URLProtectionSpace(
+                host: host,
+                port: (URL as NSURL).port?.intValue ?? 0,
+                protocol: URL.scheme,
+                realm: host,
+                authenticationMethod: NSURLAuthenticationMethodHTTPBasic
+            )
+
+            if let credentials = credentialStorage.credentials(for: protectionSpace)?.values {
+                for credential in credentials {
+                    components.append("-u \(credential.user!):\(credential.password!)")
+                }
+            } else {
+                if let credential = delegate.credential {
+                    components.append("-u \(credential.user!):\(credential.password!)")
+                }
+            }
+        }
+
+        if session.configuration.httpShouldSetCookies {
+            if let cookieStorage = session.configuration.httpCookieStorage,
+               let cookies = cookieStorage.cookies(for: URL), !cookies.isEmpty
+            {
+                let string = cookies.reduce("") { $0 + "\($1.name)=\($1.value ?? String());" }
+                components.append("-b \"\(string.substring(to: string.characters.index(before: string.endIndex)))\"")
+            }
+        }
 
-    // MARK: - TaskDelegate
+        var headers: [NSObject: AnyObject] = [:]
+
+        if let additionalHeaders = session.configuration.httpAdditionalHeaders {
+            for (field, value) in additionalHeaders where field != "Cookie" {
+                headers[field] = value
+            }
+        }
 
+        if let headerFields = request.allHTTPHeaderFields {
+            for (field, value) in headerFields where field != "Cookie" {
+                headers[field] = value
+            }
+        }
+
+        for (field, value) in headers {
+            components.append("-H \"\(field): \(value)\"")
+        }
+
+        if let httpBodyData = request.httpBody,
+           let httpBody = String(data: httpBodyData, encoding: String.Encoding.utf8)
+        {
+            var escapedBody = httpBody.replacingOccurrences(of: "\\\"", with: "\\\\\"")
+            escapedBody = escapedBody.replacingOccurrences(of: "\"", with: "\\\"")
+
+            components.append("-d \"\(escapedBody)\"")
+        }
+
+        components.append("\"\(URL.absoluteString)\"")
+
+        return components.joined(separator: " \\\n\t")
+    }
+
+    /// The textual representation used when written to an output stream, in the form of a cURL command.
+    public var debugDescription: String {
+        return cURLRepresentation()
+    }
+}
+
+// MARK: - TaskDelegate
+
+extension Request {
     /**
         The task delegate is responsible for handling all delegate callbacks for the underlying task as well as
         executing all operations attached to the serial operation queue upon task completion.
     */
     public class TaskDelegate: NSObject {
+
+        // MARK: Properties
+
         /// The serial operation queue used to execute all operations after the task completes.
         public let queue: OperationQueue
 
@@ -243,6 +359,8 @@ public class Request {
         var initialResponseTime: CFAbsoluteTime?
         var credential: URLCredential?
 
+        // MARK: Lifecycle
+
         init(task: URLSessionTask) {
             self.task = task
             self.progress = Progress(totalUnitCount: 0)
@@ -262,17 +380,13 @@ public class Request {
             queue.isSuspended = false
         }
 
-        // MARK: - NSURLSessionTaskDelegate
-
-        // MARK: Override Closures
+        // MARK: NSURLSessionTaskDelegate
 
         var taskWillPerformHTTPRedirection: ((Foundation.URLSession, URLSessionTask, HTTPURLResponse, Foundation.URLRequest) -> Foundation.URLRequest?)?
         var taskDidReceiveChallenge: ((Foundation.URLSession, URLSessionTask, URLAuthenticationChallenge) -> (Foundation.URLSession.AuthChallengeDisposition, URLCredential?))?
         var taskNeedNewBodyStream: ((Foundation.URLSession, URLSessionTask) -> InputStream?)?
         var taskDidCompleteWithError: ((Foundation.URLSession, URLSessionTask, NSError?) -> Void)?
 
-        // MARK: Delegate Methods
-
         // RDAR
         @objc(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:)
         func urlSession(
@@ -307,7 +421,7 @@ public class Request {
                 let host = challenge.protectionSpace.host
 
                 if let serverTrustPolicy = session.serverTrustPolicyManager?.serverTrustPolicyForHost(host),
-                   let serverTrust = challenge.protectionSpace.serverTrust
+                    let serverTrust = challenge.protectionSpace.serverTrust
                 {
                     if serverTrustPolicy.evaluateServerTrust(serverTrust, isValidForHost: host) {
                         disposition = .useCredential
@@ -355,21 +469,26 @@ public class Request {
                     self.error = error
 
                     if let downloadDelegate = self as? DownloadTaskDelegate,
-                       let userInfo = error.userInfo as? [String: AnyObject],
-                       let resumeData = userInfo[NSURLSessionDownloadTaskResumeData] as? Data
+                        let userInfo = error.userInfo as? [String: AnyObject],
+                        let resumeData = userInfo[NSURLSessionDownloadTaskResumeData] as? Data
                     {
                         downloadDelegate.resumeData = resumeData
                     }
                 }
-
+                
                 queue.isSuspended = false
             }
         }
     }
+}
 
-    // MARK: - DataTaskDelegate
+// MARK: - DataTaskDelegate
 
+extension Request {
     class DataTaskDelegate: TaskDelegate, URLSessionDataDelegate {
+
+        // MARK: Properties
+
         var dataTask: URLSessionDataTask? { return task as? URLSessionDataTask }
 
         override var data: Data? {
@@ -387,22 +506,20 @@ public class Request {
         private var dataProgress: ((bytesReceived: Int64, totalBytesReceived: Int64, totalBytesExpectedToReceive: Int64) -> Void)?
         private var dataStream: ((data: Data) -> Void)?
 
+        // MARK: Lifecycle
+
         override init(task: URLSessionTask) {
             mutableData = Data()
             super.init(task: task)
         }
 
-        // MARK: - NSURLSessionDataDelegate
-
-        // MARK: Override Closures
+        // MARK: NSURLSessionDataDelegate
 
         var dataTaskDidReceiveResponse: ((Foundation.URLSession, URLSessionDataTask, URLResponse) -> Foundation.URLSession.ResponseDisposition)?
         var dataTaskDidBecomeDownloadTask: ((Foundation.URLSession, URLSessionDataTask, URLSessionDownloadTask) -> Void)?
         var dataTaskDidReceiveData: ((Foundation.URLSession, URLSessionDataTask, Data) -> Void)?
         var dataTaskWillCacheResponse: ((Foundation.URLSession, URLSessionDataTask, CachedURLResponse) -> CachedURLResponse?)?
 
-        // MARK: Delegate Methods
-
         func urlSession(
             _ session: URLSession,
             dataTask: URLSessionDataTask,
@@ -465,119 +582,8 @@ public class Request {
             if let dataTaskWillCacheResponse = dataTaskWillCacheResponse {
                 cachedResponse = dataTaskWillCacheResponse(session, dataTask, proposedResponse)
             }
-
+            
             completionHandler(cachedResponse)
         }
     }
 }
-
-// MARK: - CustomStringConvertible
-
-extension Request: CustomStringConvertible {
-
-    /**
-        The textual representation used when written to an output stream, which includes the HTTP method and URL, as
-        well as the response status code if a response has been received.
-    */
-    public var description: String {
-        var components: [String] = []
-
-        if let HTTPMethod = request?.httpMethod {
-            components.append(HTTPMethod)
-        }
-
-        if let URLString = request?.url?.absoluteString {
-            components.append(URLString)
-        }
-
-        if let response = response {
-            components.append("(\(response.statusCode))")
-        }
-
-        return components.joined(separator: " ")
-    }
-}
-
-// MARK: - CustomDebugStringConvertible
-
-extension Request: CustomDebugStringConvertible {
-    func cURLRepresentation() -> String {
-        var components = ["$ curl -i"]
-
-        guard let request = self.request,
-              let URL = request.url,
-              let host = URL.host
-        else {
-            return "$ curl command could not be created"
-        }
-
-        if let httpMethod = request.httpMethod, httpMethod != "GET" {
-            components.append("-X \(httpMethod)")
-        }
-
-        if let credentialStorage = self.session.configuration.urlCredentialStorage {
-            let protectionSpace = URLProtectionSpace(
-                host: host,
-                port: (URL as NSURL).port?.intValue ?? 0,
-                protocol: URL.scheme,
-                realm: host,
-                authenticationMethod: NSURLAuthenticationMethodHTTPBasic
-            )
-
-            if let credentials = credentialStorage.credentials(for: protectionSpace)?.values {
-                for credential in credentials {
-                    components.append("-u \(credential.user!):\(credential.password!)")
-                }
-            } else {
-                if let credential = delegate.credential {
-                    components.append("-u \(credential.user!):\(credential.password!)")
-                }
-            }
-        }
-
-        if session.configuration.httpShouldSetCookies {
-            if let cookieStorage = session.configuration.httpCookieStorage,
-               let cookies = cookieStorage.cookies(for: URL), !cookies.isEmpty
-            {
-                let string = cookies.reduce("") { $0 + "\($1.name)=\($1.value ?? String());" }
-                components.append("-b \"\(string.substring(to: string.characters.index(before: string.endIndex)))\"")
-            }
-        }
-
-        var headers: [NSObject: AnyObject] = [:]
-
-        if let additionalHeaders = session.configuration.httpAdditionalHeaders {
-            for (field, value) in additionalHeaders where field != "Cookie" {
-                headers[field] = value
-            }
-        }
-
-        if let headerFields = request.allHTTPHeaderFields {
-            for (field, value) in headerFields where field != "Cookie" {
-                headers[field] = value
-            }
-        }
-
-        for (field, value) in headers {
-            components.append("-H \"\(field): \(value)\"")
-        }
-
-        if let httpBodyData = request.httpBody,
-           let httpBody = String(data: httpBodyData, encoding: String.Encoding.utf8)
-        {
-            var escapedBody = httpBody.replacingOccurrences(of: "\\\"", with: "\\\\\"")
-            escapedBody = escapedBody.replacingOccurrences(of: "\"", with: "\\\"")
-
-            components.append("-d \"\(escapedBody)\"")
-        }
-
-        components.append("\"\(URL.absoluteString)\"")
-
-        return components.joined(separator: " \\\n\t")
-    }
-
-    /// The textual representation used when written to an output stream, in the form of a cURL command.
-    public var debugDescription: String {
-        return cURLRepresentation()
-    }
-}