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 Frith-MacDonald 2000-11-17 21:09:40 +00:00
parent ed237d6ba9
commit 7c297f6781
4 changed files with 90 additions and 38 deletions

View file

@ -4,6 +4,7 @@
* Headers/Foundation/NSURLHandle.h: Added some more property keys.
* Source/GSMime.m: Update to add method for general decoding of
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/NSURLHandle.m: Register class for http and https support.
* Source/externs.m: Added property keys for URL handles.

View file

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

View file

@ -38,7 +38,7 @@
#include <Foundation/GSMime.h>
#include <string.h>
static NSString *httpVersion = @"1.0";
static NSString *httpVersion = @"1.1";
char emp[64] = {
'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];
[parser parse: d];
if ([d length] == 0)
if ([parser isComplete] == YES)
{
NSDictionary *info;
NSString *val;
@ -215,6 +215,16 @@ static NSLock *urlLock = nil;
str = [str initWithData: dat encoding: NSASCIIStringEncoding];
range = [str rangeOfString: @"\n\n"
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)
{
[nc removeObserver: self
@ -375,12 +385,12 @@ static NSLock *urlLock = 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];
}
else
{
cmd = [NSString stringWithFormat: @"CONNECT %@:%@ HTTP/%@\n\n",
cmd = [NSString stringWithFormat: @"CONNECT %@:%@ HTTP/%@\r\n\r\n",
[url host], [url port], httpVersion];
}
@ -409,30 +419,35 @@ static NSLock *urlLock = nil;
return;
}
}
/*
* Set up request - differs for proxy version unless tunneling via ssl.
*/
if ([request objectForKey: GSHTTPPropertyMethodKey] == nil)
{
[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],
[url host], [url path]];
if ([[url query] length] > 0)
{
[s appendFormat: @"?%@", [url query]];
}
[s appendFormat: @" HTTP/%@\n", httpVersion];
[s appendFormat: @" HTTP/%@\r\n", httpVersion];
}
else // no proxy
{
s = [[NSMutableString alloc] initWithFormat: @"\n%@ %@",
s = [[NSMutableString alloc] initWithFormat: @"%@ %@",
[request objectForKey: GSHTTPPropertyMethodKey], [url path]];
if ([[url query] length] > 0)
{
[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]))

View file

@ -794,7 +794,6 @@ parseCharacterSet(NSString *token)
{
data = [[NSMutableData alloc] init];
document = [[GSMimeDocument alloc] init];
context = [[GSMimeCodingContext alloc] init];
}
return self;
}
@ -1507,7 +1506,53 @@ parseCharacterSet(NSString *token)
- (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;
NSString *type;
@ -1517,25 +1562,19 @@ parseCharacterSet(NSString *token)
if ([type isEqualToString: @"multipart"] == YES)
{
NSLog(@"multipart decode attempt without boundary");
return NO;
inBody = NO;
complete = YES;
result = NO;
}
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
fromRange: NSMakeRange(0, [d length])
intoData: data
withContext: context];
if ([context atEnd] == YES)
if ([context atEnd] == YES
|| (expect > 0 && rawBodyLength >= expect))
{
inBody = NO;
complete = YES;
@ -1570,7 +1609,7 @@ parseCharacterSet(NSString *token)
[document setContent: AUTORELEASE([data copy])];
}
}
return YES;
result = YES;
}
}
else
@ -1691,9 +1730,17 @@ parseCharacterSet(NSString *token)
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
@ -1738,7 +1785,6 @@ parseCharacterSet(NSString *token)
if (lineEnd == lineStart)
{
unsigned lengthRemaining;
NSDictionary *hdr;
/*
* Overwrite the header data with the body, ready to start
@ -1756,19 +1802,7 @@ parseCharacterSet(NSString *token)
lineStart = 0;
lineEnd = 0;
input = 0;
/*
* At end of headers - set up context for decoding data.
*/
inBody = YES;
DESTROY(context);
hdr = [document headerNamed: @"content-transfer-encoding"];
if (hdr == nil)
{
hdr = [document headerNamed: @"transfer-encoding"];
}
context = [self contextFor: hdr];
RETAIN(context);
}
}
}