mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-29 16:01:38 +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
|
||||
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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue