@@ -267,8 +267,8 @@ open class HTTPCookieStorage: NSObject {
267
267
into a set of header fields to add to a request.
268
268
*/
269
269
open func cookies( for url: URL ) -> [ HTTPCookie ] ? {
270
- guard let host = url. host else { return nil }
271
- return Array ( self . syncQ. sync ( execute: { allCookies} ) . values. filter { $0. domain == host } )
270
+ guard let host = url. host? . lowercased ( ) else { return nil }
271
+ return Array ( self . syncQ. sync ( execute: { allCookies} ) . values. filter { $0. validFor ( host : host) } )
272
272
}
273
273
274
274
/*!
@@ -293,17 +293,17 @@ open class HTTPCookieStorage: NSObject {
293
293
guard cookieAcceptPolicy != . never else { return }
294
294
295
295
//if the urls don't have a host, we cannot do anything
296
- guard let urlHost = url? . host else { return }
296
+ guard let urlHost = url? . host? . lowercased ( ) else { return }
297
297
298
298
if mainDocumentURL != nil && cookieAcceptPolicy == . onlyFromMainDocumentDomain {
299
- guard let mainDocumentHost = mainDocumentURL? . host else { return }
299
+ guard let mainDocumentHost = mainDocumentURL? . host? . lowercased ( ) else { return }
300
300
301
301
//the url.host must be a suffix of manDocumentURL.host, this is based on Darwin's behaviour
302
302
guard mainDocumentHost. hasSuffix ( urlHost) else { return }
303
303
}
304
304
305
305
//save only those cookies whose domain matches with the url.host
306
- let validCookies = cookies. filter { urlHost == $0. domain }
306
+ let validCookies = cookies. filter { $0. validFor ( host : urlHost ) }
307
307
for cookie in validCookies {
308
308
setCookie ( cookie)
309
309
}
@@ -334,6 +334,28 @@ public extension Notification.Name {
334
334
}
335
335
336
336
extension HTTPCookie {
337
+ internal func validFor( host: String ) -> Bool {
338
+ // RFC6265 - HTTP State Management Mechanism
339
+ // https://tools.ietf.org/html/rfc6265#section-5.1.3
340
+ //
341
+ // 5.1.3. Domain Matching
342
+ // A string domain-matches a given domain string if at least one of the
343
+ // following conditions hold:
344
+ //
345
+ // 1) The domain string and the string are identical. (Note that both
346
+ // the domain string and the string will have been canonicalized to
347
+ // lower case at this point.)
348
+ //
349
+ // 2) All of the following conditions hold:
350
+ // * The domain string is a suffix of the string.
351
+ // * The last character of the string that is not included in the
352
+ // domain string is a %x2E (".") character.
353
+ // * The string is a host name (i.e., not an IP address).
354
+
355
+ let dotlessDomain = domain. first == " . " ? String ( domain. suffix ( domain. count - 1 ) ) : domain
356
+ return dotlessDomain == host || ( domain. first == " . " && host. hasSuffix ( domain) )
357
+ }
358
+
337
359
internal func persistableDictionary( ) -> [ String : Any ] {
338
360
var properties : [ String : Any ] = [ : ]
339
361
properties [ HTTPCookiePropertyKey . name. rawValue] = name
0 commit comments