mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Use case insensitive dictionary for headers
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25159 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
9740458609
commit
96e36de9e8
2 changed files with 20 additions and 113 deletions
|
@ -4,6 +4,7 @@
|
|||
* Source/NSURLProtocol.m: Perform automatic redirect from
|
||||
http://host to http://host/ to standardise URL used for caching as
|
||||
noted in Apple documentation.
|
||||
* Source/NSURLRequest.m: use case insensitive dictionary for headers.
|
||||
|
||||
2007-05-14 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
|
|
|
@ -23,10 +23,9 @@
|
|||
*/
|
||||
|
||||
#include "GSURLPrivate.h"
|
||||
#include "GSPrivate.h"
|
||||
|
||||
#include "Foundation/NSMapTable.h"
|
||||
#include "Foundation/NSCoder.h"
|
||||
#include "NSCallBacks.h"
|
||||
|
||||
|
||||
// Internal data storage
|
||||
|
@ -34,7 +33,7 @@ typedef struct {
|
|||
NSData *body;
|
||||
NSInputStream *bodyStream;
|
||||
NSString *method;
|
||||
NSMapTable *headers;
|
||||
NSMutableDictionary *headers;
|
||||
BOOL shouldHandleCookies;
|
||||
NSURL *URL;
|
||||
NSURL *mainDocumentURL;
|
||||
|
@ -112,14 +111,7 @@ typedef struct {
|
|||
ASSIGN(inst->bodyStream, this->bodyStream);
|
||||
ASSIGN(inst->method, this->method);
|
||||
inst->shouldHandleCookies = this->shouldHandleCookies;
|
||||
if (this->headers == 0)
|
||||
{
|
||||
inst->headers = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
inst->headers = NSCopyMapTableWithZone(this->headers, z);
|
||||
}
|
||||
inst->headers = [this->headers mutableCopy];
|
||||
}
|
||||
}
|
||||
return o;
|
||||
|
@ -135,10 +127,7 @@ typedef struct {
|
|||
RELEASE(this->URL);
|
||||
RELEASE(this->mainDocumentURL);
|
||||
RELEASE(this->properties);
|
||||
if (this->headers != 0)
|
||||
{
|
||||
NSFreeMapTable(this->headers);
|
||||
}
|
||||
RELEASE(this->headers);
|
||||
NSZoneFree([self zone], this);
|
||||
}
|
||||
[super dealloc];
|
||||
|
@ -241,32 +230,10 @@ typedef struct {
|
|||
{
|
||||
return NO;
|
||||
}
|
||||
if (this->headers != inst->headers)
|
||||
if (this->headers != inst->headers
|
||||
&& [this->headers isEqual: inst->headers] == NO)
|
||||
{
|
||||
NSMapEnumerator enumerator;
|
||||
id k;
|
||||
id v;
|
||||
|
||||
if (this->headers == 0 || inst->headers == 0)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
if (NSCountMapTable(this->headers) != NSCountMapTable(inst->headers))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
enumerator = NSEnumerateMapTable(this->headers);
|
||||
while (NSNextMapEnumeratorPair(&enumerator, (void **)(&k), (void**)&v))
|
||||
{
|
||||
id ov = (id)NSMapGet(inst->headers, (void*)k);
|
||||
|
||||
if ([v isEqual: ov] == NO)
|
||||
{
|
||||
NSEndMapTableEnumeration(&enumerator);
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&enumerator);
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
@ -293,14 +260,7 @@ typedef struct {
|
|||
ASSIGN(inst->bodyStream, this->bodyStream);
|
||||
ASSIGN(inst->method, this->method);
|
||||
inst->shouldHandleCookies = this->shouldHandleCookies;
|
||||
if (this->headers == 0)
|
||||
{
|
||||
inst->headers = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
inst->headers = NSCopyMapTableWithZone(this->headers, z);
|
||||
}
|
||||
inst->headers = [this->headers mutableCopy];
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
@ -342,66 +302,19 @@ typedef struct {
|
|||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Implement map keys for strings with case insensitive comparisons,
|
||||
* so we can have case insensitive matching of http headers (correct
|
||||
* behavior), but actually preserve case of headers stored and written
|
||||
* in case the remote server is buggy and requires particular
|
||||
* captialisation of headers (some http software is faulty like that).
|
||||
*/
|
||||
static unsigned int
|
||||
_non_retained_id_hash(void *table, NSString* o)
|
||||
{
|
||||
return [[o lowercaseString] hash];
|
||||
}
|
||||
|
||||
static BOOL
|
||||
_non_retained_id_is_equal(void *table, NSString *o, NSString *p)
|
||||
{
|
||||
if (o == nil || [o caseInsensitiveCompare: p] != NSOrderedSame)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
typedef unsigned int (*NSMT_hash_func_t)(NSMapTable *, const void *);
|
||||
typedef BOOL (*NSMT_is_equal_func_t)(NSMapTable *, const void *, const void *);
|
||||
typedef void (*NSMT_retain_func_t)(NSMapTable *, const void *);
|
||||
typedef void (*NSMT_release_func_t)(NSMapTable *, void *);
|
||||
typedef NSString *(*NSMT_describe_func_t)(NSMapTable *, const void *);
|
||||
|
||||
static const NSMapTableKeyCallBacks headerKeyCallBacks =
|
||||
{
|
||||
(NSMT_hash_func_t) _non_retained_id_hash,
|
||||
(NSMT_is_equal_func_t) _non_retained_id_is_equal,
|
||||
(NSMT_retain_func_t) _NS_non_retained_id_retain,
|
||||
(NSMT_release_func_t) _NS_non_retained_id_release,
|
||||
(NSMT_describe_func_t) _NS_non_retained_id_describe,
|
||||
NSNotAPointerMapKey
|
||||
};
|
||||
|
||||
@implementation NSURLRequest (NSHTTPURLRequest)
|
||||
|
||||
- (NSDictionary *) allHTTPHeaderFields
|
||||
{
|
||||
NSMutableDictionary *fields;
|
||||
NSDictionary *fields;
|
||||
|
||||
fields = [NSMutableDictionary dictionaryWithCapacity: 8];
|
||||
if (this->headers != 0)
|
||||
if (this->headers == nil)
|
||||
{
|
||||
NSMapEnumerator enumerator;
|
||||
NSString *k;
|
||||
NSString *v;
|
||||
|
||||
enumerator = NSEnumerateMapTable(this->headers);
|
||||
while (NSNextMapEnumeratorPair(&enumerator, (void **)(&k), (void**)&v))
|
||||
{
|
||||
[fields setObject: v forKey: k];
|
||||
}
|
||||
NSEndMapTableEnumeration(&enumerator);
|
||||
fields = [NSDictionary dictionary];
|
||||
}
|
||||
else
|
||||
{
|
||||
fields = [NSDictionary dictionaryWithDictionary: this->headers];
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
@ -428,13 +341,7 @@ static const NSMapTableKeyCallBacks headerKeyCallBacks =
|
|||
|
||||
- (NSString *) valueForHTTPHeaderField: (NSString *)field
|
||||
{
|
||||
NSString *value = nil;
|
||||
|
||||
if (this->headers != 0)
|
||||
{
|
||||
value = (NSString*)NSMapGet(this->headers, (void*)field);
|
||||
}
|
||||
return value;
|
||||
return [this->headers objectForKey: field];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -502,12 +409,11 @@ static const NSMapTableKeyCallBacks headerKeyCallBacks =
|
|||
|
||||
- (void) setValue: (NSString *)value forHTTPHeaderField: (NSString *)field
|
||||
{
|
||||
if (this->headers == 0)
|
||||
if (this->headers == nil)
|
||||
{
|
||||
this->headers = NSCreateMapTable(headerKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 8);
|
||||
this->headers = [_GSMutableInsensitiveDictionary new];
|
||||
}
|
||||
NSMapInsert(this->headers, (void*)field, (void*)value);
|
||||
[this->headers setObject: value forKey: field];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue