Some ssl tunnelling fixes

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@11345 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2001-11-08 21:19:25 +00:00
parent b516edc3dc
commit bfbe347d29
2 changed files with 81 additions and 41 deletions

View file

@ -201,8 +201,7 @@ static NSLock *urlLock = nil;
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
NSDictionary *dict = [not userInfo]; NSDictionary *dict = [not userInfo];
NSData *d; NSData *d;
NSString *str; GSMimeParser *p = [GSMimeParser new];
NSRange range;
d = [dict objectForKey: NSFileHandleNotificationDataItem]; d = [dict objectForKey: NSFileHandleNotificationDataItem];
@ -210,21 +209,28 @@ static NSLock *urlLock = nil;
{ {
[dat appendData: d]; [dat appendData: d];
} }
str = [NSString alloc]; [p parse: dat];
str = [str initWithData: dat encoding: NSASCIIStringEncoding]; if ([p isInBody] == YES)
range = [str rangeOfString: @"\n\n"
options: NSCaseInsensitiveSearch];
if (range.length == 0)
{ {
range = [str rangeOfString: @"\r\n\r\n" NSDictionary *info = [[p document] headerNamed: @"http"];
options: NSCaseInsensitiveSearch]; NSString *val;
if (range.length == 0)
{ val = [info objectForKey: NSHTTPPropertyServerHTTPVersionKey];
range = [str rangeOfString: @"\r\r" if (val != nil)
options: NSCaseInsensitiveSearch]; [pageInfo setObject: val forKey: NSHTTPPropertyServerHTTPVersionKey];
} val = [info objectForKey: NSHTTPPropertyStatusCodeKey];
if (val != nil)
[pageInfo setObject: val forKey: NSHTTPPropertyStatusCodeKey];
val = [info objectForKey: NSHTTPPropertyStatusReasonKey];
if (val != nil)
[pageInfo setObject: val forKey: NSHTTPPropertyStatusReasonKey];
[nc removeObserver: self
name: NSFileHandleReadCompletionNotification
object: sock];
[dat setLength: 0];
tunnel = NO;
} }
if ([d length] == 0 || range.length > 0) else if ([d length] == 0)
{ {
[nc removeObserver: self [nc removeObserver: self
name: NSFileHandleReadCompletionNotification name: NSFileHandleReadCompletionNotification
@ -235,7 +241,7 @@ static NSLock *urlLock = nil;
{ {
[sock readInBackgroundAndNotify]; [sock readInBackgroundAndNotify];
} }
RELEASE(str); RELEASE(p);
} }
- (void) loadInBackground - (void) loadInBackground
@ -382,10 +388,12 @@ static NSLock *urlLock = nil;
if ([[url scheme] isEqualToString: @"https"] if ([[url scheme] isEqualToString: @"https"]
&& [[request objectForKey: GSHTTPPropertyProxyHostKey] length] > 0) && [[request objectForKey: GSHTTPPropertyProxyHostKey] length] > 0)
{ {
NSRunLoop *loop = [NSRunLoop currentRunLoop]; NSRunLoop *loop = [NSRunLoop currentRunLoop];
NSString *cmd; NSString *cmd;
NSTimeInterval last = 0.0; NSTimeInterval last = 0.0;
NSTimeInterval limit = 0.01; NSTimeInterval limit = 0.01;
NSDate *when;
NSString *status;
if ([url port] == nil) if ([url port] == nil)
{ {
@ -398,24 +406,41 @@ static NSLock *urlLock = nil;
[url host], [url port], httpVersion]; [url host], [url port], httpVersion];
} }
[sock writeInBackgroundAndNotify: /*
[cmd dataUsingEncoding: NSASCIIStringEncoding]]; * Set up default status for if connection is lost.
*/
[pageInfo setObject: @"1.0" forKey: NSHTTPPropertyServerHTTPVersionKey];
[pageInfo setObject: @"503" forKey: NSHTTPPropertyStatusCodeKey];
[pageInfo setObject: @"Connection dropped by proxy server"
forKey: NSHTTPPropertyStatusReasonKey];
tunnel = YES; tunnel = YES;
[nc addObserver: self [nc addObserver: self
selector: @selector(bgdWrite:) selector: @selector(bgdWrite:)
name: GSFileHandleWriteCompletionNotification name: GSFileHandleWriteCompletionNotification
object: sock]; object: sock];
[sock writeInBackgroundAndNotify:
[cmd dataUsingEncoding: NSASCIIStringEncoding]];
when = [NSDate alloc];
while (tunnel == YES) while (tunnel == YES)
{ {
NSDate *when;
NSTimeInterval tmp = limit; NSTimeInterval tmp = limit;
limit += last; limit += last;
last = tmp; last = tmp;
when = [[NSDate alloc] initWithTimeIntervalSinceNow: limit]; when = [when initWithTimeIntervalSinceNow: limit];
[loop runUntilDate: when]; [loop runUntilDate: when];
RELEASE(when); }
RELEASE(when);
status = [pageInfo objectForKey: NSHTTPPropertyStatusCodeKey];
if ([status isEqual: @"200"] == NO)
{
[self endLoadInBackground];
[self backgroundLoadDidFailWithReason: @"Failed proxy tunneling"];
return;
} }
} }
if ([[url scheme] isEqualToString: @"https"]) if ([[url scheme] isEqualToString: @"https"])

View file

@ -1956,61 +1956,76 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
ret = SSL_set_fd(ssl, descriptor); ret = SSL_set_fd(ssl, descriptor);
loop = [NSRunLoop currentRunLoop]; loop = [NSRunLoop currentRunLoop];
[loop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]]; [loop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
ret = SSL_connect(ssl); ret = SSL_connect(ssl);
if (ret != 1) if (ret != 1)
{ {
int count = 1; int e = errno;
NSDate *final;
NSDate *when;
NSTimeInterval last = 0.0;
NSTimeInterval limit = 0.1;
final = [[NSDate alloc] initWithTimeIntervalSinceNow: 20.0];
when = [NSDate alloc];
err = SSL_get_error(ssl, ret); err = SSL_get_error(ssl, ret);
while (err == SSL_ERROR_WANT_READ && count < 10) while ((err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
&& [final timeIntervalSinceNow] > 0.0)
{ {
[loop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]]; NSTimeInterval tmp = limit;
limit += last;
last = tmp;
when = [when initWithTimeIntervalSinceNow: limit];
[loop runUntilDate: when];
ret = SSL_connect(ssl); ret = SSL_connect(ssl);
if (ret != 1) if (ret != 1)
{ {
e = errno;
err = SSL_get_error(ssl, ret); err = SSL_get_error(ssl, ret);
count++;
} }
else else
{ {
err = 0; err = SSL_ERROR_NONE;
} }
} }
//NSLog(@"Number of attempts: %d", count); RELEASE(when);
RELEASE(final);
if (err != SSL_ERROR_NONE) if (err != SSL_ERROR_NONE)
{ {
NSString *err; NSString *str;
switch (SSL_get_error(ssl, ret)) switch (err)
{ {
case SSL_ERROR_NONE: case SSL_ERROR_NONE:
err = @"No error: really helpful"; str = @"No error: really helpful";
break; break;
case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_ZERO_RETURN:
err = @"Zero Return error"; str = @"Zero Return error";
break; break;
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
err = @"Want Read Error"; str = @"Want Read Error";
break; break;
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
err = @"Want Write Error"; str = @"Want Write Error";
break; break;
case SSL_ERROR_WANT_X509_LOOKUP: case SSL_ERROR_WANT_X509_LOOKUP:
err = @"Want X509 Lookup Error"; str = @"Want X509 Lookup Error";
break; break;
case SSL_ERROR_SYSCALL: case SSL_ERROR_SYSCALL:
err = @"Syscall Error - %s", GSLastErrorStr(errno); str = [NSString stringWithFormat: @"Syscall error %d - %s",
e, GSLastErrorStr(e)];
break; break;
case SSL_ERROR_SSL: case SSL_ERROR_SSL:
err = @"SSL Error: really helpful"; str = @"SSL Error: really helpful";
break; break;
default: default:
err = @"Standard Unix Error: really helpful"; str = @"Standard Unix Error: really helpful";
break; break;
} }
NSLog(@"unable to make SSL connection to %@:%@ - %@", NSLog(@"unable to make SSL connection to %@:%@ - %@",
address, service, err); address, service, str);
return NO; return NO;
} }
} }