added iOS source code
[wl-app.git] / iOS / Pods / OAuthSwift / Sources / OAuthSwiftClient.swift
1 //
2 //  OAuthSwiftClient.swift
3 //  OAuthSwift
4 //
5 //  Created by Dongri Jin on 6/21/14.
6 //  Copyright (c) 2014 Dongri Jin. All rights reserved.
7 //
8
9 import Foundation
10
11 public var OAuthSwiftDataEncoding: String.Encoding = .utf8
12
13 @objc public protocol OAuthSwiftRequestHandle {
14     func cancel()
15 }
16
17 open class OAuthSwiftClient: NSObject {
18
19     fileprivate(set) open var credential: OAuthSwiftCredential
20     open var paramsLocation: OAuthSwiftHTTPRequest.ParamsLocation = .authorizationHeader
21     /// Contains default URL session configuration
22     open var sessionFactory = URLSessionFactory()
23
24     static let separator: String = "\r\n"
25     static var separatorData: Data = {
26         return OAuthSwiftClient.separator.data(using: OAuthSwiftDataEncoding)!
27     }()
28
29     // MARK: init
30     public init(credential: OAuthSwiftCredential) {
31         self.credential = credential
32     }
33
34     public convenience init(consumerKey: String, consumerSecret: String, version: OAuthSwiftCredential.Version = .oauth1) {
35         let credential = OAuthSwiftCredential(consumerKey: consumerKey, consumerSecret: consumerSecret)
36         credential.version = version
37         self.init(credential: credential)
38     }
39
40     public convenience init(consumerKey: String, consumerSecret: String, oauthToken: String, oauthTokenSecret: String, version: OAuthSwiftCredential.Version) {
41         self.init(consumerKey: consumerKey, consumerSecret: consumerSecret, version: version)
42         self.credential.oauthToken = oauthToken
43         self.credential.oauthTokenSecret = oauthTokenSecret
44     }
45
46     // MARK: client methods
47     @discardableResult
48     open func get(_ urlString: String, parameters: OAuthSwift.Parameters = [:], headers: OAuthSwift.Headers? = nil, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) -> OAuthSwiftRequestHandle? {
49         return self.request(urlString, method: .GET, parameters: parameters, headers: headers, success: success, failure: failure)
50     }
51
52     @discardableResult
53     open func post(_ urlString: String, parameters: OAuthSwift.Parameters = [:], headers: OAuthSwift.Headers? = nil, body: Data? = nil, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) -> OAuthSwiftRequestHandle? {
54         return self.request(urlString, method: .POST, parameters: parameters, headers: headers, body: body, success: success, failure: failure)
55     }
56
57     @discardableResult
58     open func put(_ urlString: String, parameters: OAuthSwift.Parameters = [:], headers: OAuthSwift.Headers? = nil, body: Data? = nil, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) -> OAuthSwiftRequestHandle? {
59         return self.request(urlString, method: .PUT, parameters: parameters, headers: headers, body: body, success: success, failure: failure)
60     }
61
62     @discardableResult
63     open func delete(_ urlString: String, parameters: OAuthSwift.Parameters = [:], headers: OAuthSwift.Headers? = nil, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) -> OAuthSwiftRequestHandle? {
64         return self.request(urlString, method: .DELETE, parameters: parameters, headers: headers, success: success, failure: failure)
65     }
66
67     @discardableResult
68     open func patch(_ urlString: String, parameters: OAuthSwift.Parameters = [:], headers: OAuthSwift.Headers? = nil, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) -> OAuthSwiftRequestHandle? {
69         return self.request(urlString, method: .PATCH, parameters: parameters, headers: headers, success: success, failure: failure)
70     }
71
72     @discardableResult
73     open func request(_ urlString: String, method: OAuthSwiftHTTPRequest.Method, parameters: OAuthSwift.Parameters = [:], headers: OAuthSwift.Headers? = nil, body: Data? = nil, checkTokenExpiration: Bool = true, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) -> OAuthSwiftRequestHandle? {
74
75         if checkTokenExpiration && self.credential.isTokenExpired() {
76             failure?(OAuthSwiftError.tokenExpired(error: nil))
77             return nil
78         }
79
80         guard URL(string: urlString) != nil else {
81             failure?(OAuthSwiftError.encodingError(urlString: urlString))
82             return nil
83         }
84
85         if let request = makeRequest(urlString, method: method, parameters: parameters, headers: headers, body: body) {
86             request.start(success: success, failure: failure)
87             return request
88         }
89         return nil
90     }
91
92     open func makeRequest(_ request: URLRequest) -> OAuthSwiftHTTPRequest {
93         let request = OAuthSwiftHTTPRequest(request: request, paramsLocation: self.paramsLocation, sessionFactory: self.sessionFactory)
94         request.config.updateRequest(credential: self.credential)
95         return request
96     }
97
98     open func makeRequest(_ urlString: String, method: OAuthSwiftHTTPRequest.Method, parameters: OAuthSwift.Parameters = [:], headers: OAuthSwift.Headers? = nil, body: Data? = nil) -> OAuthSwiftHTTPRequest? {
99         guard let url = URL(string: urlString) else {
100             return nil
101         }
102
103         let request = OAuthSwiftHTTPRequest(url: url, method: method, parameters: parameters, paramsLocation: self.paramsLocation, httpBody: body, headers: headers ?? [:], sessionFactory: self.sessionFactory)
104         request.config.updateRequest(credential: self.credential)
105         return request
106     }
107
108     @discardableResult
109     public func postImage(_ urlString: String, parameters: OAuthSwift.Parameters, image: Data, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) -> OAuthSwiftRequestHandle? {
110         return self.multiPartRequest(url: urlString, method: .POST, parameters: parameters, image: image, success: success, failure: failure)
111     }
112
113     open func makeMultiPartRequest(_ urlString: String, method: OAuthSwiftHTTPRequest.Method, parameters: OAuthSwift.Parameters = [:], multiparts: [OAuthSwiftMultipartData] = [], headers: OAuthSwift.Headers? = nil) -> OAuthSwiftHTTPRequest? {
114         let boundary = "AS-boundary-\(arc4random())-\(arc4random())"
115         let type = "multipart/form-data; boundary=\(boundary)"
116         let body = self.multiDataFromObject(parameters, multiparts: multiparts, boundary: boundary)
117
118         var finalHeaders = [kHTTPHeaderContentType: type]
119         finalHeaders += headers ?? [:]
120
121         return makeRequest(urlString, method: method, parameters: parameters, headers: finalHeaders, body: body)
122     }
123
124     func multiPartRequest(url: String, method: OAuthSwiftHTTPRequest.Method, parameters: OAuthSwift.Parameters, image: Data, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) -> OAuthSwiftRequestHandle? {
125         let multiparts = [ OAuthSwiftMultipartData(name: "media", data: image, fileName: "file", mimeType: "image/jpeg") ]
126
127         if let request = makeMultiPartRequest(url, method: method, parameters: parameters, multiparts: multiparts) {
128             request.start(success: success, failure: failure)
129             return request
130         }
131
132         return nil
133     }
134
135     open func multiPartBody(from inputParameters: OAuthSwift.Parameters, boundary: String) -> Data {
136         var parameters = OAuthSwift.Parameters()
137         var multiparts = [OAuthSwiftMultipartData]()
138
139         for (key, value) in inputParameters {
140             if  let data = value as? Data, key == "media" {
141                 let sectionType = "image/jpeg"
142                 let sectionFilename = "file"
143                 multiparts.append(OAuthSwiftMultipartData(name: key, data: data, fileName: sectionFilename, mimeType: sectionType))
144             } else {
145                 parameters[key] = value
146             }
147         }
148
149         return multiDataFromObject(parameters, multiparts: multiparts, boundary: boundary)
150     }
151
152     @discardableResult
153     open func postMultiPartRequest(_ url: String, method: OAuthSwiftHTTPRequest.Method, parameters: OAuthSwift.Parameters, headers: OAuthSwift.Headers? = nil, multiparts: [OAuthSwiftMultipartData] = [], checkTokenExpiration: Bool = true, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) -> OAuthSwiftRequestHandle? {
154
155         if checkTokenExpiration && self.credential.isTokenExpired() {
156             failure?(OAuthSwiftError.tokenExpired(error: nil))
157             return nil
158         }
159
160         if let request = makeMultiPartRequest(url, method: method, parameters: parameters, multiparts: multiparts, headers: headers) {
161             request.start(success: success, failure: failure)
162             return request
163         }
164         return nil
165     }
166
167     func multiDataFromObject(_ object: OAuthSwift.Parameters, multiparts: [OAuthSwiftMultipartData], boundary: String) -> Data {
168         var data = Data()
169
170         let prefixString = "--\(boundary)\r\n"
171         let prefixData = prefixString.data(using: OAuthSwiftDataEncoding)!
172
173         for (key, value) in object {
174             guard let valueData = "\(value)".data(using: OAuthSwiftDataEncoding) else {
175                 continue
176             }
177             data.append(prefixData)
178             let multipartData = OAuthSwiftMultipartData(name: key, data: valueData, fileName: nil, mimeType: nil)
179             data.append(multipartData, encoding: OAuthSwiftDataEncoding, separatorData: OAuthSwiftClient.separatorData)
180         }
181
182         for multipart in multiparts {
183             data.append(prefixData)
184             data.append(multipart, encoding: OAuthSwiftDataEncoding, separatorData: OAuthSwiftClient.separatorData)
185         }
186
187         let endingString = "--\(boundary)--\r\n"
188         let endingData = endingString.data(using: OAuthSwiftDataEncoding)!
189         data.append(endingData)
190
191         return data
192     }
193
194 }