Simplified ssl support.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14602 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2002-09-29 09:47:43 +00:00
parent dea84cb25d
commit 773dafd733
2 changed files with 10 additions and 411 deletions

View file

@ -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 <rfm@gnu.org>

View file

@ -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