diff --git a/Source/GSHTTPURLHandle.m b/Source/GSHTTPURLHandle.m index 58ff4b2b9..adc5e14e3 100644 --- a/Source/GSHTTPURLHandle.m +++ b/Source/GSHTTPURLHandle.m @@ -201,8 +201,7 @@ static NSLock *urlLock = nil; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; NSDictionary *dict = [not userInfo]; NSData *d; - NSString *str; - NSRange range; + GSMimeParser *p = [GSMimeParser new]; d = [dict objectForKey: NSFileHandleNotificationDataItem]; @@ -210,21 +209,28 @@ static NSLock *urlLock = nil; { [dat appendData: d]; } - str = [NSString alloc]; - str = [str initWithData: dat encoding: NSASCIIStringEncoding]; - range = [str rangeOfString: @"\n\n" - options: NSCaseInsensitiveSearch]; - if (range.length == 0) + [p parse: dat]; + if ([p isInBody] == YES) { - range = [str rangeOfString: @"\r\n\r\n" - options: NSCaseInsensitiveSearch]; - if (range.length == 0) - { - range = [str rangeOfString: @"\r\r" - options: NSCaseInsensitiveSearch]; - } + NSDictionary *info = [[p document] headerNamed: @"http"]; + NSString *val; + + val = [info objectForKey: NSHTTPPropertyServerHTTPVersionKey]; + if (val != nil) + [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 name: NSFileHandleReadCompletionNotification @@ -235,7 +241,7 @@ static NSLock *urlLock = nil; { [sock readInBackgroundAndNotify]; } - RELEASE(str); + RELEASE(p); } - (void) loadInBackground @@ -382,10 +388,12 @@ static NSLock *urlLock = nil; if ([[url scheme] isEqualToString: @"https"] && [[request objectForKey: GSHTTPPropertyProxyHostKey] length] > 0) { - NSRunLoop *loop = [NSRunLoop currentRunLoop]; - NSString *cmd; + NSRunLoop *loop = [NSRunLoop currentRunLoop]; + NSString *cmd; NSTimeInterval last = 0.0; NSTimeInterval limit = 0.01; + NSDate *when; + NSString *status; if ([url port] == nil) { @@ -398,24 +406,41 @@ static NSLock *urlLock = nil; [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; [nc addObserver: self selector: @selector(bgdWrite:) name: GSFileHandleWriteCompletionNotification object: sock]; + + [sock writeInBackgroundAndNotify: + [cmd dataUsingEncoding: NSASCIIStringEncoding]]; + + when = [NSDate alloc]; while (tunnel == YES) { - NSDate *when; NSTimeInterval tmp = limit; limit += last; last = tmp; - when = [[NSDate alloc] initWithTimeIntervalSinceNow: limit]; + when = [when initWithTimeIntervalSinceNow: limit]; [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"]) diff --git a/Source/UnixFileHandle.m b/Source/UnixFileHandle.m index dd04f2d3d..23589a91a 100644 --- a/Source/UnixFileHandle.m +++ b/Source/UnixFileHandle.m @@ -1956,61 +1956,76 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) ret = SSL_set_fd(ssl, descriptor); loop = [NSRunLoop currentRunLoop]; - [loop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]]; + [loop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]]; ret = SSL_connect(ssl); 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); - 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); if (ret != 1) { + e = errno; err = SSL_get_error(ssl, ret); - count++; } else { - err = 0; + err = SSL_ERROR_NONE; } } - //NSLog(@"Number of attempts: %d", count); + RELEASE(when); + RELEASE(final); if (err != SSL_ERROR_NONE) { - NSString *err; + NSString *str; - switch (SSL_get_error(ssl, ret)) + switch (err) { case SSL_ERROR_NONE: - err = @"No error: really helpful"; + str = @"No error: really helpful"; break; case SSL_ERROR_ZERO_RETURN: - err = @"Zero Return error"; + str = @"Zero Return error"; break; case SSL_ERROR_WANT_READ: - err = @"Want Read Error"; + str = @"Want Read Error"; break; case SSL_ERROR_WANT_WRITE: - err = @"Want Write Error"; + str = @"Want Write Error"; break; case SSL_ERROR_WANT_X509_LOOKUP: - err = @"Want X509 Lookup Error"; + str = @"Want X509 Lookup Error"; break; case SSL_ERROR_SYSCALL: - err = @"Syscall Error - %s", GSLastErrorStr(errno); + str = [NSString stringWithFormat: @"Syscall error %d - %s", + e, GSLastErrorStr(e)]; break; case SSL_ERROR_SSL: - err = @"SSL Error: really helpful"; + str = @"SSL Error: really helpful"; break; default: - err = @"Standard Unix Error: really helpful"; + str = @"Standard Unix Error: really helpful"; break; } NSLog(@"unable to make SSL connection to %@:%@ - %@", - address, service, err); + address, service, str); return NO; } }