Many tidyups and fixes for minor problems

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@8146 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 2000-11-17 21:09:40 +00:00
parent a1578d8fa2
commit cfdd997891
4 changed files with 90 additions and 38 deletions

View file

@ -4,6 +4,7 @@
* Headers/Foundation/NSURLHandle.h: Added some more property keys. * Headers/Foundation/NSURLHandle.h: Added some more property keys.
* Source/GSMime.m: Update to add method for general decoding of * Source/GSMime.m: Update to add method for general decoding of
different transfer encoding types including chunked (for http1.1). different transfer encoding types including chunked (for http1.1).
Recognise end of data in chunked encoding or by content length.
* Source/GSHTTPURLHandle.m: Added new class for http and https support. * Source/GSHTTPURLHandle.m: Added new class for http and https support.
* Source/NSURLHandle.m: Register class for http and https support. * Source/NSURLHandle.m: Register class for http and https support.
* Source/externs.m: Added property keys for URL handles. * Source/externs.m: Added property keys for URL handles.

View file

@ -80,6 +80,8 @@
unsigned lineStart; unsigned lineStart;
unsigned lineEnd; unsigned lineEnd;
unsigned input; unsigned input;
unsigned expect;
unsigned rawBodyLength;
BOOL inBody; BOOL inBody;
BOOL complete; BOOL complete;
NSData *boundary; NSData *boundary;

View file

