Skip to content

Commit e573221

Browse files
authored
Merge pull request swiftlang#1382 from pushkarnk/urlprotection-space
2 parents ebc61dd + 625eda7 commit e573221

File tree

1 file changed

+73
-17
lines changed

1 file changed

+73
-17
lines changed

Foundation/URLProtectionSpace.swift

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,15 @@ public let NSURLAuthenticationMethodServerTrust: String = "NSURLAuthenticationMe
105105
@discussion This class represents a protection space requiring authentication.
106106
*/
107107
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+
109117
open override func copy() -> Any {
110118
return copy(with: nil)
111119
}
@@ -135,7 +143,15 @@ open class URLProtectionSpace : NSObject, NSSecureCoding, NSCopying {
135143
valid values include nil (default method), @"digest" and @"form".
136144
@result The initialized object.
137145
*/
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+
}
139155

140156
/*!
141157
@method initWithProxyHost:port:type:realm:authenticationMethod:
@@ -151,8 +167,16 @@ open class URLProtectionSpace : NSObject, NSSecureCoding, NSCopying {
151167
valid values include nil (default method) and @"digest"
152168
@result The initialized object.
153169
*/
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+
156180
/*!
157181
@method realm
158182
@abstract Get the authentication realm for which the protection space that
@@ -161,7 +185,9 @@ open class URLProtectionSpace : NSObject, NSSecureCoding, NSCopying {
161185
authentication, and may be nil otherwise.
162186
@result The realm string
163187
*/
164-
open var realm: String? { NSUnimplemented() }
188+
open var realm: String? {
189+
return _realm
190+
}
165191

166192
/*!
167193
@method receivesCredentialSecurely
@@ -170,47 +196,77 @@ open class URLProtectionSpace : NSObject, NSSecureCoding, NSCopying {
170196
*/
171197
open var receivesCredentialSecurely: Bool { NSUnimplemented() }
172198

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-
179199
/*!
180200
@method host
181201
@abstract Get the proxy host if this is a proxy authentication, or the host from the URL.
182202
@result The host for this protection space.
183203
*/
184-
open var host: String { NSUnimplemented() }
204+
open var host: String {
205+
return _host
206+
}
185207

186208
/*!
187209
@method port
188210
@abstract Get the proxy port if this is a proxy authentication, or the port from the URL.
189211
@result The port for this protection space, or 0 if not set.
190212
*/
191-
open var port: Int { NSUnimplemented() }
213+
open var port: Int {
214+
return _port
215+
}
192216

193217
/*!
194218
@method proxyType
195219
@abstract Get the type of this protection space, if a proxy
196220
@result The type string, or nil if not a proxy.
197221
*/
198-
open var proxyType: String? { NSUnimplemented() }
222+
open var proxyType: String? {
223+
return _proxyType
224+
}
199225

200226
/*!
201227
@method protocol
202228
@abstract Get the protocol of this protection space, if not a proxy
203229
@result The type string, or nil if a proxy.
204230
*/
205-
open var `protocol`: String? { NSUnimplemented() }
231+
open var `protocol`: String? {
232+
return _protocol
233+
}
206234

207235
/*!
208236
@method authenticationMethod
209237
@abstract Get the authentication method to be used for this protection space
210238
@result The authentication method
211239
*/
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+
}
214270
}
215271

216272
extension URLProtectionSpace {

0 commit comments

Comments
 (0)