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) unsigned long SSLError;
|
||||||
@property (readonly, nonatomic) long verifyResult;
|
@property (readonly, nonatomic) long verifyResult;
|
||||||
|
|
||||||
+ (instancetype)exceptionWithHost: (OFString *)host
|
+ (instancetype)exceptionWithHost: (nullable OFString *)host
|
||||||
port: (uint16_t)port
|
port: (uint16_t)port
|
||||||
socket: (id)socket OF_UNAVAILABLE;
|
socket: (id)socket OF_UNAVAILABLE;
|
||||||
+ (instancetype)exceptionWithHost: (OFString *)host
|
+ (instancetype)exceptionWithHost: (nullable OFString *)host
|
||||||
port: (uint16_t)port
|
port: (uint16_t)port
|
||||||
socket: (id)socket
|
socket: (id)socket
|
||||||
errNo: (int)errNo OF_UNAVAILABLE;
|
errNo: (int)errNo OF_UNAVAILABLE;
|
||||||
|
@ -51,22 +51,22 @@ OF_ASSUME_NONNULL_BEGIN
|
||||||
socket: (SSLSocket *)socket
|
socket: (SSLSocket *)socket
|
||||||
SSLError: (unsigned long)SSLError
|
SSLError: (unsigned long)SSLError
|
||||||
verifyResult: (long)verifyResult;
|
verifyResult: (long)verifyResult;
|
||||||
- initWithHost: (OFString *)host
|
- (instancetype)initWithHost: (nullable OFString *)host
|
||||||
port: (uint16_t)port
|
port: (uint16_t)port
|
||||||
socket: (id)socket OF_UNAVAILABLE;
|
socket: (id)socket OF_UNAVAILABLE;
|
||||||
- initWithHost: (OFString *)host
|
- (instancetype)initWithHost: (nullable OFString *)host
|
||||||
port: (uint16_t)port
|
port: (uint16_t)port
|
||||||
socket: (id)socket
|
socket: (id)socket
|
||||||
errNo: (int)errNo OF_UNAVAILABLE;
|
errNo: (int)errNo OF_UNAVAILABLE;
|
||||||
- initWithHost: (OFString *)host
|
- (instancetype)initWithHost: (OFString *)host
|
||||||
port: (uint16_t)port
|
port: (uint16_t)port
|
||||||
socket: (SSLSocket *)socket
|
socket: (SSLSocket *)socket
|
||||||
SSLError: (unsigned long)SSLError;
|
SSLError: (unsigned long)SSLError;
|
||||||
- initWithHost: (OFString *)host
|
- (instancetype)initWithHost: (OFString *)host
|
||||||
port: (uint16_t)port
|
port: (uint16_t)port
|
||||||
socket: (SSLSocket *)socket
|
socket: (SSLSocket *)socket
|
||||||
SSLError: (unsigned long)SSLError
|
SSLError: (unsigned long)SSLError
|
||||||
verifyResult: (long)verifyResult OF_DESIGNATED_INITIALIZER;
|
verifyResult: (long)verifyResult OF_DESIGNATED_INITIALIZER;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
OF_ASSUME_NONNULL_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 ()
|
@interface SSLSocket ()
|
||||||
|
- (void)SSL_startTLSWithExpectedHost: (OFString *)host
|
||||||
|
port: (uint16_t)port;
|
||||||
- (void)SSL_super_close;
|
- (void)SSL_super_close;
|
||||||
@end
|
@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
|
@implementation SSLSocket
|
||||||
@synthesize delegate = _delegate, certificateFile = _certificateFile;
|
@synthesize delegate = _delegate, certificateFile = _certificateFile;
|
||||||
@synthesize privateKeyFile = _privateKeyFile;
|
@synthesize privateKeyFile = _privateKeyFile;
|
||||||
|
@ -281,16 +356,58 @@ locking_callback(int mode, int n, const char *file, int line)
|
||||||
port: 0];
|
port: 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)connectToHost: (OFString *)host
|
- (void)asyncConnectToHost: (OFString *)host
|
||||||
port: (uint16_t)port
|
port: (uint16_t)port
|
||||||
|
runLoopMode: (of_run_loop_mode_t)runLoopMode
|
||||||
|
target: (id)target
|
||||||
|
selector: (SEL)selector
|
||||||
|
context: (id)userContext
|
||||||
{
|
{
|
||||||
[super connectToHost: host
|
void *pool = objc_autoreleasePoolPush();
|
||||||
port: port];
|
SSLSocket_ConnectContext *context;
|
||||||
|
|
||||||
[self SSL_startTLSWithExpectedHost: host
|
context = [[[SSLSocket_ConnectContext alloc]
|
||||||
port: port];
|
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
|
- (instancetype)accept
|
||||||
{
|
{
|
||||||
SSLSocket *client = (SSLSocket *)[super accept];
|
SSLSocket *client = (SSLSocket *)[super accept];
|
||||||
|
|
Reference in a new issue