1
+ // The content below is the concatenation of the files in Starscream (https://github.com/daltoniam/Starscream)
2
+ // with trivial warnings fixed, trailing spaces removed, and some access levels changed.
1
3
//
2
- // Starscream.swift
3
- // PusherSwift
4
- //
5
- // Created by Hamilton Chapman on 06/04/2016.
6
- //
7
- // The content below is the concatenation of these files
8
- // - https://raw.githubusercontent.com/daltoniam/Starscream/swift-23/Source/SSLSecurity.swift
9
- // - https://raw.githubusercontent.com/daltoniam/Starscream/swift-23/Source/WebSocket.swift
10
- // (with trivial warnings fixed, trailing spaces removed, and some access levels changed)
11
- //
12
- // commit SHA ee993322c
4
+ // Based on commit SHA 789264eeff101e, but without some docs fixes from ee993322c
5
+ // onwards, and without the compression support.
13
6
14
7
//////////////////////////////////////////////////////////////////////////////////////////////////
15
8
//
@@ -394,7 +387,7 @@ open class WebSocket : NSObject, StreamDelegate {
394
387
395
388
// MARK: - Block based API.
396
389
397
- public var onConnect : ( ( Void ) -> Void ) ?
390
+ public var onConnect : ( ( ) -> Void ) ?
398
391
public var onDisconnect : ( ( NSError ? ) -> Void ) ?
399
392
public var onText : ( ( String ) -> Void ) ?
400
393
public var onData : ( ( Data ) -> Void ) ?
@@ -408,7 +401,10 @@ open class WebSocket : NSObject, StreamDelegate {
408
401
public var origin : String ?
409
402
public var timeout = 5
410
403
public var isConnected : Bool {
411
- return connected
404
+ connectedMutex. lock ( )
405
+ let isConnected = connected
406
+ connectedMutex. unlock ( )
407
+ return isConnected
412
408
}
413
409
414
410
public var currentURL : URL { return url }
@@ -420,19 +416,20 @@ open class WebSocket : NSObject, StreamDelegate {
420
416
private var outputStream : OutputStream ?
421
417
private var connected = false
422
418
private var isConnecting = false
419
+ private let connectedMutex = NSLock ( )
423
420
private var writeQueue = OperationQueue ( )
424
421
private var readStack = [ WSResponse] ( )
425
422
private var inputQueue = [ Data] ( )
426
423
private var fragBuffer : Data ?
427
424
private var certValidated = false
428
425
private var didDisconnect = false
429
426
private var readyToWrite = false
430
- private let mutex = NSLock ( )
427
+ private let readyToWriteMutex = NSLock ( )
431
428
private let notificationCenter = NotificationCenter . default
432
429
private var canDispatch : Bool {
433
- mutex . lock ( )
430
+ readyToWriteMutex . lock ( )
434
431
let canWork = readyToWrite
435
- mutex . unlock ( )
432
+ readyToWriteMutex . unlock ( )
436
433
return canWork
437
434
}
438
435
/// The shared processing queue used for all WebSocket.
@@ -484,12 +481,17 @@ open class WebSocket : NSObject, StreamDelegate {
484
481
let milliseconds = Int ( seconds * 1_000 )
485
482
callbackQueue. asyncAfter ( deadline: . now( ) + . milliseconds( milliseconds) ) { [ weak self] in
486
483
self ? . disconnectStream ( nil )
484
+ WebSocket . sharedWorkQueue. async {
485
+ self ? . disconnectStream ( nil )
486
+ }
487
487
}
488
488
fallthrough
489
489
case . none:
490
490
writeError ( closeCode)
491
491
default :
492
- disconnectStream ( nil )
492
+ WebSocket . sharedWorkQueue. async { [ weak self] in
493
+ self ? . disconnectStream ( nil )
494
+ }
493
495
break
494
496
}
495
497
}
@@ -620,13 +622,17 @@ open class WebSocket : NSObject, StreamDelegate {
620
622
let resIn = SSLSetEnabledCiphers ( sslContextIn, cipherSuites, cipherSuites. count)
621
623
let resOut = SSLSetEnabledCiphers ( sslContextOut, cipherSuites, cipherSuites. count)
622
624
if resIn != errSecSuccess {
623
- let error = self . errorWithDetail ( " Error setting ingoing cypher suites " , code: UInt16 ( resIn) )
624
- disconnectStream ( error)
625
+ WebSocket . sharedWorkQueue. async { [ weak self] in
626
+ let error = self ? . errorWithDetail ( " Error setting ingoing cypher suites " , code: UInt16 ( resIn) )
627
+ self ? . disconnectStream ( error)
628
+ }
625
629
return
626
630
}
627
631
if resOut != errSecSuccess {
628
- let error = self . errorWithDetail ( " Error setting outgoing cypher suites " , code: UInt16 ( resOut) )
629
- disconnectStream ( error)
632
+ WebSocket . sharedWorkQueue. async { [ weak self] in
633
+ let error = self ? . errorWithDetail ( " Error setting outgoing cypher suites " , code: UInt16 ( resOut) )
634
+ self ? . disconnectStream ( error)
635
+ }
630
636
return
631
637
}
632
638
}
@@ -644,9 +650,9 @@ open class WebSocket : NSObject, StreamDelegate {
644
650
inStream. open ( )
645
651
outStream. open ( )
646
652
647
- self . mutex . lock ( )
653
+ self . readyToWriteMutex . lock ( )
648
654
self . readyToWrite = true
649
- self . mutex . unlock ( )
655
+ self . readyToWriteMutex . unlock ( )
650
656
651
657
let bytes = UnsafeRawPointer ( ( data as NSData ) . bytes) . assumingMemoryBound ( to: UInt8 . self)
652
658
var out = timeout * 1_000_000 // wait 5 seconds before giving up
@@ -670,9 +676,12 @@ open class WebSocket : NSObject, StreamDelegate {
670
676
guard !sOperation. isCancelled, let s = self else { return }
671
677
// Do the pinning now if needed
672
678
if let sec = s. security, !s. certValidated {
673
- let trust = outStream. property ( forKey: kCFStreamPropertySSLPeerTrust as Stream . PropertyKey ) as! SecTrust
674
- let domain = outStream. property ( forKey: kCFStreamSSLPeerName as Stream . PropertyKey ) as? String
675
- s. certValidated = sec. isValid ( trust, domain: domain)
679
+ if let possibleTrust = outStream. property ( forKey: kCFStreamPropertySSLPeerTrust as Stream . PropertyKey ) {
680
+ let domain = outStream. property ( forKey: kCFStreamSSLPeerName as Stream . PropertyKey ) as? String
681
+ s. certValidated = sec. isValid ( possibleTrust as! SecTrust , domain: domain)
682
+ } else {
683
+ s. certValidated = false
684
+ }
676
685
if !s. certValidated {
677
686
WebSocket . sharedWorkQueue. async {
678
687
let error = s. errorWithDetail ( " Invalid SSL certificate " , code: 1 )
@@ -711,7 +720,9 @@ open class WebSocket : NSObject, StreamDelegate {
711
720
writeQueue. cancelAllOperations ( )
712
721
}
713
722
cleanupStream ( )
723
+ connectedMutex. lock ( )
714
724
connected = false
725
+ connectedMutex. unlock ( )
715
726
if runDelegate {
716
727
doDisconnect ( error)
717
728
}
@@ -820,7 +831,9 @@ open class WebSocket : NSObject, StreamDelegate {
820
831
return code
821
832
}
822
833
isConnecting = false
834
+ connectedMutex. lock ( )
823
835
connected = true
836
+ connectedMutex. unlock ( )
824
837
didDisconnect = false
825
838
if canDispatch {
826
839
callbackQueue. async { [ weak self] in
@@ -1202,7 +1215,9 @@ open class WebSocket : NSObject, StreamDelegate {
1202
1215
guard !didDisconnect else { return }
1203
1216
didDisconnect = true
1204
1217
isConnecting = false
1218
+ connectedMutex. lock ( )
1205
1219
connected = false
1220
+ connectedMutex. unlock ( )
1206
1221
guard canDispatch else { return }
1207
1222
callbackQueue. async { [ weak self] in
1208
1223
guard let s = self else { return }
@@ -1216,9 +1231,9 @@ open class WebSocket : NSObject, StreamDelegate {
1216
1231
// MARK: - Deinit
1217
1232
1218
1233
deinit {
1219
- mutex . lock ( )
1234
+ readyToWriteMutex . lock ( )
1220
1235
readyToWrite = false
1221
- mutex . unlock ( )
1236
+ readyToWriteMutex . unlock ( )
1222
1237
cleanupStream ( )
1223
1238
writeQueue. cancelAllOperations ( )
1224
1239
}
0 commit comments