mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 08:21:25 +00:00
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:
parent
dea84cb25d
commit
773dafd733
2 changed files with 10 additions and 411 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
* Source/GSFileHandle.m: Encapsulate read and write operations in
|
* Source/GSFileHandle.m: Encapsulate read and write operations in
|
||||||
new low level methods to ease subclassing.
|
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>
|
2002-09-28 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
|
|
@ -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
|
- (void) closeFile
|
||||||
{
|
{
|
||||||
[self sslDisconnect];
|
[self sslDisconnect];
|
||||||
|
@ -166,326 +123,13 @@ static NSString* NotificationKey = @"NSFileHandleNotificationKey";
|
||||||
[super gcFinalize];
|
[super gcFinalize];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSData*) readDataOfLength: (unsigned)len
|
- (int) read: (void*)buf length: (int)len
|
||||||
{
|
{
|
||||||
NSMutableData *d;
|
if (connected)
|
||||||
int got;
|
|
||||||
|
|
||||||
[self checkRead];
|
|
||||||
if (isNonBlocking == YES)
|
|
||||||
[self setNonBlocking: NO];
|
|
||||||
if (len <= 65536)
|
|
||||||
{
|
{
|
||||||
char *buf;
|
return SSL_read(ssl, buf, len);
|
||||||
|
|
||||||
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 [super read: buf length: len];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) sslConnect
|
- (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;
|
if (connected)
|
||||||
const void *ptr = [item bytes];
|
|
||||||
unsigned int len = [item length];
|
|
||||||
unsigned int pos = 0;
|
|
||||||
|
|
||||||
[self checkWrite];
|
|
||||||
if (isNonBlocking == YES)
|
|
||||||
{
|
{
|
||||||
[self setNonBlocking: NO];
|
return SSL_write(ssl, buf, len);
|
||||||
}
|
|
||||||
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 [super write: buf length: len];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue