From 773dafd7332e26f5c76a36a2132af6ba1bd91e55 Mon Sep 17 00:00:00 2001 From: Richard Frith-Macdonald Date: Sun, 29 Sep 2002 09:47:43 +0000 Subject: [PATCH] Simplified ssl support. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14602 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 1 + SSL/GSSSLHandle.m | 420 +--------------------------------------------- 2 files changed, 10 insertions(+), 411 deletions(-) diff --git a/ChangeLog b/ChangeLog index 22fcdd28c..ab478f60f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ * Source/GSFileHandle.m: Encapsulate read and write operations in new low level methods to ease subclassing. + * SSL/GSSSLHandle.m: Use new read and write methods to simplify. 2002-09-28 Richard Frith-Macdonald diff --git a/SSL/GSSSLHandle.m b/SSL/GSSSLHandle.m index 1b0efb300..3109fb552 100644 --- a/SSL/GSSSLHandle.m +++ b/SSL/GSSSLHandle.m @@ -111,49 +111,6 @@ static NSString* NotificationKey = @"NSFileHandleNotificationKey"; } } -- (NSData*) availableData -{ - char buf[NETBUF_SIZE]; - NSMutableData *d; - int len; - - [self checkRead]; - if (isNonBlocking == YES) - [self setNonBlocking: NO]; - d = [NSMutableData dataWithCapacity: 0]; - if (isSocket) - { - if (connected) - { - if ((len = SSL_read(ssl, buf, sizeof(buf))) > 0) - { - [d appendBytes: buf length: len]; - } - } - else - { - if ((len = recv(descriptor, buf, sizeof(buf), 0)) > 0) - { - [d appendBytes: buf length: len]; - } - } - } - else - { - while ((len = read(descriptor, buf, sizeof(buf))) > 0) - { - [d appendBytes: buf length: len]; - } - } - if (len < 0) - { - [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; - } - return d; -} - - (void) closeFile { [self sslDisconnect]; @@ -166,326 +123,13 @@ static NSString* NotificationKey = @"NSFileHandleNotificationKey"; [super gcFinalize]; } -- (NSData*) readDataOfLength: (unsigned)len +- (int) read: (void*)buf length: (int)len { - NSMutableData *d; - int got; - - [self checkRead]; - if (isNonBlocking == YES) - [self setNonBlocking: NO]; - if (len <= 65536) + if (connected) { - char *buf; - - buf = NSZoneMalloc(NSDefaultMallocZone(), len); - d = [NSMutableData dataWithBytesNoCopy: buf length: len]; - if ((got = SSL_read(ssl, [d mutableBytes], len)) < 0) - { - [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; - } - [d setLength: got]; - } - else - { - char buf[NETBUF_SIZE]; - - d = [NSMutableData dataWithCapacity: 0]; - do - { - int chunk = len > sizeof(buf) ? sizeof(buf) : len; - - if (connected) - { - got = SSL_read(ssl, buf, chunk); - } - else if (isSocket) - { - got = recv(descriptor, buf, chunk, 0); - } - else - { - got = read(descriptor, buf, chunk); - } - if (got > 0) - { - [d appendBytes: buf length: got]; - len -= got; - } - else if (got < 0) - { - [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; - } - } - while (len > 0 && got > 0); - } - return d; -} - -- (NSData*) readDataToEndOfFile -{ - char buf[NETBUF_SIZE]; - NSMutableData *d; - int len; - - [self checkRead]; - if (isNonBlocking == YES) - [self setNonBlocking: NO]; - d = [NSMutableData dataWithCapacity: 0]; - if (isSocket) - { - if (connected) - { - while ((len = SSL_read(ssl, buf, sizeof(buf))) > 0) - { - [d appendBytes: buf length: len]; - } - } - else - { - while ((len = recv(descriptor, buf, sizeof(buf), 0)) > 0) - { - [d appendBytes: buf length: len]; - } - } - } - else - { - while ((len = read(descriptor, buf, sizeof(buf))) > 0) - { - [d appendBytes: buf length: len]; - } - } - if (len < 0) - { - [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; - } - return d; -} - -- (void) receivedEvent: (void*)data - type: (RunLoopEventType)type - extra: (void*)extra - forMode: (NSString*)mode -{ - NSString *operation; - - NSDebugMLLog(@"NSFileHandle", @"%@ event: %d", self, type); - - if (isNonBlocking == NO) - { - [self setNonBlocking: YES]; - } - - if (type == ET_RDESC) - { - operation = [readInfo objectForKey: NotificationKey]; - if (operation == NSFileHandleConnectionAcceptedNotification) - { - struct sockaddr_in buf; - int desc; - int blen = sizeof(buf); - - desc = accept(descriptor, (struct sockaddr*)&buf, &blen); - if (desc < 0) - { - NSString *s; - - s = [NSString stringWithFormat: @"Accept attempt failed - %s", - GSLastErrorStr(errno)]; - [readInfo setObject: s forKey: GSFileHandleNotificationError]; - } - else - { // Accept attempt completed. - GSSSLHandle *h; - struct sockaddr_in sin; - int size = sizeof(sin); - - h = [[GSSSLHandle alloc] initWithFileDescriptor: desc - closeOnDealloc: YES]; - getpeername(desc, (struct sockaddr*)&sin, &size); - [h setAddr: &sin]; - [readInfo setObject: h - forKey: NSFileHandleNotificationFileHandleItem]; - RELEASE(h); - } - [self postReadNotification]; - } - else if (operation == NSFileHandleDataAvailableNotification) - { - [self postReadNotification]; - } - else - { - NSMutableData *item; - int length; - int received = 0; - char buf[NETBUF_SIZE]; - - item = [readInfo objectForKey: NSFileHandleNotificationDataItem]; - /* - * We may have a maximum data size set... - */ - if (readMax > 0) - { - length = readMax - [item length]; - if (length > sizeof(buf)) - { - length = sizeof(buf); - } - } - else - { - length = sizeof(buf); - } - -#if USE_ZLIB - if (gzDescriptor != 0) - { - received = gzread(gzDescriptor, buf, length); - } - else -#endif - if (isSocket) - { - if (connected) - { - received = SSL_read(ssl, buf, length); - } - else - { - received = recv(descriptor, buf, length, 0); - } - } - else - { - received = read(descriptor, buf, length); - } - if (received == 0) - { // Read up to end of file. - [self postReadNotification]; - } - else if (received < 0) - { - if (errno != EAGAIN && errno != EINTR) - { - NSString *s; - - s = [NSString stringWithFormat: @"Read attempt failed - %s", - GSLastErrorStr(errno)]; - [readInfo setObject: s forKey: GSFileHandleNotificationError]; - [self postReadNotification]; - } - } - else - { - [item appendBytes: buf length: received]; - if (readMax < 0 || (readMax > 0 && [item length] == readMax)) - { - // Read a single chunk of data - [self postReadNotification]; - } - } - } - } - else - { - extern NSString * const GSSOCKSConnect; - NSMutableDictionary *info; - - info = [writeInfo objectAtIndex: 0]; - operation = [info objectForKey: NotificationKey]; - if (operation == GSFileHandleConnectCompletionNotification - || operation == GSSOCKSConnect) - { // Connection attempt completed. - int result; - int len = sizeof(result); - - if (getsockopt(descriptor, SOL_SOCKET, SO_ERROR, - (char*)&result, &len) == 0 && result != 0) - { - NSString *s; - - s = [NSString stringWithFormat: @"Connect attempt failed - %s", - GSLastErrorStr(result)]; - [info setObject: s forKey: GSFileHandleNotificationError]; - } - else - { - readOK = YES; - writeOK = YES; - } - connectOK = NO; - [self postWriteNotification]; - } - else - { - NSData *item; - int length; - const void *ptr; - - item = [info objectForKey: NSFileHandleNotificationDataItem]; - length = [item length]; - ptr = [item bytes]; - if (writePos < length) - { - int written; - -#if USE_ZLIB - if (gzDescriptor != 0) - { - written = gzwrite(gzDescriptor, (char*)ptr+writePos, - length-writePos); - } - else -#endif - if (isSocket) - { - if (connected) - { - written = SSL_write(ssl, (char*)ptr + writePos, - length - writePos); - } - else - { - written = send(descriptor, (char*)ptr + writePos, - length - writePos, 0); - } - } - else - { - written = write(descriptor, (char*)ptr + writePos, - length - writePos); - } - if (written <= 0) - { - if (written < 0 && errno != EAGAIN && errno != EINTR) - { - NSString *s; - - s = [NSString stringWithFormat: - @"Write attempt failed - %s", GSLastErrorStr(errno)]; - [info setObject: s forKey: GSFileHandleNotificationError]; - [self postWriteNotification]; - } - } - else - { - writePos += written; - } - } - if (writePos >= length) - { // Write operation completed. - [self postWriteNotification]; - } - } + return SSL_read(ssl, buf, len); } + return [super read: buf length: len]; } - (BOOL) sslConnect @@ -645,60 +289,14 @@ static NSString* NotificationKey = @"NSFileHandleNotificationKey"; } } -- (void) writeData: (NSData*)item +- (int) write: (const void*)buf length: (int)len { - int rval = 0; - const void *ptr = [item bytes]; - unsigned int len = [item length]; - unsigned int pos = 0; - - [self checkWrite]; - if (isNonBlocking == YES) + if (connected) { - [self setNonBlocking: NO]; - } - while (pos < len) - { - int toWrite = len - pos; - - if (toWrite > NETBUF_SIZE) - { - toWrite = NETBUF_SIZE; - } - if (isSocket) - { - if (connected) - { - rval = SSL_write(ssl, (char*)ptr+pos, toWrite); - } - else - { - rval = send(descriptor, (char*)ptr+pos, toWrite, 0); - } - } - else - { - rval = write(descriptor, (char*)ptr+pos, toWrite); - } - if (rval < 0) - { - if (errno == EAGAIN == errno == EINTR) - { - rval = 0; - } - else - { - break; - } - } - pos += rval; - } - if (rval < 0) - { - [NSException raise: NSFileHandleOperationException - format: @"unable to write to descriptor - %s", - GSLastErrorStr(errno)]; + return SSL_write(ssl, buf, len); } + return [super write: buf length: len]; } + @end