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