bump websocket version
This commit is contained in:
parent
4ee196c5fb
commit
ed3d49001f
@ -25,6 +25,7 @@ class SocketParserTest: XCTestCase {
|
|||||||
"0/swift": ("/swift", [], [], -1),
|
"0/swift": ("/swift", [], [], -1),
|
||||||
"1/swift": ("/swift", [], [], -1),
|
"1/swift": ("/swift", [], [], -1),
|
||||||
"4\"ERROR\"": ("/", ["ERROR"], [], -1),
|
"4\"ERROR\"": ("/", ["ERROR"], [], -1),
|
||||||
|
"4{\"test\":2}": ("/", [["test": 2]], [], -1),
|
||||||
"41": ("/", [1], [], -1)]
|
"41": ("/", [1], [], -1)]
|
||||||
|
|
||||||
func testDisconnect() {
|
func testDisconnect() {
|
||||||
@ -87,6 +88,11 @@ class SocketParserTest: XCTestCase {
|
|||||||
validateParseResult(message)
|
validateParseResult(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testErrorTypeDictionary() {
|
||||||
|
let message = "4{\"test\":2}"
|
||||||
|
validateParseResult(message)
|
||||||
|
}
|
||||||
|
|
||||||
func testErrorTypeInt() {
|
func testErrorTypeInt() {
|
||||||
let message = "41"
|
let message = "41"
|
||||||
validateParseResult(message)
|
validateParseResult(message)
|
||||||
|
|||||||
@ -116,7 +116,7 @@ extension SocketParsable {
|
|||||||
|
|
||||||
switch parseData(noPlaceholders) {
|
switch parseData(noPlaceholders) {
|
||||||
case let .Left(err):
|
case let .Left(err):
|
||||||
// If first you don't succeed, try again
|
// Errors aren't always enclosed in an array
|
||||||
if case let .Right(data) = parseData("\([noPlaceholders as AnyObject])") {
|
if case let .Right(data) = parseData("\([noPlaceholders as AnyObject])") {
|
||||||
return .Right(SocketPacket(type: type, data: data, id: Int(idString) ?? -1,
|
return .Right(SocketPacket(type: type, data: data, id: Int(idString) ?? -1,
|
||||||
nsp: namespace, placeholders: placeholders))
|
nsp: namespace, placeholders: placeholders))
|
||||||
|
|||||||
@ -180,30 +180,42 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///write a string to the websocket. This sends it as a text frame.
|
/**
|
||||||
public func writeString(str: String) {
|
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.
|
||||||
|
- parameter str: The string to write.
|
||||||
|
- parameter completion: The (optional) completion handler.
|
||||||
|
*/
|
||||||
|
public func writeString(str: String, completion: (() -> ())? = nil) {
|
||||||
guard isConnected else { return }
|
guard isConnected else { return }
|
||||||
dequeueWrite(str.dataUsingEncoding(NSUTF8StringEncoding)!, code: .TextFrame)
|
dequeueWrite(str.dataUsingEncoding(NSUTF8StringEncoding)!, code: .TextFrame, writeCompletion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
///write binary data to the websocket. This sends it as a binary frame.
|
/**
|
||||||
public func writeData(data: NSData) {
|
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.
|
||||||
|
- parameter data: The data to write.
|
||||||
|
- parameter completion: The (optional) completion handler.
|
||||||
|
*/
|
||||||
|
public func writeData(data: NSData, completion: (() -> ())? = nil) {
|
||||||
guard isConnected else { return }
|
guard isConnected else { return }
|
||||||
dequeueWrite(data, code: .BinaryFrame)
|
dequeueWrite(data, code: .BinaryFrame, writeCompletion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
//write a ping to the websocket. This sends it as a control frame.
|
//write a ping to the websocket. This sends it as a control frame.
|
||||||
//yodel a sound to the planet. This sends it as an astroid. http://youtu.be/Eu5ZJELRiJ8?t=42s
|
//yodel a sound to the planet. This sends it as an astroid. http://youtu.be/Eu5ZJELRiJ8?t=42s
|
||||||
public func writePing(data: NSData) {
|
public func writePing(data: NSData, completion: (() -> ())? = nil) {
|
||||||
guard isConnected else { return }
|
guard isConnected else { return }
|
||||||
dequeueWrite(data, code: .Ping)
|
dequeueWrite(data, code: .Ping, writeCompletion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
//private method that starts the connection
|
//private method that starts the connection
|
||||||
private func createHTTPRequest() {
|
private func createHTTPRequest() {
|
||||||
|
|
||||||
let urlRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, "GET",
|
let urlRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, "GET",
|
||||||
url, kCFHTTPVersion1_1).takeRetainedValue()
|
url, kCFHTTPVersion1_1).takeRetainedValue()
|
||||||
|
|
||||||
var port = url.port
|
var port = url.port
|
||||||
if port == nil {
|
if port == nil {
|
||||||
@ -283,18 +295,18 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
if let cipherSuites = self.enabledSSLCipherSuites {
|
if let cipherSuites = self.enabledSSLCipherSuites {
|
||||||
if let sslContextIn = CFReadStreamCopyProperty(inputStream, kCFStreamPropertySSLContext) as! SSLContextRef?,
|
if let sslContextIn = CFReadStreamCopyProperty(inputStream, kCFStreamPropertySSLContext) as! SSLContextRef?,
|
||||||
sslContextOut = CFWriteStreamCopyProperty(outputStream, kCFStreamPropertySSLContext) as! SSLContextRef? {
|
sslContextOut = CFWriteStreamCopyProperty(outputStream, kCFStreamPropertySSLContext) as! SSLContextRef? {
|
||||||
let resIn = SSLSetEnabledCiphers(sslContextIn, cipherSuites, cipherSuites.count)
|
let resIn = SSLSetEnabledCiphers(sslContextIn, cipherSuites, cipherSuites.count)
|
||||||
let resOut = SSLSetEnabledCiphers(sslContextOut, cipherSuites, cipherSuites.count)
|
let resOut = SSLSetEnabledCiphers(sslContextOut, cipherSuites, cipherSuites.count)
|
||||||
if resIn != errSecSuccess {
|
if resIn != errSecSuccess {
|
||||||
let error = self.errorWithDetail("Error setting ingoing cypher suites", code: UInt16(resIn))
|
let error = self.errorWithDetail("Error setting ingoing cypher suites", code: UInt16(resIn))
|
||||||
disconnectStream(error)
|
disconnectStream(error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if resOut != errSecSuccess {
|
if resOut != errSecSuccess {
|
||||||
let error = self.errorWithDetail("Error setting outgoing cypher suites", code: UInt16(resOut))
|
let error = self.errorWithDetail("Error setting outgoing cypher suites", code: UInt16(resOut))
|
||||||
disconnectStream(error)
|
disconnectStream(error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CFReadStreamSetDispatchQueue(inStream, WebSocket.sharedWorkQueue)
|
CFReadStreamSetDispatchQueue(inStream, WebSocket.sharedWorkQueue)
|
||||||
@ -428,7 +440,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
}
|
}
|
||||||
case -1:
|
case -1:
|
||||||
fragBuffer = NSData(bytes: buffer, length: bufferLen)
|
fragBuffer = NSData(bytes: buffer, length: bufferLen)
|
||||||
break //do nothing, we are going to collect more data
|
break //do nothing, we are going to collect more data
|
||||||
default:
|
default:
|
||||||
doDisconnect(errorWithDetail("Invalid HTTP upgrade", code: UInt16(code)))
|
doDisconnect(errorWithDetail("Invalid HTTP upgrade", code: UInt16(code)))
|
||||||
}
|
}
|
||||||
@ -547,10 +559,10 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
let isControlFrame = (receivedOpcode == .ConnectionClose || receivedOpcode == .Ping)
|
let isControlFrame = (receivedOpcode == .ConnectionClose || receivedOpcode == .Ping)
|
||||||
if !isControlFrame && (receivedOpcode != .BinaryFrame && receivedOpcode != .ContinueFrame &&
|
if !isControlFrame && (receivedOpcode != .BinaryFrame && receivedOpcode != .ContinueFrame &&
|
||||||
receivedOpcode != .TextFrame && receivedOpcode != .Pong) {
|
receivedOpcode != .TextFrame && receivedOpcode != .Pong) {
|
||||||
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
|
||||||
}
|
}
|
||||||
if isControlFrame && isFin == 0 {
|
if isControlFrame && isFin == 0 {
|
||||||
let errCode = CloseCode.ProtocolError.rawValue
|
let errCode = CloseCode.ProtocolError.rawValue
|
||||||
@ -603,7 +615,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
if dataLength > UInt64(bufferLen) {
|
if dataLength > UInt64(bufferLen) {
|
||||||
len = UInt64(bufferLen-offset)
|
len = UInt64(bufferLen-offset)
|
||||||
}
|
}
|
||||||
var data: NSData!
|
let data: NSData
|
||||||
if len < 0 {
|
if len < 0 {
|
||||||
len = 0
|
len = 0
|
||||||
data = NSData()
|
data = NSData()
|
||||||
@ -739,7 +751,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
dequeueWrite(NSData(bytes: buffer, length: sizeof(UInt16)), code: .ConnectionClose)
|
dequeueWrite(NSData(bytes: buffer, length: sizeof(UInt16)), code: .ConnectionClose)
|
||||||
}
|
}
|
||||||
///used to write things to the stream
|
///used to write things to the stream
|
||||||
private func dequeueWrite(data: NSData, code: OpCode) {
|
private func dequeueWrite(data: NSData, code: OpCode, writeCompletion: (() -> ())? = nil) {
|
||||||
writeQueue.addOperationWithBlock { [weak self] in
|
writeQueue.addOperationWithBlock { [weak self] in
|
||||||
//stream isn't ready, let's wait
|
//stream isn't ready, let's wait
|
||||||
guard let s = self else { return }
|
guard let s = self else { return }
|
||||||
@ -788,6 +800,12 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
|||||||
total += len
|
total += len
|
||||||
}
|
}
|
||||||
if total >= offset {
|
if total >= offset {
|
||||||
|
if let queue = self?.queue, callback = writeCompletion {
|
||||||
|
dispatch_async(queue) {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user