@@ -105,7 +105,15 @@ public let NSURLAuthenticationMethodServerTrust: String = "NSURLAuthenticationMe
105
105
@discussion This class represents a protection space requiring authentication.
106
106
*/
107
107
open class URLProtectionSpace : NSObject , NSSecureCoding , NSCopying {
108
-
108
+
109
+ private let _host : String
110
+ private let _isProxy : Bool
111
+ private let _proxyType : String ?
112
+ private let _port : Int
113
+ private let _protocol : String ?
114
+ private let _realm : String ?
115
+ private let _authenticationMethod : String
116
+
109
117
open override func copy( ) -> Any {
110
118
return copy ( with: nil )
111
119
}
@@ -135,7 +143,15 @@ open class URLProtectionSpace : NSObject, NSSecureCoding, NSCopying {
135
143
valid values include nil (default method), @"digest" and @"form".
136
144
@result The initialized object.
137
145
*/
138
- public init ( host: String , port: Int , protocol: String ? , realm: String ? , authenticationMethod: String ? ) { NSUnimplemented ( ) }
146
+ public init ( host: String , port: Int , protocol: String ? , realm: String ? , authenticationMethod: String ? ) {
147
+ _host = host
148
+ _port = port
149
+ _protocol = `protocol`
150
+ _realm = realm
151
+ _authenticationMethod = authenticationMethod ?? NSURLAuthenticationMethodDefault
152
+ _proxyType = nil
153
+ _isProxy = false
154
+ }
139
155
140
156
/*!
141
157
@method initWithProxyHost:port:type:realm:authenticationMethod:
@@ -151,8 +167,16 @@ open class URLProtectionSpace : NSObject, NSSecureCoding, NSCopying {
151
167
valid values include nil (default method) and @"digest"
152
168
@result The initialized object.
153
169
*/
154
- public init ( proxyHost host: String , port: Int , type: String ? , realm: String ? , authenticationMethod: String ? ) { NSUnimplemented ( ) }
155
-
170
+ public init ( proxyHost host: String , port: Int , type: String ? , realm: String ? , authenticationMethod: String ? ) {
171
+ _host = host
172
+ _port = port
173
+ _proxyType = type
174
+ _realm = realm
175
+ _authenticationMethod = authenticationMethod ?? NSURLAuthenticationMethodDefault
176
+ _isProxy = true
177
+ _protocol = nil
178
+ }
179
+
156
180
/*!
157
181
@method realm
158
182
@abstract Get the authentication realm for which the protection space that
@@ -161,7 +185,9 @@ open class URLProtectionSpace : NSObject, NSSecureCoding, NSCopying {
161
185
authentication, and may be nil otherwise.
162
186
@result The realm string
163
187
*/
164
- open var realm : String ? { NSUnimplemented ( ) }
188
+ open var realm : String ? {
189
+ return _realm
190
+ }
165
191
166
192
/*!
167
193
@method receivesCredentialSecurely
@@ -170,47 +196,77 @@ open class URLProtectionSpace : NSObject, NSSecureCoding, NSCopying {
170
196
*/
171
197
open var receivesCredentialSecurely : Bool { NSUnimplemented ( ) }
172
198
173
- /*!
174
- @method isProxy
175
- @abstract Determine if this authenticating protection space is a proxy server
176
- @result YES if a proxy, NO otherwise
177
- */
178
-
179
199
/*!
180
200
@method host
181
201
@abstract Get the proxy host if this is a proxy authentication, or the host from the URL.
182
202
@result The host for this protection space.
183
203
*/
184
- open var host : String { NSUnimplemented ( ) }
204
+ open var host : String {
205
+ return _host
206
+ }
185
207
186
208
/*!
187
209
@method port
188
210
@abstract Get the proxy port if this is a proxy authentication, or the port from the URL.
189
211
@result The port for this protection space, or 0 if not set.
190
212
*/
191
- open var port : Int { NSUnimplemented ( ) }
213
+ open var port : Int {
214
+ return _port
215
+ }
192
216
193
217
/*!
194
218
@method proxyType
195
219
@abstract Get the type of this protection space, if a proxy
196
220
@result The type string, or nil if not a proxy.
197
221
*/
198
- open var proxyType : String ? { NSUnimplemented ( ) }
222
+ open var proxyType : String ? {
223
+ return _proxyType
224
+ }
199
225
200
226
/*!
201
227
@method protocol
202
228
@abstract Get the protocol of this protection space, if not a proxy
203
229
@result The type string, or nil if a proxy.
204
230
*/
205
- open var `protocol` : String ? { NSUnimplemented ( ) }
231
+ open var `protocol` : String ? {
232
+ return _protocol
233
+ }
206
234
207
235
/*!
208
236
@method authenticationMethod
209
237
@abstract Get the authentication method to be used for this protection space
210
238
@result The authentication method
211
239
*/
212
- open var authenticationMethod : String { NSUnimplemented ( ) }
213
- open override func isProxy( ) -> Bool { NSUnimplemented ( ) }
240
+ open var authenticationMethod : String {
241
+ return _authenticationMethod
242
+ }
243
+
244
+ /*!
245
+ @method isProxy
246
+ @abstract Determine if this authenticating protection space is a proxy server
247
+ @result YES if a proxy, NO otherwise
248
+ */
249
+ open override func isProxy( ) -> Bool {
250
+ return _isProxy
251
+ }
252
+ }
253
+
254
+ extension URLProtectionSpace {
255
+ //an internal helper to create a URLProtectionSpace from a HTTPURLResponse
256
+ static func create( using response: HTTPURLResponse ) -> URLProtectionSpace {
257
+ let host = response. url? . host ?? " "
258
+ let port = response. url? . port ?? 80 //HTTP
259
+ let _protocol = response. url? . scheme
260
+ guard let wwwAuthHeader = response. allHeaderFields [ " Www-Authenticate " ] as? String else {
261
+ fatalError ( " Authentication failed but no Www-Authenticate header in response " )
262
+ }
263
+
264
+ //The format of the authentication header is `<auth-scheme> realm="<realm value>"`
265
+ //Example: `Basic realm="Fake Realm"`
266
+ let authMethod = wwwAuthHeader. components ( separatedBy: " " ) [ 0 ]
267
+ let realm = String ( String ( wwwAuthHeader. components ( separatedBy: " realm= " ) [ 1 ] . dropFirst ( ) ) . dropLast ( ) )
268
+ return URLProtectionSpace ( host: host, port: port, protocol: _protocol, realm: realm, authenticationMethod: authMethod)
269
+ }
214
270
}
215
271
216
272
extension URLProtectionSpace {
0 commit comments