bump websocket version
This commit is contained in:
parent
3e3ba60165
commit
8042053331
@ -95,7 +95,7 @@ Carthage
|
|||||||
-----------------
|
-----------------
|
||||||
Add this line to your `Cartfile`:
|
Add this line to your `Cartfile`:
|
||||||
```
|
```
|
||||||
github "socketio/socket.io-client-swift" ~> 8.0.2 # Or latest version
|
github "socketio/socket.io-client-swift" ~> 8.0.3 # Or latest version
|
||||||
```
|
```
|
||||||
|
|
||||||
Run `carthage update --platform ios,macosx`.
|
Run `carthage update --platform ios,macosx`.
|
||||||
@ -108,7 +108,7 @@ Create `Podfile` and add `pod 'Socket.IO-Client-Swift'`:
|
|||||||
use_frameworks!
|
use_frameworks!
|
||||||
|
|
||||||
target 'YourApp' do
|
target 'YourApp' do
|
||||||
pod 'Socket.IO-Client-Swift', '~> 8.0.2' # Or latest version
|
pod 'Socket.IO-Client-Swift', '~> 8.0.3' # Or latest version
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ CocoaSeeds
|
|||||||
Add this line to your `Seedfile`:
|
Add this line to your `Seedfile`:
|
||||||
|
|
||||||
```
|
```
|
||||||
github "socketio/socket.io-client-swift", "v8.0.2", :files => "Source/*.swift" # Or latest version
|
github "socketio/socket.io-client-swift", "v8.0.3", :files => "Source/*.swift" # Or latest version
|
||||||
```
|
```
|
||||||
|
|
||||||
Run `seed install`.
|
Run `seed install`.
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "Socket.IO-Client-Swift"
|
s.name = "Socket.IO-Client-Swift"
|
||||||
s.module_name = "SocketIO"
|
s.module_name = "SocketIO"
|
||||||
s.version = "8.0.2"
|
s.version = "8.0.3"
|
||||||
s.summary = "Socket.IO-client for iOS and OS X"
|
s.summary = "Socket.IO-client for iOS and OS X"
|
||||||
s.description = <<-DESC
|
s.description = <<-DESC
|
||||||
Socket.IO-client for iOS and OS X.
|
Socket.IO-client for iOS and OS X.
|
||||||
@ -14,7 +14,7 @@ Pod::Spec.new do |s|
|
|||||||
s.ios.deployment_target = '8.0'
|
s.ios.deployment_target = '8.0'
|
||||||
s.osx.deployment_target = '10.10'
|
s.osx.deployment_target = '10.10'
|
||||||
s.tvos.deployment_target = '9.0'
|
s.tvos.deployment_target = '9.0'
|
||||||
s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v8.0.2' }
|
s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v8.0.3' }
|
||||||
s.source_files = "Source/**/*.swift"
|
s.source_files = "Source/**/*.swift"
|
||||||
s.requires_arc = true
|
s.requires_arc = true
|
||||||
# s.dependency 'Starscream', '~> 0.9' # currently this repo includes Starscream swift files
|
# s.dependency 'Starscream', '~> 0.9' # currently this repo includes Starscream swift files
|
||||||
|
|||||||
@ -19,10 +19,13 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import Security
|
import Security
|
||||||
|
|
||||||
|
public protocol SSLTrustValidator {
|
||||||
|
func isValid(_ trust: SecTrust, domain: String?) -> Bool
|
||||||
|
}
|
||||||
|
|
||||||
open class SSLCert {
|
open class SSLCert {
|
||||||
var certData: Data?
|
var certData: Data?
|
||||||
var key: SecKey?
|
var key: SecKey?
|
||||||
@ -50,7 +53,7 @@ open class SSLCert {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class SSLSecurity {
|
open class SSLSecurity : SSLTrustValidator {
|
||||||
public var validatedDN = true //should the domain name be validated?
|
public var validatedDN = true //should the domain name be validated?
|
||||||
|
|
||||||
var isReady = false //is the key processing done?
|
var isReady = false //is the key processing done?
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import CoreFoundation
|
import CoreFoundation
|
||||||
import Security
|
import Security
|
||||||
@ -77,7 +76,6 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
var optionalProtocols: [String]?
|
var optionalProtocols: [String]?
|
||||||
|
|
||||||
// MARK: - Constants
|
// MARK: - Constants
|
||||||
|
|
||||||
let headerWSUpgradeName = "Upgrade"
|
let headerWSUpgradeName = "Upgrade"
|
||||||
let headerWSUpgradeValue = "websocket"
|
let headerWSUpgradeValue = "websocket"
|
||||||
let headerWSHostName = "Host"
|
let headerWSHostName = "Host"
|
||||||
@ -108,7 +106,6 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Delegates
|
// MARK: - Delegates
|
||||||
|
|
||||||
/// Responds to callback about new messages coming in over the WebSocket
|
/// Responds to callback about new messages coming in over the WebSocket
|
||||||
/// and also connection/disconnect messages.
|
/// and also connection/disconnect messages.
|
||||||
public weak var delegate: WebSocketDelegate?
|
public weak var delegate: WebSocketDelegate?
|
||||||
@ -118,7 +115,6 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
|
|
||||||
|
|
||||||
// MARK: - Block based API.
|
// MARK: - Block based API.
|
||||||
|
|
||||||
public var onConnect: ((Void) -> Void)?
|
public var onConnect: ((Void) -> Void)?
|
||||||
public var onDisconnect: ((NSError?) -> Void)?
|
public var onDisconnect: ((NSError?) -> Void)?
|
||||||
public var onText: ((String) -> Void)?
|
public var onText: ((String) -> Void)?
|
||||||
@ -128,7 +124,7 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
public var headers = [String: String]()
|
public var headers = [String: String]()
|
||||||
public var voipEnabled = false
|
public var voipEnabled = false
|
||||||
public var disableSSLCertValidation = false
|
public var disableSSLCertValidation = false
|
||||||
public var security: SSLSecurity?
|
public var security: SSLTrustValidator?
|
||||||
public var enabledSSLCipherSuites: [SSLCipherSuite]?
|
public var enabledSSLCipherSuites: [SSLCipherSuite]?
|
||||||
public var origin: String?
|
public var origin: String?
|
||||||
public var timeout = 5
|
public var timeout = 5
|
||||||
@ -139,7 +135,6 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
public var currentURL: URL { return url }
|
public var currentURL: URL { return url }
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private var url: URL
|
private var url: URL
|
||||||
private var inputStream: InputStream?
|
private var inputStream: InputStream?
|
||||||
private var outputStream: OutputStream?
|
private var outputStream: OutputStream?
|
||||||
@ -190,11 +185,8 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Disconnect from the server. I send a Close control frame to the server, then expect the server to respond with a Close control frame and close the socket from its end. I notify my delegate once the socket has been closed.
|
Disconnect from the server. I send a Close control frame to the server, then expect the server to respond with a Close control frame and close the socket from its end. I notify my delegate once the socket has been closed.
|
||||||
|
|
||||||
If you supply a non-nil `forceTimeout`, I wait at most that long (in seconds) for the server to close the socket. After the timeout expires, I close the socket and notify my delegate.
|
If you supply a non-nil `forceTimeout`, I wait at most that long (in seconds) for the server to close the socket. After the timeout expires, I close the socket and notify my delegate.
|
||||||
|
|
||||||
If you supply a zero (or negative) `forceTimeout`, I immediately close the socket (without sending a Close control frame) and notify my delegate.
|
If you supply a zero (or negative) `forceTimeout`, I immediately close the socket (without sending a Close control frame) and notify my delegate.
|
||||||
|
|
||||||
- Parameter forceTimeout: Maximum time to wait for the server to close the socket.
|
- Parameter forceTimeout: Maximum time to wait for the server to close the socket.
|
||||||
- Parameter closeCode: The code to send on disconnect. The default is the normal close code for cleanly disconnecting a webSocket.
|
- Parameter closeCode: The code to send on disconnect. The default is the normal close code for cleanly disconnecting a webSocket.
|
||||||
*/
|
*/
|
||||||
@ -216,9 +208,7 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Write a string to the websocket. This sends it as a text frame.
|
Write a string to the websocket. This sends it as a text frame.
|
||||||
|
|
||||||
If you supply a non-nil completion block, I will perform it when the write completes.
|
If you supply a non-nil completion block, I will perform it when the write completes.
|
||||||
|
|
||||||
- parameter string: The string to write.
|
- parameter string: The string to write.
|
||||||
- parameter completion: The (optional) completion handler.
|
- parameter completion: The (optional) completion handler.
|
||||||
*/
|
*/
|
||||||
@ -229,9 +219,7 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Write binary data to the websocket. This sends it as a binary frame.
|
Write binary data to the websocket. This sends it as a binary frame.
|
||||||
|
|
||||||
If you supply a non-nil completion block, I will perform it when the write completes.
|
If you supply a non-nil completion block, I will perform it when the write completes.
|
||||||
|
|
||||||
- parameter data: The data to write.
|
- parameter data: The data to write.
|
||||||
- parameter completion: The (optional) completion handler.
|
- parameter completion: The (optional) completion handler.
|
||||||
*/
|
*/
|
||||||
@ -313,7 +301,6 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
private func initStreamsWithData(_ data: Data, _ port: Int) {
|
private func initStreamsWithData(_ data: Data, _ port: Int) {
|
||||||
//higher level API we will cut over to at some point
|
//higher level API we will cut over to at some point
|
||||||
//NSStream.getStreamsToHostWithName(url.host, port: url.port.integerValue, inputStream: &inputStream, outputStream: &outputStream)
|
//NSStream.getStreamsToHostWithName(url.host, port: url.port.integerValue, inputStream: &inputStream, outputStream: &outputStream)
|
||||||
|
|
||||||
var readStream: Unmanaged<CFReadStream>?
|
var readStream: Unmanaged<CFReadStream>?
|
||||||
var writeStream: Unmanaged<CFWriteStream>?
|
var writeStream: Unmanaged<CFWriteStream>?
|
||||||
let h = url.host! as NSString
|
let h = url.host! as NSString
|
||||||
@ -326,6 +313,28 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
if supportedSSLSchemes.contains(url.scheme!) {
|
if supportedSSLSchemes.contains(url.scheme!) {
|
||||||
inStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
|
inStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
|
||||||
outStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
|
outStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
|
||||||
|
if disableSSLCertValidation {
|
||||||
|
let settings: [NSObject: NSObject] = [kCFStreamSSLValidatesCertificateChain: NSNumber(value: false), kCFStreamSSLPeerName: kCFNull]
|
||||||
|
inStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as Stream.PropertyKey)
|
||||||
|
outStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as Stream.PropertyKey)
|
||||||
|
}
|
||||||
|
if let cipherSuites = self.enabledSSLCipherSuites {
|
||||||
|
if let sslContextIn = CFReadStreamCopyProperty(inputStream, CFStreamPropertyKey(rawValue: kCFStreamPropertySSLContext)) as! SSLContext?,
|
||||||
|
let sslContextOut = CFWriteStreamCopyProperty(outputStream, CFStreamPropertyKey(rawValue: kCFStreamPropertySSLContext)) as! SSLContext? {
|
||||||
|
let resIn = SSLSetEnabledCiphers(sslContextIn, cipherSuites, cipherSuites.count)
|
||||||
|
let resOut = SSLSetEnabledCiphers(sslContextOut, cipherSuites, cipherSuites.count)
|
||||||
|
if resIn != errSecSuccess {
|
||||||
|
let error = self.errorWithDetail("Error setting ingoing cypher suites", code: UInt16(resIn))
|
||||||
|
disconnectStream(error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if resOut != errSecSuccess {
|
||||||
|
let error = self.errorWithDetail("Error setting outgoing cypher suites", code: UInt16(resOut))
|
||||||
|
disconnectStream(error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
certValidated = true //not a https session, so no need to check SSL pinning
|
certValidated = true //not a https session, so no need to check SSL pinning
|
||||||
}
|
}
|
||||||
@ -333,28 +342,6 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
inStream.setProperty(StreamNetworkServiceTypeValue.voIP as AnyObject, forKey: Stream.PropertyKey.networkServiceType)
|
inStream.setProperty(StreamNetworkServiceTypeValue.voIP as AnyObject, forKey: Stream.PropertyKey.networkServiceType)
|
||||||
outStream.setProperty(StreamNetworkServiceTypeValue.voIP as AnyObject, forKey: Stream.PropertyKey.networkServiceType)
|
outStream.setProperty(StreamNetworkServiceTypeValue.voIP as AnyObject, forKey: Stream.PropertyKey.networkServiceType)
|
||||||
}
|
}
|
||||||
if disableSSLCertValidation {
|
|
||||||
let settings: [NSObject: NSObject] = [kCFStreamSSLValidatesCertificateChain: NSNumber(value: false), kCFStreamSSLPeerName: kCFNull]
|
|
||||||
inStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as Stream.PropertyKey)
|
|
||||||
outStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as Stream.PropertyKey)
|
|
||||||
}
|
|
||||||
if let cipherSuites = self.enabledSSLCipherSuites {
|
|
||||||
if let sslContextIn = CFReadStreamCopyProperty(inputStream, CFStreamPropertyKey(rawValue: kCFStreamPropertySSLContext)) as! SSLContext?,
|
|
||||||
let sslContextOut = CFWriteStreamCopyProperty(outputStream, CFStreamPropertyKey(rawValue: kCFStreamPropertySSLContext)) as! SSLContext? {
|
|
||||||
let resIn = SSLSetEnabledCiphers(sslContextIn, cipherSuites, cipherSuites.count)
|
|
||||||
let resOut = SSLSetEnabledCiphers(sslContextOut, cipherSuites, cipherSuites.count)
|
|
||||||
if resIn != errSecSuccess {
|
|
||||||
let error = self.errorWithDetail("Error setting ingoing cypher suites", code: UInt16(resIn))
|
|
||||||
disconnectStream(error)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if resOut != errSecSuccess {
|
|
||||||
let error = self.errorWithDetail("Error setting outgoing cypher suites", code: UInt16(resOut))
|
|
||||||
disconnectStream(error)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CFReadStreamSetDispatchQueue(inStream, WebSocket.sharedWorkQueue)
|
CFReadStreamSetDispatchQueue(inStream, WebSocket.sharedWorkQueue)
|
||||||
CFWriteStreamSetDispatchQueue(outStream, WebSocket.sharedWorkQueue)
|
CFWriteStreamSetDispatchQueue(outStream, WebSocket.sharedWorkQueue)
|
||||||
@ -447,7 +434,6 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
let buf = NSMutableData(capacity: BUFFER_MAX)
|
let buf = NSMutableData(capacity: BUFFER_MAX)
|
||||||
let buffer = UnsafeMutableRawPointer(mutating: buf!.bytes).assumingMemoryBound(to: UInt8.self)
|
let buffer = UnsafeMutableRawPointer(mutating: buf!.bytes).assumingMemoryBound(to: UInt8.self)
|
||||||
let length = inputStream!.read(buffer, maxLength: BUFFER_MAX)
|
let length = inputStream!.read(buffer, maxLength: BUFFER_MAX)
|
||||||
|
|
||||||
guard length > 0 else { return }
|
guard length > 0 else { return }
|
||||||
var process = false
|
var process = false
|
||||||
if inputQueue.count == 0 {
|
if inputQueue.count == 0 {
|
||||||
@ -643,34 +629,22 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
writeError(errCode)
|
writeError(errCode)
|
||||||
return emptyBuffer
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
|
var closeCode = CloseCode.normal.rawValue
|
||||||
if receivedOpcode == .connectionClose {
|
if receivedOpcode == .connectionClose {
|
||||||
var code = CloseCode.normal.rawValue
|
|
||||||
if payloadLen == 1 {
|
if payloadLen == 1 {
|
||||||
code = CloseCode.protocolError.rawValue
|
closeCode = CloseCode.protocolError.rawValue
|
||||||
} else if payloadLen > 1 {
|
} else if payloadLen > 1 {
|
||||||
code = WebSocket.readUint16(baseAddress, offset: offset)
|
closeCode = WebSocket.readUint16(baseAddress, offset: offset)
|
||||||
if code < 1000 || (code > 1003 && code < 1007) || (code > 1011 && code < 3000) {
|
if closeCode < 1000 || (closeCode > 1003 && closeCode < 1007) || (closeCode > 1011 && closeCode < 3000) {
|
||||||
code = CloseCode.protocolError.rawValue
|
closeCode = CloseCode.protocolError.rawValue
|
||||||
}
|
|
||||||
offset += 2
|
|
||||||
}
|
|
||||||
var closeReason = "connection closed by server"
|
|
||||||
if payloadLen > 2 {
|
|
||||||
let len = Int(payloadLen - 2)
|
|
||||||
if len > 0 {
|
|
||||||
let bytes = baseAddress + offset
|
|
||||||
if let customCloseReason = String(data: Data(bytes: bytes, count: len), encoding: .utf8) {
|
|
||||||
closeReason = customCloseReason
|
|
||||||
} else {
|
|
||||||
code = CloseCode.protocolError.rawValue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
doDisconnect(errorWithDetail(closeReason, code: code))
|
if payloadLen < 2 {
|
||||||
writeError(code)
|
doDisconnect(errorWithDetail("connection closed by server", code: closeCode))
|
||||||
return emptyBuffer
|
writeError(closeCode)
|
||||||
}
|
return emptyBuffer
|
||||||
if isControlFrame && payloadLen > 125 {
|
}
|
||||||
|
} else if isControlFrame && payloadLen > 125 {
|
||||||
writeError(CloseCode.protocolError.rawValue)
|
writeError(CloseCode.protocolError.rawValue)
|
||||||
return emptyBuffer
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
@ -695,8 +669,24 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
len = 0
|
len = 0
|
||||||
data = Data()
|
data = Data()
|
||||||
} else {
|
} else {
|
||||||
|
if receivedOpcode == .connectionClose && len > 0 {
|
||||||
|
let size = MemoryLayout<UInt16>.size
|
||||||
|
offset += size
|
||||||
|
len -= UInt64(size)
|
||||||
|
}
|
||||||
data = Data(bytes: baseAddress+offset, count: Int(len))
|
data = Data(bytes: baseAddress+offset, count: Int(len))
|
||||||
}
|
}
|
||||||
|
if receivedOpcode == .connectionClose {
|
||||||
|
var closeReason = "connection closed by server"
|
||||||
|
if let customCloseReason = String(data: data, encoding: .utf8) {
|
||||||
|
closeReason = customCloseReason
|
||||||
|
} else {
|
||||||
|
closeCode = CloseCode.protocolError.rawValue
|
||||||
|
}
|
||||||
|
doDisconnect(errorWithDetail(closeReason, code: closeCode))
|
||||||
|
writeError(closeCode)
|
||||||
|
return emptyBuffer
|
||||||
|
}
|
||||||
if receivedOpcode == .pong {
|
if receivedOpcode == .pong {
|
||||||
if canDispatch {
|
if canDispatch {
|
||||||
callbackQueue.async { [weak self] in
|
callbackQueue.async { [weak self] in
|
||||||
@ -910,7 +900,6 @@ open class WebSocket : NSObject, StreamDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Deinit
|
// MARK: - Deinit
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
mutex.lock()
|
mutex.lock()
|
||||||
readyToWrite = false
|
readyToWrite = false
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user