@ -38,7 +38,7 @@
#include <Foundation/GSMime.h> #include <Foundation/GSMime.h>
#include <string.h> #include <string.h>
static NSString *httpVersion = @"1.0"; static NSString *httpVersion = @"1.1";
char emp[64] = { char emp[64] = {
'A','B','C','D','E','F','G','H','I','J','K','L','M', 'A','B','C','D','E','F','G','H','I','J','K','L','M',
@ -162,7 +162,7 @@ static NSLock *urlLock = nil;
d = [dict objectForKey: NSFileHandleNotificationDataItem]; d = [dict objectForKey: NSFileHandleNotificationDataItem];
[parser parse: d]; [parser parse: d];
if ([d length] == 0) if ([parser isComplete] == YES)
{ {
NSDictionary *info; NSDictionary *info;
NSString *val; NSString *val;
@ -215,6 +215,16 @@ static NSLock *urlLock = nil;
str = [str initWithData: dat encoding: NSASCIIStringEncoding]; str = [str initWithData: dat encoding: NSASCIIStringEncoding];
range = [str rangeOfString: @"\n\n" range = [str rangeOfString: @"\n\n"
options: NSCaseInsensitiveSearch]; options: NSCaseInsensitiveSearch];
if (range.length == 0)
{
range = [str rangeOfString: @"\r\n\r\n"
options: NSCaseInsensitiveSearch];
if (range.length == 0)
{
range = [str rangeOfString: @"\r\r"
options: NSCaseInsensitiveSearch];
}
}
if ([d length] == 0 || range.length > 0) if ([d length] == 0 || range.length > 0)
{ {
[nc removeObserver: self [nc removeObserver: self
@ -375,12 +385,12 @@ static NSLock *urlLock = nil;
if ([url port] == nil) if ([url port] == nil)
{ {
cmd = [NSString stringWithFormat: @"CONNECT %@:443 HTTP/%@\n\n", cmd = [NSString stringWithFormat: @"CONNECT %@:443 HTTP/%@\r\n\r\n",
[url host], httpVersion]; [url host], httpVersion];
} }
else else
{ {
cmd = [NSString stringWithFormat: @"CONNECT %@:%@ HTTP/%@\n\n", cmd = [NSString stringWithFormat: @"CONNECT %@:%@ HTTP/%@\r\n\r\n",
[url host], [url port], httpVersion]; [url host], [url port], httpVersion];
} }
@ -409,30 +419,35 @@ static NSLock *urlLock = nil;
return; return;
} }
} }
/*
* Set up request - differs for proxy version unless tunneling via ssl.
*/
if ([request objectForKey: GSHTTPPropertyMethodKey] == nil) if ([request objectForKey: GSHTTPPropertyMethodKey] == nil)
{ {
[request setObject: @"GET" forKey: GSHTTPPropertyMethodKey]; [request setObject: @"GET" forKey: GSHTTPPropertyMethodKey];
} }
if ([request objectForKey: GSHTTPPropertyProxyHostKey] != nil) if ([request objectForKey: GSHTTPPropertyProxyHostKey] != nil
&& [[url scheme] isEqualToString: @"https"] == NO)
{ {
s = [[NSMutableString alloc] initWithFormat: @"\n%@ http://%@%@", s = [[NSMutableString alloc] initWithFormat: @"%@ http://%@%@",
[request objectForKey: GSHTTPPropertyMethodKey], [request objectForKey: GSHTTPPropertyMethodKey],
[url host], [url path]]; [url host], [url path]];
if ([[url query] length] > 0) if ([[url query] length] > 0)
{ {
[s appendFormat: @"?%@", [url query]]; [s appendFormat: @"?%@", [url query]];
} }
[s appendFormat: @" HTTP/%@\n", httpVersion]; [s appendFormat: @" HTTP/%@\r\n", httpVersion];
} }
else // no proxy else // no proxy
{ {
s = [[NSMutableString alloc] initWithFormat: @"\n%@ %@", s = [[NSMutableString alloc] initWithFormat: @"%@ %@",
[request objectForKey: GSHTTPPropertyMethodKey], [url path]]; [request objectForKey: GSHTTPPropertyMethodKey], [url path]];
if ([[url query] length] > 0) if ([[url query] length] > 0)
{ {
[s appendFormat: @"?%@", [url query]]; [s appendFormat: @"?%@", [url query]];
} }
[s appendFormat: @" HTTP/%@\nHost: %@\n", [url host], httpVersion]; [s appendFormat: @" HTTP/%@\nHost: %@\r\n", httpVersion, [url host]];
} }
while ((key = [wpEnumerator nextObject])) while ((key = [wpEnumerator nextObject]))

View file

@ -794,7 +794,6 @@ parseCharacterSet(NSString *token)
{ {
data = [[NSMutableData alloc] init]; data = [[NSMutableData alloc] init];
document = [[GSMimeDocument alloc] init]; document = [[GSMimeDocument alloc] init];
context = [[GSMimeCodingContext alloc] init];
} }
return self; return self;
} }
@ -1507,7 +1506,53 @@ parseCharacterSet(NSString *token)
- (BOOL) _decodeBody: (NSData*)d - (BOOL) _decodeBody: (NSData*)d
{ {
if (boundary == nil) BOOL result = NO;
rawBodyLength += [d length];
if (context == nil)
{
NSDictionary *hdr;
/*
* Check for expected content length.
*/
hdr = [document headerNamed: @"content-length"];
if (hdr != nil)
{
expect = [[hdr objectForKey: @"BaseValue"] intValue];
}
/*
* Set up context for decoding data.
*/
hdr = [document headerNamed: @"transfer-encoding"];
if (hdr == nil)
{
hdr = [document headerNamed: @"content-transfer-encoding"];
}
else if ([[hdr objectForKey: @"Value"] isEqual: @"chunked"] == YES)
{
/*
* Chunked transfer encoding overrides any content length spec.
*/
expect = 0;
}
context = [self contextFor: hdr];
RETAIN(context);
}
if ([context atEnd] == YES)
{
inBody = NO;
complete = YES;
if ([d length] > 0)
{
NSLog(@"Additional data ignored after parse complete");
}
result = YES; /* Nothing more to do */
}
else if (boundary == nil)
{ {
NSDictionary *typeInfo; NSDictionary *typeInfo;
NSString *type; NSString *type;
@ -1517,25 +1562,19 @@ parseCharacterSet(NSString *token)
if ([type isEqualToString: @"multipart"] == YES) if ([type isEqualToString: @"multipart"] == YES)
{ {
NSLog(@"multipart decode attempt without boundary"); NSLog(@"multipart decode attempt without boundary");
return NO; inBody = NO;
complete = YES;
result = NO;
} }
else else
{ {
if ([context atEnd] == YES)
{
if ([d length] > 0)
{
NSLog(@"Additional data ignored after parse complete");
}
return YES; /* Nothing more to do */
}
[self decodeData: d [self decodeData: d
fromRange: NSMakeRange(0, [d length]) fromRange: NSMakeRange(0, [d length])
intoData: data intoData: data
withContext: context]; withContext: context];
if ([context atEnd] == YES) if ([context atEnd] == YES
|| (expect > 0 && rawBodyLength >= expect))
{ {
inBody = NO; inBody = NO;
complete = YES; complete = YES;
@ -1570,7 +1609,7 @@ parseCharacterSet(NSString *token)
[document setContent: AUTORELEASE([data copy])]; [document setContent: AUTORELEASE([data copy])];
} }
} }
return YES; result = YES;
} }
} }
else else
@ -1691,9 +1730,17 @@ parseCharacterSet(NSString *token)
sectionStart = 0; sectionStart = 0;
} }
} }
return YES; /*
* Check to see if we have reached content length.
*/
if (expect > 0 && rawBodyLength >= expect)
{
complete = YES;
inBody = NO;
}
result = YES;
} }
return NO; return result;
} }
- (BOOL) _unfoldHeader - (BOOL) _unfoldHeader
@ -1738,7 +1785,6 @@ parseCharacterSet(NSString *token)
if (lineEnd == lineStart) if (lineEnd == lineStart)
{ {
unsigned lengthRemaining; unsigned lengthRemaining;
NSDictionary *hdr;
/* /*
* Overwrite the header data with the body, ready to start * Overwrite the header data with the body, ready to start
@ -1756,19 +1802,7 @@ parseCharacterSet(NSString *token)
lineStart = 0; lineStart = 0;
lineEnd = 0; lineEnd = 0;
input = 0; input = 0;
/*
* At end of headers - set up context for decoding data.
*/
inBody = YES; inBody = YES;
DESTROY(context);
hdr = [document headerNamed: @"content-transfer-encoding"];
if (hdr == nil)
{
hdr = [document headerNamed: @"transfer-encoding"];
}
context = [self contextFor: hdr];
RETAIN(context);
} }
} }
} }