Skip to content

Commit 2f943a9

Browse files
committed
Added SSL support on IOS. Changed Socket.read() on IOS to block indefinitely (no timeout) to match behaviour of other platforms. Fixed available() method to not block on iOS.
1 parent c3c8a8a commit 2f943a9

File tree

2 files changed

+156
-114
lines changed

2 files changed

+156
-114
lines changed

dist/CN1Sockets.cn1lib

582 Bytes
Binary file not shown.

native/ios/ca_weblite_codename1_net_impl_NativeSocketImpl.m

+156-114
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,14 @@ -(int)read{
4141
}
4242
errorMessage = NULL;
4343
uint8_t buf[1];
44-
_yield();
44+
_yield(); // Tell the GC that it is OK to collect on us while we're blocked
45+
while ([self available] <= 0) {
46+
// Since iOS doesn't block infinitely, we need to wait until there is
47+
// data to read.
48+
usleep(100000);
49+
}
4550
int bytesRead = [inputStream read:buf maxLength:1];
46-
_resume();
51+
_resume(); // tell the GC that we're back
4752
if ( bytesRead == -1 ){
4853
errorMessage = [[inputStream streamError] localizedDescription];
4954
return -2;
@@ -68,9 +73,14 @@ -(long long)skip:(long long)param{
6873
} else {
6974
bytesToRead = bufSize;
7075
}
71-
_yield();
76+
_yield(); // Tell GC that it is ok to collect our garbage while we're blocked
77+
while ([self available] <= 0) {
78+
// Since iOS doesn't block infinitely, we need to wait until there is
79+
// data to read.
80+
usleep(100000);
81+
}
7282
bytesRead = [inputStream read:buf maxLength:bytesToRead];
73-
_resume();
83+
_resume(); // Tell the GC that we're back
7484
if ( bytesRead == -1 ){
7585
errorMessage = [[inputStream streamError] localizedDescription];
7686
return -2;
@@ -85,10 +95,11 @@ -(long long)skip:(long long)param{
8595

8696
-(int)available{
8797
errorMessage = NULL;
88-
uint8_t* buf;
89-
NSUInteger len;
90-
BOOL available = [inputStream getBuffer:&buf length:&len];
91-
return (int)len;
98+
BOOL available = [inputStream hasBytesAvailable];
99+
if (available)
100+
return 1;
101+
else
102+
return 0;
92103
}
93104

94105
-(BOOL)markSupported{
@@ -164,119 +175,150 @@ -(int)readBuf:(int)len{
164175
JAVA_ARRAY_BYTE* buffer = (JAVA_ARRAY_BYTE*)byteArray->fields.org_xmlvm_runtime_XMLVMArray.array_;
165176
if ( len > byteArray->fields.org_xmlvm_runtime_XMLVMArray.length_){
166177
#else
167-
JAVA_ARRAY byteArray = (JAVA_ARRAY)ca_weblite_codename1_net_Socket_getBuffer___int_R_byte_1ARRAY(CN1_THREAD_GET_STATE_PASS_ARG bufferId);
168-
JAVA_ARRAY_BYTE* buffer = (JAVA_ARRAY_BYTE*)byteArray->data;
169-
if ( len > byteArray->length){
178+
JAVA_ARRAY byteArray = (JAVA_ARRAY)ca_weblite_codename1_net_Socket_getBuffer___int_R_byte_1ARRAY(CN1_THREAD_GET_STATE_PASS_ARG bufferId);
179+
JAVA_ARRAY_BYTE* buffer = (JAVA_ARRAY_BYTE*)byteArray->data;
180+
if ( len > byteArray->length){
170181
#endif
171-
errorMessage = @"Attempt to read byte array longer than the buffer.";
172-
return -2;
182+
errorMessage = @"Attempt to read byte array longer than the buffer.";
183+
return -2;
184+
}
185+
186+
187+
_yield(); // tell the GC that it is OK to do GC while this thread is blocked
188+
while ([self available] <= 0) {
189+
// Since iOS doesn't block infinitely, we need to wait until there is
190+
// data to read.
191+
usleep(100000);
192+
}
193+
int bytesRead = [inputStream read:buffer maxLength:len];
194+
_resume(); // Tell the GC that we're back
195+
if ( bytesRead == -1 ){
196+
errorMessage = [[inputStream streamError] localizedDescription];
197+
return -2;
198+
} else if ( bytesRead == 0 ){
199+
return -1;
200+
} else {
201+
if ( bytesRead < len ){
202+
isFinished = YES;
203+
}
204+
return bytesRead;
205+
}
173206
}
174-
_yield();
175-
int bytesRead = [inputStream read:buffer maxLength:len];
176-
_resume();
177-
if ( bytesRead == -1 ){
178-
errorMessage = [[inputStream streamError] localizedDescription];
179-
return -2;
180-
} else if ( bytesRead == 0 ){
181-
return -1;
182-
} else {
183-
if ( bytesRead < len ){
184-
isFinished = YES;
207+
208+
-(BOOL)closeInputStream{
209+
errorMessage = NULL;
210+
[inputStream close];
211+
return YES;
212+
}
213+
214+
-(int)getErrorCode{
215+
if ( errorMessage == NULL ){
216+
return 0;
217+
} else {
218+
return 500;
185219
}
186-
return bytesRead;
187220
}
188-
}
189-
190-
-(BOOL)closeInputStream{
191-
errorMessage = NULL;
192-
[inputStream close];
193-
return YES;
194-
}
195-
196-
-(int)getErrorCode{
197-
if ( errorMessage == NULL ){
198-
return 0;
199-
} else {
200-
return 500;
221+
222+
-(BOOL)createSocket:(NSString*)host param1:(int)port{
223+
isFinished = NO;
224+
CFReadStreamRef readStream;
225+
CFWriteStreamRef writeStream;
226+
227+
BOOL isSSL = NO;
228+
if ([host hasPrefix:@"SSL@"]) {
229+
isSSL = YES;
230+
host = [host stringByReplacingOccurrencesOfString:@"SSL@" withString:@""];
231+
NSLog(@"Connecting to SSL socket %@:%d", host, port);
232+
}
233+
else {
234+
NSLog(@"Connecting to plain socket %@:%d", host, port);
235+
}
236+
237+
_yield();
238+
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
239+
_resume();
240+
241+
inputStream = (__bridge NSInputStream *)readStream;
242+
outputStream = (__bridge NSOutputStream *)writeStream;
243+
244+
[inputStream retain];
245+
[outputStream retain];
246+
247+
if (isSSL) {
248+
NSDictionary *settings = [ [NSDictionary alloc ]
249+
initWithObjectsAndKeys:
250+
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
251+
[NSNull null], kCFStreamSSLPeerName,
252+
kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamSSLLevel,
253+
nil ];
254+
CFReadStreamSetProperty((CFReadStreamRef)inputStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
255+
CFWriteStreamSetProperty((CFWriteStreamRef)outputStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
256+
}
257+
258+
return YES;
201259
}
202-
}
203-
204-
-(BOOL)createSocket:(NSString*)host param1:(int)port{
205-
isFinished = NO;
206-
CFReadStreamRef readStream;
207-
CFWriteStreamRef writeStream;
208-
_yield();
209-
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)host, port, &readStream, &writeStream);
210-
_resume();
211-
inputStream = (NSInputStream *)readStream;
212-
outputStream = (NSOutputStream *)writeStream;
213260

214-
[inputStream retain];
215-
[outputStream retain];
216-
return YES;
217-
}
218-
219-
-(BOOL)closeSocket{
220-
errorMessage = NULL;
221-
[inputStream close];
222-
[outputStream close];
223-
return YES;
224-
}
225-
226-
-(BOOL)writeBuf:(NSData*)buffer{
227-
isFinished = NO;
228-
errorMessage = NULL;
229-
_yield();
230-
int bytesWritten = [outputStream write:(const uint8_t*)[buffer bytes] maxLength:[buffer length]];
231-
_resume();
232-
if ( bytesWritten == -1 ){
233-
errorMessage = [[outputStream streamError] localizedDescription];
261+
-(BOOL)closeSocket{
262+
errorMessage = NULL;
263+
[inputStream close];
264+
[outputStream close];
265+
return YES;
266+
}
267+
268+
-(BOOL)writeBuf:(NSData*)buffer{
269+
isFinished = NO;
270+
errorMessage = NULL;
271+
_yield();
272+
int bytesWritten = [outputStream write:(const uint8_t*)[buffer bytes] maxLength:[buffer length]];
273+
_resume();
274+
if ( bytesWritten == -1 ){
275+
errorMessage = [[outputStream streamError] localizedDescription];
276+
return NO;
277+
} else if ( bytesWritten != [buffer length]){
278+
errorMessage = [NSString stringWithFormat:@"Not all bytes in buffer were written. Buffer length was %d but only wrote %d bytes.", [buffer length], bytesWritten];
279+
return NO;
280+
}
281+
return YES;
282+
}
283+
284+
-(BOOL)flushOutputStream{
285+
286+
return YES;
287+
}
288+
289+
-(BOOL)markInputStream:(int)param{
290+
errorMessage = @"Mark not supported";
234291
return NO;
235-
} else if ( bytesWritten != [buffer length]){
236-
errorMessage = [NSString stringWithFormat:@"Not all bytes in buffer were written. Buffer length was %d but only wrote %d bytes.", [buffer length], bytesWritten];
292+
}
293+
294+
-(BOOL)connectSocket:(int)timeout{
295+
isFinished = NO;
296+
errorMessage = NULL;
297+
[inputStream open];
298+
[outputStream open];
299+
return YES;
300+
}
301+
302+
303+
-(BOOL)isSocketConnected{
304+
return ![self isInputShutdown] && ![self isOutputShutdown];
305+
}
306+
307+
-(BOOL)isSocketClosed{
308+
return ![self isSocketConnected];
309+
}
310+
311+
-(BOOL)writeBuffOffsetLength:(NSData*)param param1:(int)param1 param2:(int)param2{
237312
return NO;
238313
}
239-
return YES;
240-
}
241-
242-
-(BOOL)flushOutputStream{
243314

244-
return YES;
245-
}
246-
247-
-(BOOL)markInputStream:(int)param{
248-
errorMessage = @"Mark not supported";
249-
return NO;
250-
}
251-
252-
-(BOOL)connectSocket:(int)timeout{
253-
isFinished = NO;
254-
errorMessage = NULL;
255-
[inputStream open];
256-
[outputStream open];
257-
return YES;
258-
}
259-
260-
261-
-(BOOL)isSocketConnected{
262-
return ![self isInputShutdown] && ![self isOutputShutdown];
263-
}
264-
265-
-(BOOL)isSocketClosed{
266-
return ![self isSocketConnected];
267-
}
268-
269-
-(BOOL)writeBuffOffsetLength:(NSData*)param param1:(int)param1 param2:(int)param2{
270-
return NO;
271-
}
272-
273-
-(BOOL)resetInputStream{
274-
isFinished = NO;
275-
return NO;
276-
}
277-
278-
-(BOOL)isSupported{
279-
return YES;
280-
}
281-
282-
@end
315+
-(BOOL)resetInputStream{
316+
isFinished = NO;
317+
return NO;
318+
}
319+
320+
-(BOOL)isSupported{
321+
return YES;
322+
}
323+
324+
@end

0 commit comments

Comments
 (0)