bump websocket
This commit is contained in:
parent
50216647ca
commit
3401414430
@ -385,7 +385,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
|
|||||||
doPoll()
|
doPoll()
|
||||||
}
|
}
|
||||||
|
|
||||||
client?.engineDidOpen?("Connect")
|
client?.engineDidOpen("Connect")
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
didError("Error parsing open packet")
|
didError("Error parsing open packet")
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import Foundation
|
|||||||
@objc public protocol SocketEngineClient {
|
@objc public protocol SocketEngineClient {
|
||||||
func engineDidError(reason: String)
|
func engineDidError(reason: String)
|
||||||
func engineDidClose(reason: String)
|
func engineDidClose(reason: String)
|
||||||
optional func engineDidOpen(reason: String)
|
func engineDidOpen(reason: String)
|
||||||
func parseEngineMessage(msg: String)
|
func parseEngineMessage(msg: String)
|
||||||
func parseEngineBinaryData(data: NSData)
|
func parseEngineBinaryData(data: NSData)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -284,6 +284,10 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
|
|||||||
|
|
||||||
handleEvent("error", data: [reason], isInternalMessage: true)
|
handleEvent("error", data: [reason], isInternalMessage: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func engineDidOpen(reason: String) {
|
||||||
|
DefaultSocketLogger.Logger.log(reason, type: "SocketEngineClient")
|
||||||
|
}
|
||||||
|
|
||||||
// Called when the socket gets an ack for something it sent
|
// Called when the socket gets an ack for something it sent
|
||||||
func handleAck(ack: Int, data: [AnyObject]) {
|
func handleAck(ack: Int, data: [AnyObject]) {
|
||||||
@ -296,9 +300,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
|
|||||||
|
|
||||||
/// Causes an event to be handled. Only use if you know what you're doing.
|
/// Causes an event to be handled. Only use if you know what you're doing.
|
||||||
public func handleEvent(event: String, data: [AnyObject], isInternalMessage: Bool, withAck ack: Int = -1) {
|
public func handleEvent(event: String, data: [AnyObject], isInternalMessage: Bool, withAck ack: Int = -1) {
|
||||||
guard status == .Connected || isInternalMessage else {
|
guard status == .Connected || isInternalMessage else { return }
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
DefaultSocketLogger.Logger.log("Handling event: %@ with data: %@", type: logType, args: event, data ?? "")
|
DefaultSocketLogger.Logger.log("Handling event: %@ with data: %@", type: logType, args: event, data ?? "")
|
||||||
|
|
||||||
@ -333,14 +335,14 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable
|
|||||||
public func off(event: String) {
|
public func off(event: String) {
|
||||||
DefaultSocketLogger.Logger.log("Removing handler for event: %@", type: logType, args: event)
|
DefaultSocketLogger.Logger.log("Removing handler for event: %@", type: logType, args: event)
|
||||||
|
|
||||||
handlers = handlers.filter { $0.event != event }
|
handlers = handlers.filter({ $0.event != event })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a handler with the specified UUID gotten from an `on` or `once`
|
/// Removes a handler with the specified UUID gotten from an `on` or `once`
|
||||||
public func off(id id: NSUUID) {
|
public func off(id id: NSUUID) {
|
||||||
DefaultSocketLogger.Logger.log("Removing handler with id: %@", type: logType, args: id)
|
DefaultSocketLogger.Logger.log("Removing handler with id: %@", type: logType, args: id)
|
||||||
|
|
||||||
handlers = handlers.filter { $0.id != id }
|
handlers = handlers.filter({ $0.id != id })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a handler for an event.
|
/// Adds a handler for an event.
|
||||||
|
|||||||
@ -112,6 +112,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
public var security: SSLSecurity?
|
public var security: SSLSecurity?
|
||||||
public var enabledSSLCipherSuites: [SSLCipherSuite]?
|
public var enabledSSLCipherSuites: [SSLCipherSuite]?
|
||||||
public var origin: String?
|
public var origin: String?
|
||||||
|
public var timeout = 5
|
||||||
public var isConnected :Bool {
|
public var isConnected :Bool {
|
||||||
return connected
|
return connected
|
||||||
}
|
}
|
||||||
@ -319,12 +320,12 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
self.mutex.unlock()
|
self.mutex.unlock()
|
||||||
|
|
||||||
let bytes = UnsafePointer<UInt8>(data.bytes)
|
let bytes = UnsafePointer<UInt8>(data.bytes)
|
||||||
var timeout = 5000000 //wait 5 seconds before giving up
|
var out = timeout * 1000000 //wait 5 seconds before giving up
|
||||||
writeQueue.addOperationWithBlock { [weak self] in
|
writeQueue.addOperationWithBlock { [weak self] in
|
||||||
while !outStream.hasSpaceAvailable {
|
while !outStream.hasSpaceAvailable {
|
||||||
usleep(100) //wait until the socket is ready
|
usleep(100) //wait until the socket is ready
|
||||||
timeout -= 100
|
out -= 100
|
||||||
if timeout < 0 {
|
if out < 0 {
|
||||||
self?.cleanupStream()
|
self?.cleanupStream()
|
||||||
self?.doDisconnect(self?.errorWithDetail("write wait timed out", code: 2))
|
self?.doDisconnect(self?.errorWithDetail("write wait timed out", code: 2))
|
||||||
return
|
return
|
||||||
@ -405,25 +406,24 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
}
|
}
|
||||||
///dequeue the incoming input so it is processed in order
|
///dequeue the incoming input so it is processed in order
|
||||||
private func dequeueInput() {
|
private func dequeueInput() {
|
||||||
guard !inputQueue.isEmpty else { return }
|
while !inputQueue.isEmpty {
|
||||||
|
let data = inputQueue[0]
|
||||||
let data = inputQueue[0]
|
var work = data
|
||||||
var work = data
|
if let fragBuffer = fragBuffer {
|
||||||
if let fragBuffer = fragBuffer {
|
let combine = NSMutableData(data: fragBuffer)
|
||||||
let combine = NSMutableData(data: fragBuffer)
|
combine.appendData(data)
|
||||||
combine.appendData(data)
|
work = combine
|
||||||
work = combine
|
self.fragBuffer = nil
|
||||||
self.fragBuffer = nil
|
}
|
||||||
|
let buffer = UnsafePointer<UInt8>(work.bytes)
|
||||||
|
let length = work.length
|
||||||
|
if !connected {
|
||||||
|
processTCPHandshake(buffer, bufferLen: length)
|
||||||
|
} else {
|
||||||
|
processRawMessagesInBuffer(buffer, bufferLen: length)
|
||||||
|
}
|
||||||
|
inputQueue = inputQueue.filter{$0 != data}
|
||||||
}
|
}
|
||||||
let buffer = UnsafePointer<UInt8>(work.bytes)
|
|
||||||
let length = work.length
|
|
||||||
if !connected {
|
|
||||||
processTCPHandshake(buffer, bufferLen: length)
|
|
||||||
} else {
|
|
||||||
processRawMessage(buffer, bufferLen: length)
|
|
||||||
}
|
|
||||||
inputQueue = inputQueue.filter{$0 != data}
|
|
||||||
dequeueInput()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//handle checking the inital connection status
|
//handle checking the inital connection status
|
||||||
@ -469,7 +469,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
totalSize += 1 //skip the last \n
|
totalSize += 1 //skip the last \n
|
||||||
let restSize = bufferLen - totalSize
|
let restSize = bufferLen - totalSize
|
||||||
if restSize > 0 {
|
if restSize > 0 {
|
||||||
processRawMessage((buffer+totalSize),bufferLen: restSize)
|
processRawMessagesInBuffer(buffer + totalSize, bufferLen: restSize)
|
||||||
}
|
}
|
||||||
return 0 //success
|
return 0 //success
|
||||||
}
|
}
|
||||||
@ -522,12 +522,15 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///process the websocket data
|
/// Process one message at the start of `buffer`. Return another buffer (sharing storage) that contains the leftover contents of `buffer` that I didn't process.
|
||||||
private func processRawMessage(buffer: UnsafePointer<UInt8>, bufferLen: Int) {
|
@warn_unused_result
|
||||||
|
private func processOneRawMessage(inBuffer buffer: UnsafeBufferPointer<UInt8>) -> UnsafeBufferPointer<UInt8> {
|
||||||
let response = readStack.last
|
let response = readStack.last
|
||||||
|
let baseAddress = buffer.baseAddress
|
||||||
|
let bufferLen = buffer.count
|
||||||
if response != nil && bufferLen < 2 {
|
if response != nil && bufferLen < 2 {
|
||||||
fragBuffer = NSData(bytes: buffer, length: bufferLen)
|
fragBuffer = NSData(buffer: buffer)
|
||||||
return
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
if let response = response where response.bytesLeft > 0 {
|
if let response = response where response.bytesLeft > 0 {
|
||||||
var len = response.bytesLeft
|
var len = response.bytesLeft
|
||||||
@ -537,24 +540,20 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
extra = 0
|
extra = 0
|
||||||
}
|
}
|
||||||
response.bytesLeft -= len
|
response.bytesLeft -= len
|
||||||
response.buffer?.appendData(NSData(bytes: buffer, length: len))
|
response.buffer?.appendData(NSData(bytes: baseAddress, length: len))
|
||||||
processResponse(response)
|
processResponse(response)
|
||||||
let offset = bufferLen - extra
|
return buffer.fromOffset(bufferLen - extra)
|
||||||
if extra > 0 {
|
|
||||||
processExtra((buffer+offset), bufferLen: extra)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
} else {
|
} else {
|
||||||
let isFin = (FinMask & buffer[0])
|
let isFin = (FinMask & baseAddress[0])
|
||||||
let receivedOpcode = OpCode(rawValue: (OpCodeMask & buffer[0]))
|
let receivedOpcode = OpCode(rawValue: (OpCodeMask & baseAddress[0]))
|
||||||
let isMasked = (MaskMask & buffer[1])
|
let isMasked = (MaskMask & baseAddress[1])
|
||||||
let payloadLen = (PayloadLenMask & buffer[1])
|
let payloadLen = (PayloadLenMask & baseAddress[1])
|
||||||
var offset = 2
|
var offset = 2
|
||||||
if (isMasked > 0 || (RSVMask & buffer[0]) > 0) && receivedOpcode != .Pong {
|
if (isMasked > 0 || (RSVMask & baseAddress[0]) > 0) && receivedOpcode != .Pong {
|
||||||
let errCode = CloseCode.ProtocolError.rawValue
|
let errCode = CloseCode.ProtocolError.rawValue
|
||||||
doDisconnect(errorWithDetail("masked and rsv data is not currently supported", code: errCode))
|
doDisconnect(errorWithDetail("masked and rsv data is not currently supported", code: errCode))
|
||||||
writeError(errCode)
|
writeError(errCode)
|
||||||
return
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
let isControlFrame = (receivedOpcode == .ConnectionClose || receivedOpcode == .Ping)
|
let isControlFrame = (receivedOpcode == .ConnectionClose || receivedOpcode == .Ping)
|
||||||
if !isControlFrame && (receivedOpcode != .BinaryFrame && receivedOpcode != .ContinueFrame &&
|
if !isControlFrame && (receivedOpcode != .BinaryFrame && receivedOpcode != .ContinueFrame &&
|
||||||
@ -562,20 +561,20 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
let errCode = CloseCode.ProtocolError.rawValue
|
let errCode = CloseCode.ProtocolError.rawValue
|
||||||
doDisconnect(errorWithDetail("unknown opcode: \(receivedOpcode)", code: errCode))
|
doDisconnect(errorWithDetail("unknown opcode: \(receivedOpcode)", code: errCode))
|
||||||
writeError(errCode)
|
writeError(errCode)
|
||||||
return
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
if isControlFrame && isFin == 0 {
|
if isControlFrame && isFin == 0 {
|
||||||
let errCode = CloseCode.ProtocolError.rawValue
|
let errCode = CloseCode.ProtocolError.rawValue
|
||||||
doDisconnect(errorWithDetail("control frames can't be fragmented", code: errCode))
|
doDisconnect(errorWithDetail("control frames can't be fragmented", code: errCode))
|
||||||
writeError(errCode)
|
writeError(errCode)
|
||||||
return
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
if receivedOpcode == .ConnectionClose {
|
if receivedOpcode == .ConnectionClose {
|
||||||
var code = CloseCode.Normal.rawValue
|
var code = CloseCode.Normal.rawValue
|
||||||
if payloadLen == 1 {
|
if payloadLen == 1 {
|
||||||
code = CloseCode.ProtocolError.rawValue
|
code = CloseCode.ProtocolError.rawValue
|
||||||
} else if payloadLen > 1 {
|
} else if payloadLen > 1 {
|
||||||
code = WebSocket.readUint16(buffer, offset: offset)
|
code = WebSocket.readUint16(baseAddress, offset: offset)
|
||||||
if code < 1000 || (code > 1003 && code < 1007) || (code > 1011 && code < 3000) {
|
if code < 1000 || (code > 1003 && code < 1007) || (code > 1011 && code < 3000) {
|
||||||
code = CloseCode.ProtocolError.rawValue
|
code = CloseCode.ProtocolError.rawValue
|
||||||
}
|
}
|
||||||
@ -584,7 +583,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
if payloadLen > 2 {
|
if payloadLen > 2 {
|
||||||
let len = Int(payloadLen-2)
|
let len = Int(payloadLen-2)
|
||||||
if len > 0 {
|
if len > 0 {
|
||||||
let bytes = UnsafePointer<UInt8>((buffer+offset))
|
let bytes = baseAddress + offset
|
||||||
let str: NSString? = NSString(data: NSData(bytes: bytes, length: len), encoding: NSUTF8StringEncoding)
|
let str: NSString? = NSString(data: NSData(bytes: bytes, length: len), encoding: NSUTF8StringEncoding)
|
||||||
if str == nil {
|
if str == nil {
|
||||||
code = CloseCode.ProtocolError.rawValue
|
code = CloseCode.ProtocolError.rawValue
|
||||||
@ -593,23 +592,23 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
}
|
}
|
||||||
doDisconnect(errorWithDetail("connection closed by server", code: code))
|
doDisconnect(errorWithDetail("connection closed by server", code: code))
|
||||||
writeError(code)
|
writeError(code)
|
||||||
return
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
if isControlFrame && payloadLen > 125 {
|
if isControlFrame && payloadLen > 125 {
|
||||||
writeError(CloseCode.ProtocolError.rawValue)
|
writeError(CloseCode.ProtocolError.rawValue)
|
||||||
return
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
var dataLength = UInt64(payloadLen)
|
var dataLength = UInt64(payloadLen)
|
||||||
if dataLength == 127 {
|
if dataLength == 127 {
|
||||||
dataLength = WebSocket.readUint64(buffer, offset: offset)
|
dataLength = WebSocket.readUint64(baseAddress, offset: offset)
|
||||||
offset += sizeof(UInt64)
|
offset += sizeof(UInt64)
|
||||||
} else if dataLength == 126 {
|
} else if dataLength == 126 {
|
||||||
dataLength = UInt64(WebSocket.readUint16(buffer, offset: offset))
|
dataLength = UInt64(WebSocket.readUint16(baseAddress, offset: offset))
|
||||||
offset += sizeof(UInt16)
|
offset += sizeof(UInt16)
|
||||||
}
|
}
|
||||||
if bufferLen < offset || UInt64(bufferLen - offset) < dataLength {
|
if bufferLen < offset || UInt64(bufferLen - offset) < dataLength {
|
||||||
fragBuffer = NSData(bytes: buffer, length: bufferLen)
|
fragBuffer = NSData(bytes: baseAddress, length: bufferLen)
|
||||||
return
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
var len = dataLength
|
var len = dataLength
|
||||||
if dataLength > UInt64(bufferLen) {
|
if dataLength > UInt64(bufferLen) {
|
||||||
@ -620,7 +619,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
len = 0
|
len = 0
|
||||||
data = NSData()
|
data = NSData()
|
||||||
} else {
|
} else {
|
||||||
data = NSData(bytes: UnsafePointer<UInt8>((buffer+offset)), length: Int(len))
|
data = NSData(bytes: baseAddress+offset, length: Int(len))
|
||||||
}
|
}
|
||||||
if receivedOpcode == .Pong {
|
if receivedOpcode == .Pong {
|
||||||
if canDispatch {
|
if canDispatch {
|
||||||
@ -630,12 +629,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
s.pongDelegate?.websocketDidReceivePong(s)
|
s.pongDelegate?.websocketDidReceivePong(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let step = Int(offset+numericCast(len))
|
return buffer.fromOffset(offset + Int(len))
|
||||||
let extra = bufferLen-step
|
|
||||||
if extra > 0 {
|
|
||||||
processRawMessage((buffer+step), bufferLen: extra)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
var response = readStack.last
|
var response = readStack.last
|
||||||
if isControlFrame {
|
if isControlFrame {
|
||||||
@ -645,7 +639,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
let errCode = CloseCode.ProtocolError.rawValue
|
let errCode = CloseCode.ProtocolError.rawValue
|
||||||
doDisconnect(errorWithDetail("continue frame before a binary or text frame", code: errCode))
|
doDisconnect(errorWithDetail("continue frame before a binary or text frame", code: errCode))
|
||||||
writeError(errCode)
|
writeError(errCode)
|
||||||
return
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
var isNew = false
|
var isNew = false
|
||||||
if response == nil {
|
if response == nil {
|
||||||
@ -654,7 +648,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
doDisconnect(errorWithDetail("first frame can't be a continue frame",
|
doDisconnect(errorWithDetail("first frame can't be a continue frame",
|
||||||
code: errCode))
|
code: errCode))
|
||||||
writeError(errCode)
|
writeError(errCode)
|
||||||
return
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
isNew = true
|
isNew = true
|
||||||
response = WSResponse()
|
response = WSResponse()
|
||||||
@ -669,7 +663,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
doDisconnect(errorWithDetail("second and beyond of fragment message must be a continue frame",
|
doDisconnect(errorWithDetail("second and beyond of fragment message must be a continue frame",
|
||||||
code: errCode))
|
code: errCode))
|
||||||
writeError(errCode)
|
writeError(errCode)
|
||||||
return
|
return emptyBuffer
|
||||||
}
|
}
|
||||||
response!.buffer!.appendData(data)
|
response!.buffer!.appendData(data)
|
||||||
}
|
}
|
||||||
@ -684,20 +678,18 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let step = Int(offset+numericCast(len))
|
let step = Int(offset+numericCast(len))
|
||||||
let extra = bufferLen-step
|
return buffer.fromOffset(step)
|
||||||
if extra > 0 {
|
|
||||||
processExtra((buffer+step), bufferLen: extra)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///process the extra of a buffer
|
/// Process all messages in the buffer if possible.
|
||||||
private func processExtra(buffer: UnsafePointer<UInt8>, bufferLen: Int) {
|
private func processRawMessagesInBuffer(pointer: UnsafePointer<UInt8>, bufferLen: Int) {
|
||||||
if bufferLen < 2 {
|
var buffer = UnsafeBufferPointer(start: pointer, count: bufferLen)
|
||||||
fragBuffer = NSData(bytes: buffer, length: bufferLen)
|
repeat {
|
||||||
} else {
|
buffer = processOneRawMessage(inBuffer: buffer)
|
||||||
processRawMessage(buffer, bufferLen: bufferLen)
|
} while buffer.count >= 2
|
||||||
|
if buffer.count > 0 {
|
||||||
|
fragBuffer = NSData(buffer: buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -835,6 +827,25 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private extension NSData {
|
||||||
|
|
||||||
|
convenience init(buffer: UnsafeBufferPointer<UInt8>) {
|
||||||
|
self.init(bytes: buffer.baseAddress, length: buffer.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension UnsafeBufferPointer {
|
||||||
|
|
||||||
|
func fromOffset(offset: Int) -> UnsafeBufferPointer<Element> {
|
||||||
|
return UnsafeBufferPointer<Element>(start: baseAddress.advancedBy(offset), count: count - offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private let emptyBuffer = UnsafeBufferPointer<UInt8>(start: nil, count: 0)
|
||||||
|
|
||||||
|
|
||||||
public class SSLCert {
|
public class SSLCert {
|
||||||
var certData: NSData?
|
var certData: NSData?
|
||||||
var key: SecKeyRef?
|
var key: SecKeyRef?
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user