diff --git a/Headers/Foundation/NSURLCredential.h b/Headers/Foundation/NSURLCredential.h index 3506edf51..f6d2c849c 100644 --- a/Headers/Foundation/NSURLCredential.h +++ b/Headers/Foundation/NSURLCredential.h @@ -72,6 +72,13 @@ typedef enum { password: (NSString *)password persistence: (NSURLCredentialPersistence)persistence; +/** + * Tests two credentials for equality ... credentials are considered to + * be equal if their -user methods return the same value, since you cannot + * have more than one credential for a suser within an [NSURLProtectionSpace]. + */ +- (BOOL) isEqual: (id)other; + /** * Returns the password for the receiver.
* May require prompting of the user to authorize retrieval.
diff --git a/Source/GSHTTPDigest.m b/Source/GSHTTPDigest.m index 238366a5a..d31c10110 100644 --- a/Source/GSHTTPDigest.m +++ b/Source/GSHTTPDigest.m @@ -25,11 +25,13 @@ #include "GSURLPrivate.h" #include "Foundation/NSDictionary.h" #include "Foundation/NSScanner.h" +#include "Foundation/NSSet.h" #include "Foundation/NSDebug.h" #include "GNUstepBase/GSLock.h" #include "GNUstepBase/GSMime.h" +static NSMutableSet *spaces = nil; static NSMutableDictionary *store = nil; static GSLazyLock *storeLock = nil; static GSMimeParser *mimeParser = nil; @@ -75,6 +77,7 @@ static GSMimeParser *mimeParser = nil; if (store == nil) { mimeParser = [GSMimeParser new]; + spaces = [NSMutableSet new]; store = [NSMutableDictionary new]; storeLock = [GSLazyLock new]; } @@ -84,9 +87,21 @@ static GSMimeParser *mimeParser = nil; inProtectionSpace: (NSURLProtectionSpace*)space { NSMutableDictionary *cDict; + NSURLProtectionSpace *known; GSHTTPDigest *digest = nil; [storeLock lock]; + /* + * Keep track of known protection spaces so we don't make lots of + * duplicate copies, but share one copy between digest objects. + */ + known = [spaces member: space]; + if (known == nil) + { + [spaces addObject: space]; + known = [spaces member: space]; + } + space = known; cDict = [store objectForKey: space]; if (cDict == nil) { @@ -318,8 +333,8 @@ static GSMimeParser *mimeParser = nil; if ((self = [super init]) != nil) { self->_lock = [GSLazyLock new]; - ASSIGNCOPY(self->_space, space); - ASSIGNCOPY(self->_credential, credential); + ASSIGN(self->_space, space); + ASSIGN(self->_credential, credential); } return self; } diff --git a/Source/NSURLCredential.m b/Source/NSURLCredential.m index 03d851fb7..3c21522c3 100644 --- a/Source/NSURLCredential.m +++ b/Source/NSURLCredential.m @@ -91,6 +91,11 @@ typedef struct { return this->hasPassword; } +- (unsigned) hash +{ + return [this->user hash]; +} + - (id) initWithUser: (NSString *)user password: (NSString *)password persistence: (NSURLCredentialPersistence)persistence @@ -114,6 +119,19 @@ typedef struct { return self; } +- (BOOL) isEqual: (id)other +{ + if ((id)self == other) + { + return YES; + } + if ([other isKindOfClass: [NSURLCredential class]] == NO) + { + return NO; + } + return [[(NSURLCredential*)other user] isEqualToString: this->user]; +} + - (NSString *) password { return this->password; diff --git a/Source/NSURLProtectionSpace.m b/Source/NSURLProtectionSpace.m index cf321c49d..cbca2dfb9 100644 --- a/Source/NSURLProtectionSpace.m +++ b/Source/NSURLProtectionSpace.m @@ -162,6 +162,10 @@ authenticationMethod: (NSString *)authenticationMethod - (unsigned) isEqual: (id)other { + if ((id)self == other) + { + return YES; + } if ([other isKindOfClass: [NSURLProtectionSpace class]] == NO) { return NO; @@ -202,8 +206,8 @@ authenticationMethod: (NSString *)authenticationMethod return NO; } } - return YES; - } + return YES; + } } - (BOOL) isProxy