Skip to content
This repository was archived by the owner on Dec 2, 2024. It is now read-only.

Commit 2fdbf23

Browse files
committed
Support for async connecting
1 parent 9c45593 commit 2fdbf23

2 files changed

Lines changed: 141 additions & 24 deletions

File tree

src/SSLConnectionFailedException.h

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ OF_ASSUME_NONNULL_BEGIN
3535
@property (readonly, nonatomic) unsigned long SSLError;
3636
@property (readonly, nonatomic) long verifyResult;
3737

38-
+ (instancetype)exceptionWithHost: (OFString *)host
38+
+ (instancetype)exceptionWithHost: (nullable OFString *)host
3939
port: (uint16_t)port
4040
socket: (id)socket OF_UNAVAILABLE;
41-
+ (instancetype)exceptionWithHost: (OFString *)host
41+
+ (instancetype)exceptionWithHost: (nullable OFString *)host
4242
port: (uint16_t)port
4343
socket: (id)socket
4444
errNo: (int)errNo OF_UNAVAILABLE;
@@ -51,22 +51,22 @@ OF_ASSUME_NONNULL_BEGIN
5151
socket: (SSLSocket *)socket
5252
SSLError: (unsigned long)SSLError
5353
verifyResult: (long)verifyResult;
54-
- initWithHost: (OFString *)host
55-
port: (uint16_t)port
56-
socket: (id)socket OF_UNAVAILABLE;
57-
- initWithHost: (OFString *)host
58-
port: (uint16_t)port
59-
socket: (id)socket
60-
errNo: (int)errNo OF_UNAVAILABLE;
61-
- initWithHost: (OFString *)host
62-
port: (uint16_t)port
63-
socket: (SSLSocket *)socket
64-
SSLError: (unsigned long)SSLError;
65-
- initWithHost: (OFString *)host
66-
port: (uint16_t)port
67-
socket: (SSLSocket *)socket
68-
SSLError: (unsigned long)SSLError
69-
verifyResult: (long)verifyResult OF_DESIGNATED_INITIALIZER;
54+
- (instancetype)initWithHost: (nullable OFString *)host
55+
port: (uint16_t)port
56+
socket: (id)socket OF_UNAVAILABLE;
57+
- (instancetype)initWithHost: (nullable OFString *)host
58+
port: (uint16_t)port
59+
socket: (id)socket
60+
errNo: (int)errNo OF_UNAVAILABLE;
61+
- (instancetype)initWithHost: (OFString *)host
62+
port: (uint16_t)port
63+
socket: (SSLSocket *)socket
64+
SSLError: (unsigned long)SSLError;
65+
- (instancetype)initWithHost: (OFString *)host
66+
port: (uint16_t)port
67+
socket: (SSLSocket *)socket
68+
SSLError: (unsigned long)SSLError
69+
verifyResult: (long)verifyResult OF_DESIGNATED_INITIALIZER;
7070
@end
7171

7272
OF_ASSUME_NONNULL_END

src/SSLSocket.m

Lines changed: 123 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,84 @@
9191
}
9292

9393
@interface SSLSocket ()
94+
- (void)SSL_startTLSWithExpectedHost: (OFString *)host
95+
port: (uint16_t)port;
9496
- (void)SSL_super_close;
9597
@end
9698

99+
@interface SSLSocket_ConnectContext: OFObject
100+
{
101+
OFString *_host;
102+
uint16_t _port;
103+
id _target;
104+
SEL _selector;
105+
id _context;
106+
}
107+
108+
- (instancetype)initWithHost: (OFString *)host
109+
port: (uint16_t)port
110+
target: (id)target
111+
selector: (SEL)selector
112+
context: (id)context;
113+
- (void)socketDidConnect: (SSLSocket *)sock
114+
context: (id)context
115+
exception: (id)exception;
116+
@end
117+
118+
@implementation SSLSocket_ConnectContext
119+
- (instancetype)initWithHost: (OFString *)host
120+
port: (uint16_t)port
121+
target: (id)target
122+
selector: (SEL)selector
123+
context: (id)context
124+
{
125+
self = [super init];
126+
127+
@try {
128+
_host = [host copy];
129+
_port = port;
130+
_target = [target retain];
131+
_selector = selector;
132+
_context = [context retain];
133+
} @catch (id e) {
134+
[self release];
135+
@throw e;
136+
}
137+
138+
return self;
139+
}
140+
141+
- (void)dealloc
142+
{
143+
[_host release];
144+
[_target release];
145+
[_context release];
146+
147+
[super dealloc];
148+
}
149+
150+
- (void)socketDidConnect: (SSLSocket *)sock
151+
context: (id)context
152+
exception: (id)exception
153+
{
154+
void (*func)(id, SEL, OFTCPSocket *, id, id) =
155+
(void (*)(id, SEL, OFTCPSocket *, id, id))
156+
[_target methodForSelector: _selector];
157+
158+
if (exception == nil) {
159+
@try {
160+
[sock SSL_startTLSWithExpectedHost: _host
161+
port: _port];
162+
} @catch (id e) {
163+
func(_target, _selector, sock, _context, e);
164+
return;
165+
}
166+
}
167+
168+
func(_target, _selector, sock, _context, exception);
169+
}
170+
@end
171+
97172
@implementation SSLSocket
98173
@synthesize delegate = _delegate, certificateFile = _certificateFile;
99174
@synthesize privateKeyFile = _privateKeyFile;
@@ -281,15 +356,57 @@ - (void)startTLSWithExpectedHost: (OFString *)host
281356
port: 0];
282357
}
283358

284-
- (void)connectToHost: (OFString *)host
285-
port: (uint16_t)port
359+
- (void)asyncConnectToHost: (OFString *)host
360+
port: (uint16_t)port
361+
runLoopMode: (of_run_loop_mode_t)runLoopMode
362+
target: (id)target
363+
selector: (SEL)selector
364+
context: (id)userContext
286365
{
287-
[super connectToHost: host
288-
port: port];
366+
void *pool = objc_autoreleasePoolPush();
367+
SSLSocket_ConnectContext *context;
368+
369+
context = [[[SSLSocket_ConnectContext alloc]
370+
initWithHost: host
371+
port: port
372+
target: target
373+
selector: selector
374+
context: userContext] autorelease];
375+
[super asyncConnectToHost: host
376+
port: port
377+
runLoopMode: runLoopMode
378+
target: context
379+
selector: @selector(socketDidConnect:context:
380+
exception:)
381+
context: nil];
382+
383+
objc_autoreleasePoolPop(pool);
384+
}
289385

290-
[self SSL_startTLSWithExpectedHost: host
291-
port: port];
386+
#ifdef OF_HAVE_BLOCKS
387+
- (void)asyncConnectToHost: (OFString *)host
388+
port: (uint16_t)port
389+
runLoopMode: (of_run_loop_mode_t)runLoopMode
390+
block: (of_tcp_socket_async_connect_block_t)block
391+
{
392+
[super asyncConnectToHost: host
393+
port: port
394+
runLoopMode: runLoopMode
395+
block: ^ (SSLSocket *sock, id exception) {
396+
if (exception == nil) {
397+
@try {
398+
[sock SSL_startTLSWithExpectedHost: host
399+
port: port];
400+
} @catch (id e) {
401+
block(sock, e);
402+
return;
403+
}
404+
}
405+
406+
block(sock, exception);
407+
}];
292408
}
409+
#endif
293410

294411
- (instancetype)accept
295412
{

0 commit comments

Comments
 (0)