Support for async connecting
This commit is contained in:
parent
9c45593f47
commit
2fdbf231bb
2 changed files with 141 additions and 24 deletions
|
@ -35,10 +35,10 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
@property (readonly, nonatomic) unsigned long SSLError;
|
||||
@property (readonly, nonatomic) long verifyResult;
|
||||
|
||||
+ (instancetype)exceptionWithHost: (OFString *)host
|
||||
+ (instancetype)exceptionWithHost: (nullable OFString *)host
|
||||
port: (uint16_t)port
|
||||
socket: (id)socket OF_UNAVAILABLE;
|
||||
+ (instancetype)exceptionWithHost: (OFString *)host
|
||||
+ (instancetype)exceptionWithHost: (nullable OFString *)host
|
||||
port: (uint16_t)port
|
||||
socket: (id)socket
|
||||
errNo: (int)errNo OF_UNAVAILABLE;
|
||||
|
@ -51,22 +51,22 @@ OF_ASSUME_NONNULL_BEGIN
|
|||
socket: (SSLSocket *)socket
|
||||
SSLError: (unsigned long)SSLError
|
||||
verifyResult: (long)verifyResult;
|
||||
- initWithHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
socket: (id)socket OF_UNAVAILABLE;
|
||||
- initWithHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
socket: (id)socket
|
||||
errNo: (int)errNo OF_UNAVAILABLE;
|
||||
- initWithHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
socket: (SSLSocket *)socket
|
||||
SSLError: (unsigned long)SSLError;
|
||||
- initWithHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
socket: (SSLSocket *)socket
|
||||
SSLError: (unsigned long)SSLError
|
||||
verifyResult: (long)verifyResult OF_DESIGNATED_INITIALIZER;
|
||||
- (instancetype)initWithHost: (nullable OFString *)host
|
||||
port: (uint16_t)port
|
||||
socket: (id)socket OF_UNAVAILABLE;
|
||||
- (instancetype)initWithHost: (nullable OFString *)host
|
||||
port: (uint16_t)port
|
||||
socket: (id)socket
|
||||
errNo: (int)errNo OF_UNAVAILABLE;
|
||||
- (instancetype)initWithHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
socket: (SSLSocket *)socket
|
||||
SSLError: (unsigned long)SSLError;
|
||||
- (instancetype)initWithHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
socket: (SSLSocket *)socket
|
||||
SSLError: (unsigned long)SSLError
|
||||
verifyResult: (long)verifyResult OF_DESIGNATED_INITIALIZER;
|
||||
@end
|
||||
|
||||
OF_ASSUME_NONNULL_END
|
||||
|
|
129
src/SSLSocket.m
129
src/SSLSocket.m
|
@ -91,9 +91,84 @@ locking_callback(int mode, int n, const char *file, int line)
|
|||
}
|
||||
|
||||
@interface SSLSocket ()
|
||||
- (void)SSL_startTLSWithExpectedHost: (OFString *)host
|
||||
port: (uint16_t)port;
|
||||
- (void)SSL_super_close;
|
||||
@end
|
||||
|
||||
@interface SSLSocket_ConnectContext: OFObject
|
||||
{
|
||||
OFString *_host;
|
||||
uint16_t _port;
|
||||
id _target;
|
||||
SEL _selector;
|
||||
id _context;
|
||||
}
|
||||
|
||||
- (instancetype)initWithHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
target: (id)target
|
||||
selector: (SEL)selector
|
||||
context: (id)context;
|
||||
- (void)socketDidConnect: (SSLSocket *)sock
|
||||
context: (id)context
|
||||
exception: (id)exception;
|
||||
@end
|
||||
|
||||
@implementation SSLSocket_ConnectContext
|
||||
- (instancetype)initWithHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
target: (id)target
|
||||
selector: (SEL)selector
|
||||
context: (id)context
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
@try {
|
||||
_host = [host copy];
|
||||
_port = port;
|
||||
_target = [target retain];
|
||||
_selector = selector;
|
||||
_context = [context retain];
|
||||
} @catch (id e) {
|
||||
[self release];
|
||||
@throw e;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_host release];
|
||||
[_target release];
|
||||
[_context release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)socketDidConnect: (SSLSocket *)sock
|
||||
context: (id)context
|
||||
exception: (id)exception
|
||||
{
|
||||
void (*func)(id, SEL, OFTCPSocket *, id, id) =
|
||||
(void (*)(id, SEL, OFTCPSocket *, id, id))
|
||||
[_target methodForSelector: _selector];
|
||||
|
||||
if (exception == nil) {
|
||||
@try {
|
||||
[sock SSL_startTLSWithExpectedHost: _host
|
||||
port: _port];
|
||||
} @catch (id e) {
|
||||
func(_target, _selector, sock, _context, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
func(_target, _selector, sock, _context, exception);
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation SSLSocket
|
||||
@synthesize delegate = _delegate, certificateFile = _certificateFile;
|
||||
@synthesize privateKeyFile = _privateKeyFile;
|
||||
|
@ -281,16 +356,58 @@ locking_callback(int mode, int n, const char *file, int line)
|
|||
port: 0];
|
||||
}
|
||||
|
||||
- (void)connectToHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
- (void)asyncConnectToHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
runLoopMode: (of_run_loop_mode_t)runLoopMode
|
||||
target: (id)target
|
||||
selector: (SEL)selector
|
||||
context: (id)userContext
|
||||
{
|
||||
[super connectToHost: host
|
||||
port: port];
|
||||
void *pool = objc_autoreleasePoolPush();
|
||||
SSLSocket_ConnectContext *context;
|
||||
|
||||
[self SSL_startTLSWithExpectedHost: host
|
||||
port: port];
|
||||
context = [[[SSLSocket_ConnectContext alloc]
|
||||
initWithHost: host
|
||||
port: port
|
||||
target: target
|
||||
selector: selector
|
||||
context: userContext] autorelease];
|
||||
[super asyncConnectToHost: host
|
||||
port: port
|
||||
runLoopMode: runLoopMode
|
||||
target: context
|
||||
selector: @selector(socketDidConnect:context:
|
||||
exception:)
|
||||
context: nil];
|
||||
|
||||
objc_autoreleasePoolPop(pool);
|
||||
}
|
||||
|
||||
#ifdef OF_HAVE_BLOCKS
|
||||
- (void)asyncConnectToHost: (OFString *)host
|
||||
port: (uint16_t)port
|
||||
runLoopMode: (of_run_loop_mode_t)runLoopMode
|
||||
block: (of_tcp_socket_async_connect_block_t)block
|
||||
{
|
||||
[super asyncConnectToHost: host
|
||||
port: port
|
||||
runLoopMode: runLoopMode
|
||||
block: ^ (SSLSocket *sock, id exception) {
|
||||
if (exception == nil) {
|
||||
@try {
|
||||
[sock SSL_startTLSWithExpectedHost: host
|
||||
port: port];
|
||||
} @catch (id e) {
|
||||
block(sock, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
block(sock, exception);
|
||||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (instancetype)accept
|
||||
{
|
||||
SSLSocket *client = (SSLSocket *)[super accept];
|
||||
|
|
Reference in a new issue