Merge branch '1.2'
This commit is contained in:
commit
a0dff2fea4
@ -26,7 +26,7 @@ import Foundation
|
||||
|
||||
extension String {
|
||||
private var length:Int {
|
||||
return countElements(self)
|
||||
return count(self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
var connected:Bool {
|
||||
return self._connected
|
||||
}
|
||||
|
||||
|
||||
weak var client:SocketEngineClient?
|
||||
var cookies:[NSHTTPCookie]?
|
||||
var pingInterval:Int?
|
||||
@ -83,7 +83,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
return self._websocket
|
||||
}
|
||||
var ws:WebSocket?
|
||||
|
||||
|
||||
public init(client:SocketEngineClient, forcePolling:Bool,
|
||||
forceWebsockets:Bool, withCookies cookies:[NSHTTPCookie]?) {
|
||||
self.client = client
|
||||
@ -93,19 +93,19 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
self.session = NSURLSession(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration(),
|
||||
delegate: nil, delegateQueue: self.workQueue)
|
||||
}
|
||||
|
||||
|
||||
public func close(#fast:Bool) {
|
||||
self.pingTimer?.invalidate()
|
||||
self.closed = true
|
||||
|
||||
|
||||
self.write("", withType: PacketType.CLOSE, withData: nil)
|
||||
self.ws?.disconnect()
|
||||
|
||||
|
||||
if fast || self.polling {
|
||||
self.client?.didForceClose("Disconnect")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func createBinaryDataForSend(data:NSData) -> (NSData?, String?) {
|
||||
if self.websocket {
|
||||
var byteArray = [UInt8](count: 1, repeatedValue: 0x0)
|
||||
@ -117,20 +117,20 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
var str = "b4"
|
||||
str += data.base64EncodedStringWithOptions(
|
||||
NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
|
||||
|
||||
|
||||
return (nil, str)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func createURLs(params:[String: AnyObject]?) -> (String, String) {
|
||||
if self.client == nil {
|
||||
return ("", "")
|
||||
}
|
||||
|
||||
|
||||
var url = "\(self.client!.socketURL)/socket.io/?transport="
|
||||
var urlPolling:String
|
||||
var urlWebSocket:String
|
||||
|
||||
|
||||
if self.client!.secure {
|
||||
urlPolling = "https://" + url + "polling"
|
||||
urlWebSocket = "wss://" + url + "websocket"
|
||||
@ -138,16 +138,16 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
urlPolling = "http://" + url + "polling"
|
||||
urlWebSocket = "ws://" + url + "websocket"
|
||||
}
|
||||
|
||||
|
||||
if params != nil {
|
||||
for (key, value) in params! {
|
||||
let keyEsc = key.stringByAddingPercentEncodingWithAllowedCharacters(
|
||||
NSCharacterSet.URLHostAllowedCharacterSet())!
|
||||
urlPolling += "&\(keyEsc)="
|
||||
urlWebSocket += "&\(keyEsc)="
|
||||
|
||||
|
||||
if value is String {
|
||||
let valueEsc = (value as String).stringByAddingPercentEncodingWithAllowedCharacters(
|
||||
let valueEsc = (value as! String).stringByAddingPercentEncodingWithAllowedCharacters(
|
||||
NSCharacterSet.URLHostAllowedCharacterSet())!
|
||||
urlPolling += "\(valueEsc)"
|
||||
urlWebSocket += "\(valueEsc)"
|
||||
@ -157,26 +157,26 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (urlPolling, urlWebSocket)
|
||||
}
|
||||
|
||||
|
||||
private func createWebsocket(andConnect connect:Bool) {
|
||||
self.ws = WebSocket(url: NSURL(string: self.urlWebSocket! + "&sid=\(self.sid)")!)
|
||||
self.ws?.queue = self.handleQueue
|
||||
self.ws?.delegate = self
|
||||
|
||||
|
||||
if connect {
|
||||
self.ws?.connect()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func doFastUpgrade() {
|
||||
if self.waitingForPoll {
|
||||
NSLog("Outstanding poll when switched to websockets," +
|
||||
"we'll probably disconnect soon. You should report this.")
|
||||
}
|
||||
|
||||
|
||||
self.sendWebSocketMessage("", withType: PacketType.UPGRADE, datas: nil)
|
||||
self._websocket = true
|
||||
self._polling = false
|
||||
@ -184,25 +184,25 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
self.probing = false
|
||||
self.flushProbeWait()
|
||||
}
|
||||
|
||||
|
||||
private func doPoll() {
|
||||
if self.websocket || self.waitingForPoll || !self.connected {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
self.waitingForPoll = true
|
||||
let req = NSMutableURLRequest(URL: NSURL(string: self.urlPolling! + "&sid=\(self.sid)&b64=1")!)
|
||||
|
||||
|
||||
self.doRequest(req)
|
||||
}
|
||||
|
||||
|
||||
private func doRequest(req:NSMutableURLRequest) {
|
||||
if !self.polling {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
req.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
|
||||
|
||||
|
||||
// NSLog("Doing request: \(req)")
|
||||
self.session.dataTaskWithRequest(req) {[weak self] data, res, err in
|
||||
if self == nil {
|
||||
@ -213,20 +213,21 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
} else {
|
||||
NSLog(err.localizedDescription)
|
||||
}
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// NSLog("Got response: \(res)")
|
||||
|
||||
|
||||
if let str = NSString(data: data, encoding: NSUTF8StringEncoding) as? String {
|
||||
dispatch_async(self!.parseQueue) {
|
||||
self?.parsePollingMessage(str)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
self?.waitingForPoll = false
|
||||
|
||||
if self!.fastUpgrade {
|
||||
self?.doFastUpgrade()
|
||||
return
|
||||
@ -235,26 +236,26 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
}
|
||||
}.resume()
|
||||
}
|
||||
|
||||
|
||||
private func flushProbeWait() {
|
||||
// NSLog("flushing probe wait")
|
||||
dispatch_async(self.emitQueue) {[weak self] in
|
||||
if self == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
for waiter in self!.probeWait {
|
||||
self?.write(waiter.msg, withType: waiter.type, withData: waiter.data)
|
||||
}
|
||||
|
||||
|
||||
self?.probeWait.removeAll(keepCapacity: false)
|
||||
|
||||
|
||||
if self?.postWait.count != 0 {
|
||||
self?.flushWaitingForPostToWebSocket()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func flushWaitingForPost() {
|
||||
if self.postWait.count == 0 || !self.connected {
|
||||
return
|
||||
@ -262,33 +263,33 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
self.flushWaitingForPostToWebSocket()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
var postStr = ""
|
||||
|
||||
|
||||
for packet in self.postWait {
|
||||
let len = countElements(packet)
|
||||
|
||||
let len = count(packet)
|
||||
|
||||
postStr += "\(len):\(packet)"
|
||||
}
|
||||
|
||||
|
||||
self.postWait.removeAll(keepCapacity: false)
|
||||
|
||||
|
||||
let req = NSMutableURLRequest(URL: NSURL(string: self.urlPolling! + "&sid=\(self.sid)")!)
|
||||
|
||||
|
||||
req.HTTPMethod = "POST"
|
||||
req.setValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type")
|
||||
|
||||
|
||||
let postData = postStr.dataUsingEncoding(NSUTF8StringEncoding,
|
||||
allowLossyConversion: false)!
|
||||
|
||||
|
||||
req.HTTPBody = postData
|
||||
req.setValue(String(postData.length), forHTTPHeaderField: "Content-Length")
|
||||
|
||||
|
||||
self.waitingForPost = true
|
||||
|
||||
|
||||
// NSLog("posting: \(postStr)")
|
||||
// NSLog("Posting with WS status of: \(self.websocket)")
|
||||
|
||||
|
||||
self.session.dataTaskWithRequest(req) {[weak self] data, res, err in
|
||||
if self == nil {
|
||||
return
|
||||
@ -299,7 +300,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
NSLog(err.localizedDescription)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
self?.waitingForPost = false
|
||||
dispatch_async(self!.emitQueue) {
|
||||
if !self!.fastUpgrade {
|
||||
@ -308,89 +309,90 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
}
|
||||
}}.resume()
|
||||
}
|
||||
|
||||
|
||||
// We had packets waiting for send when we upgraded
|
||||
// Send them raw
|
||||
private func flushWaitingForPostToWebSocket() {
|
||||
for msg in self.postWait {
|
||||
self.ws?.writeString(msg)
|
||||
}
|
||||
|
||||
|
||||
self.postWait.removeAll(keepCapacity: true)
|
||||
}
|
||||
|
||||
|
||||
// A poll failed, tell the client about it
|
||||
|
||||
private func handlePollingFailed(reason:String) {
|
||||
self._connected = false
|
||||
self.ws?.disconnect()
|
||||
self.pingTimer?.invalidate()
|
||||
self.waitingForPoll = false
|
||||
self.waitingForPost = false
|
||||
|
||||
|
||||
if self.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if !self.closed && !self.client!.reconnecting {
|
||||
self.client?.pollingDidFail(reason)
|
||||
} else if !self.client!.reconnecting {
|
||||
self.client?.didForceClose(reason)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func open(opts:[String: AnyObject]? = nil) {
|
||||
if self.connected {
|
||||
fatalError("Engine tried to open while connected")
|
||||
}
|
||||
|
||||
|
||||
self.closed = false
|
||||
let (urlPolling, urlWebSocket) = self.createURLs(opts)
|
||||
self.urlPolling = urlPolling
|
||||
self.urlWebSocket = urlWebSocket
|
||||
|
||||
|
||||
if self.forceWebsockets {
|
||||
self._polling = false
|
||||
self._websocket = true
|
||||
self.createWebsocket(andConnect: true)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let reqPolling = NSMutableURLRequest(URL: NSURL(string: urlPolling + "&b64=1")!)
|
||||
|
||||
|
||||
if self.cookies != nil {
|
||||
let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(self.cookies!)
|
||||
reqPolling.allHTTPHeaderFields = headers
|
||||
}
|
||||
|
||||
|
||||
self.doRequest(reqPolling)
|
||||
}
|
||||
|
||||
|
||||
// Translatation of engine.io-parser#decodePayload
|
||||
private func parsePollingMessage(str:String) {
|
||||
if str.length == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// println(str)
|
||||
|
||||
|
||||
let strArray = Array(str)
|
||||
var length = ""
|
||||
var n = 0
|
||||
var msg = ""
|
||||
|
||||
|
||||
func testLength(length:String, inout n:Int) -> Bool {
|
||||
if let num = length.toInt() {
|
||||
n = num
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
for var i = 0, l = str.length; i < l; i = i &+ 1 {
|
||||
let chr = String(strArray[i])
|
||||
|
||||
|
||||
if chr != ":" {
|
||||
length += chr
|
||||
} else {
|
||||
@ -399,16 +401,16 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
self.handlePollingFailed("Error parsing XHR message")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
msg = String(strArray[i&+1...i&+n])
|
||||
|
||||
|
||||
if let lengthInt = length.toInt() {
|
||||
if lengthInt != msg.length {
|
||||
NSLog("parsing error: \(str)")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if msg.length != 0 {
|
||||
// Be sure to capture the value of the msg
|
||||
dispatch_async(self.handleQueue) {[weak self, msg] in
|
||||
@ -416,54 +418,54 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
i += n
|
||||
length = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func parseEngineData(data:NSData) {
|
||||
if self.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
dispatch_async(self.client!.handleQueue) {[weak self] in
|
||||
self?.client?.parseBinaryData(data.subdataWithRange(NSMakeRange(1, data.length - 1)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func parseEngineMessage(var message:String, fromPolling:Bool) {
|
||||
// NSLog("Engine got message: \(message)")
|
||||
if fromPolling {
|
||||
fixDoubleUTF8(&message)
|
||||
}
|
||||
|
||||
|
||||
let type = message["^(\\d)"].groups()?[1]
|
||||
|
||||
|
||||
if type != PacketType.MESSAGE.rawValue {
|
||||
// TODO Handle other packets
|
||||
if message.hasPrefix("b4") {
|
||||
// binary in base64 string
|
||||
|
||||
|
||||
message.removeRange(Range<String.Index>(start: message.startIndex,
|
||||
end: advance(message.startIndex, 2)))
|
||||
|
||||
|
||||
if let data = NSData(base64EncodedString: message,
|
||||
options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) {
|
||||
// println("sending \(data)")
|
||||
|
||||
|
||||
if self.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
dispatch_async(self.client!.handleQueue) {[weak self] in
|
||||
self?.client?.parseBinaryData(data)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return
|
||||
} else if type == PacketType.NOOP.rawValue {
|
||||
self.doPoll()
|
||||
@ -474,14 +476,14 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
self.upgradeTransport()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
return
|
||||
} else if type == PacketType.OPEN.rawValue {
|
||||
var err:NSError?
|
||||
|
||||
|
||||
message.removeAtIndex(message.startIndex)
|
||||
let mesData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
|
||||
|
||||
|
||||
if let json = NSJSONSerialization.JSONObjectWithData(mesData,
|
||||
options: NSJSONReadingOptions.AllowFragments, error: &err) as? NSDictionary {
|
||||
if let sid = json["sid"] as? String {
|
||||
@ -495,55 +497,55 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
NSLog("Error handshaking")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if let pingInterval = json["pingInterval"] as? Int {
|
||||
self.pingInterval = pingInterval / 1000
|
||||
}
|
||||
} else {
|
||||
fatalError("Error parsing engine connect")
|
||||
}
|
||||
|
||||
|
||||
self.startPingTimer()
|
||||
|
||||
|
||||
if !self.forceWebsockets {
|
||||
self.doPoll()
|
||||
}
|
||||
|
||||
|
||||
return
|
||||
} else if type == PacketType.CLOSE.rawValue {
|
||||
if self.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if self.polling {
|
||||
self.client!.didForceClose("Disconnect")
|
||||
}
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
// println("Got something idk what to do with")
|
||||
// println(messageString)
|
||||
}
|
||||
|
||||
|
||||
// Remove message type
|
||||
message.removeAtIndex(message.startIndex)
|
||||
|
||||
|
||||
if self.client == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
dispatch_async(self.client!.handleQueue) {[weak self] in
|
||||
self?.client?.parseSocketMessage(message)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func probeWebSocket() {
|
||||
if self.websocketConnected {
|
||||
self.sendWebSocketMessage("probe", withType: PacketType.PING)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Send an engine message (4)
|
||||
public func send(msg:String, withData datas:ContiguousArray<NSData>?) {
|
||||
if self.probing {
|
||||
@ -552,11 +554,11 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
self.write(msg, withType: PacketType.MESSAGE, withData: datas)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func sendPing() {
|
||||
self.write("", withType: PacketType.PING, withData: nil)
|
||||
}
|
||||
|
||||
|
||||
/// Send polling message.
|
||||
/// Only call on emitQueue
|
||||
private func sendPollMessage(var msg:String, withType type:PacketType,
|
||||
@ -564,29 +566,29 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
// println("Sending poll: \(msg) as type: \(type.rawValue)")
|
||||
doubleEncodeUTF8(&msg)
|
||||
let strMsg = "\(type.rawValue)\(msg)"
|
||||
|
||||
|
||||
self.postWait.append(strMsg)
|
||||
|
||||
|
||||
if datas != nil {
|
||||
for data in datas! {
|
||||
let (nilData, b64Data) = self.createBinaryDataForSend(data)
|
||||
|
||||
|
||||
self.postWait.append(b64Data!)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !self.waitingForPost {
|
||||
self.flushWaitingForPost()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Send message on WebSockets
|
||||
/// Only call on emitQueue
|
||||
private func sendWebSocketMessage(str:String, withType type:PacketType,
|
||||
datas:ContiguousArray<NSData>? = nil) {
|
||||
// println("Sending ws: \(str) as type: \(type.rawValue)")
|
||||
self.ws?.writeString("\(type.rawValue)\(str)")
|
||||
|
||||
|
||||
if datas != nil {
|
||||
for data in datas! {
|
||||
let (data, nilString) = self.createBinaryDataForSend(data)
|
||||
@ -596,13 +598,13 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Starts the ping timer
|
||||
private func startPingTimer() {
|
||||
if self.pingInterval == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
self.pingTimer?.invalidate()
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
self.pingTimer = NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(self.pingInterval!),
|
||||
@ -610,7 +612,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
selector: Selector("sendPing"), userInfo: nil, repeats: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func upgradeTransport() {
|
||||
if self.websocketConnected {
|
||||
// NSLog("Doing fast upgrade")
|
||||
@ -620,13 +622,13 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
self.sendPollMessage("", withType: PacketType.NOOP)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func write(msg:String, withType type:PacketType, withData data:ContiguousArray<NSData>?) {
|
||||
dispatch_async(self.emitQueue) {[weak self] in
|
||||
if self == nil || !self!.connected {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if self!.websocket {
|
||||
// NSLog("writing ws: \(msg):\(data)")
|
||||
self?.sendWebSocketMessage(msg, withType: type, datas: data)
|
||||
@ -636,12 +638,12 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Delagate methods
|
||||
|
||||
|
||||
public func websocketDidConnect(socket:WebSocket) {
|
||||
self.websocketConnected = true
|
||||
|
||||
|
||||
if !self.forceWebsockets {
|
||||
self.probing = true
|
||||
self.probeWebSocket()
|
||||
@ -651,21 +653,21 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
self._polling = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func websocketDidDisconnect(socket:WebSocket, error:NSError?) {
|
||||
self.websocketConnected = false
|
||||
self.probing = false
|
||||
|
||||
|
||||
if self.closed {
|
||||
self.client?.didForceClose("Disconnect")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if self.websocket {
|
||||
self.pingTimer?.invalidate()
|
||||
self._connected = false
|
||||
self._websocket = false
|
||||
|
||||
|
||||
let reason = error?.localizedDescription
|
||||
self.client?.webSocketDidCloseWithCode(1,
|
||||
reason: reason == nil ? "Socket Disconnected" : reason!)
|
||||
@ -673,11 +675,11 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
||||
self.flushProbeWait()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func websocketDidReceiveMessage(socket:WebSocket, text:String) {
|
||||
self.parseEngineMessage(text, fromPolling: false)
|
||||
}
|
||||
|
||||
|
||||
public func websocketDidReceiveData(socket:WebSocket, data:NSData) {
|
||||
self.parseEngineData(data)
|
||||
}
|
||||
|
||||
@ -34,4 +34,4 @@ func doubleEncodeUTF8(inout str:String) {
|
||||
let latin1 = str.dataUsingEncoding(NSUTF8StringEncoding)!
|
||||
let utf8 = NSString(data: latin1, encoding: NSISOLatin1StringEncoding)!
|
||||
str = utf8 as String
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ public class SocketIOClient: NSObject, SocketEngineClient {
|
||||
return
|
||||
}
|
||||
|
||||
self?.ackHandlers.addAck(ack, callback)
|
||||
self?.ackHandlers.addAck(ack, callback: callback)
|
||||
|
||||
dispatch_async(self!.emitQueue) {
|
||||
self?._emit(event, items, ack: ack)
|
||||
@ -344,7 +344,7 @@ public class SocketIOClient: NSObject, SocketEngineClient {
|
||||
var ackData:[AnyObject]?
|
||||
|
||||
if data is NSArray {
|
||||
ackData = data as? NSArray
|
||||
ackData = (data as? [AnyObject]?)!
|
||||
} else if data != nil {
|
||||
ackData = [data!]
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ enum SocketPacketType:Int {
|
||||
case ERROR = 4
|
||||
case BINARY_EVENT = 5
|
||||
case BINARY_ACK = 6
|
||||
|
||||
|
||||
init(str:String) {
|
||||
if let int = str.toInt() {
|
||||
self = SocketPacketType(rawValue: int)!
|
||||
@ -51,7 +51,7 @@ class SocketPacket {
|
||||
var nsp = ""
|
||||
var placeholders:Int?
|
||||
var type:SocketPacketType?
|
||||
|
||||
|
||||
init(type:SocketPacketType?, data:[AnyObject]? = nil, nsp:String = "",
|
||||
placeholders:Int? = nil, id:Int? = nil) {
|
||||
self.type = type
|
||||
@ -60,11 +60,11 @@ class SocketPacket {
|
||||
self.placeholders = placeholders
|
||||
self.id = id
|
||||
}
|
||||
|
||||
|
||||
func getEvent() -> String {
|
||||
return data?.removeAtIndex(0) as String
|
||||
return data?.removeAtIndex(0) as! String
|
||||
}
|
||||
|
||||
|
||||
func addData(data:NSData) -> Bool {
|
||||
func checkDoEvent() -> Bool {
|
||||
if self.placeholders == self.currentPlace {
|
||||
@ -73,14 +73,14 @@ class SocketPacket {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if checkDoEvent() {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
self.binary.append(data)
|
||||
self.currentPlace++
|
||||
|
||||
|
||||
if checkDoEvent() {
|
||||
self.currentPlace = 0
|
||||
return true
|
||||
@ -88,14 +88,14 @@ class SocketPacket {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func createMessageForEvent(event:String) -> String {
|
||||
var message:String
|
||||
var jsonSendError:NSError?
|
||||
|
||||
|
||||
if self.binary.count == 0 {
|
||||
self.type = SocketPacketType.EVENT
|
||||
|
||||
|
||||
if self.nsp == "/" {
|
||||
if self.id == nil {
|
||||
message = "2[\"\(event)\""
|
||||
@ -111,7 +111,7 @@ class SocketPacket {
|
||||
}
|
||||
} else {
|
||||
self.type = SocketPacketType.BINARY_EVENT
|
||||
|
||||
|
||||
if self.nsp == "/" {
|
||||
if self.id == nil {
|
||||
message = "5\(self.binary.count)-[\"\(event)\""
|
||||
@ -126,16 +126,16 @@ class SocketPacket {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return self.completeMessage(message)
|
||||
}
|
||||
|
||||
|
||||
func createAck() -> String {
|
||||
var msg:String
|
||||
|
||||
|
||||
if self.binary.count == 0 {
|
||||
self.type = SocketPacketType.ACK
|
||||
|
||||
|
||||
if nsp == "/" {
|
||||
msg = "3\(self.id!)["
|
||||
} else {
|
||||
@ -143,58 +143,57 @@ class SocketPacket {
|
||||
}
|
||||
} else {
|
||||
self.type = SocketPacketType.BINARY_ACK
|
||||
|
||||
|
||||
if nsp == "/" {
|
||||
msg = "6\(self.binary.count)-\(self.id!)["
|
||||
} else {
|
||||
msg = "6\(self.binary.count)-/\(self.nsp),\(self.id!)["
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return self.completeMessage(msg, ack: true)
|
||||
}
|
||||
|
||||
|
||||
func completeMessage(var message:String, ack:Bool = false) -> String {
|
||||
var err:NSError?
|
||||
|
||||
|
||||
if self.data == nil || self.data!.count == 0 {
|
||||
return message + "]"
|
||||
} else if !ack {
|
||||
message += ","
|
||||
}
|
||||
|
||||
|
||||
for arg in self.data! {
|
||||
|
||||
if arg is NSDictionary || arg is [AnyObject] {
|
||||
let jsonSend = NSJSONSerialization.dataWithJSONObject(arg,
|
||||
options: NSJSONWritingOptions(0), error: &err)
|
||||
let jsonString = NSString(data: jsonSend!, encoding: NSUTF8StringEncoding)
|
||||
|
||||
|
||||
message += jsonString! as String
|
||||
message += ","
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
if arg is String {
|
||||
message += "\"\(arg)\""
|
||||
message += ","
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
message += "\(arg)"
|
||||
message += ","
|
||||
}
|
||||
|
||||
|
||||
if message != "" {
|
||||
message.removeAtIndex(message.endIndex.predecessor())
|
||||
}
|
||||
|
||||
|
||||
return message + "]"
|
||||
}
|
||||
|
||||
|
||||
func fillInPlaceholders() {
|
||||
var newArr = NSMutableArray(array: self.data!)
|
||||
|
||||
|
||||
for i in 0..<self.data!.count {
|
||||
if let str = self.data?[i] as? String {
|
||||
if let num = str["~~(\\d)"].groups() {
|
||||
@ -204,10 +203,10 @@ class SocketPacket {
|
||||
newArr[i] = self._fillInPlaceholders(self.data![i])
|
||||
}
|
||||
}
|
||||
|
||||
self.data = newArr
|
||||
|
||||
self.data = newArr as [AnyObject]
|
||||
}
|
||||
|
||||
|
||||
private func _fillInPlaceholders(data:AnyObject) -> AnyObject {
|
||||
if let str = data as? String {
|
||||
if let num = str["~~(\\d)"].groups() {
|
||||
@ -217,19 +216,19 @@ class SocketPacket {
|
||||
}
|
||||
} else if let dict = data as? NSDictionary {
|
||||
var newDict = NSMutableDictionary(dictionary: dict)
|
||||
|
||||
|
||||
for (key, value) in dict {
|
||||
newDict[key as NSCopying] = _fillInPlaceholders(value)
|
||||
newDict[key as! NSCopying] = _fillInPlaceholders(value)
|
||||
}
|
||||
|
||||
|
||||
return newDict
|
||||
} else if let arr = data as? NSArray {
|
||||
var newArr = NSMutableArray(array: arr)
|
||||
|
||||
|
||||
for i in 0..<arr.count {
|
||||
newArr[i] = _fillInPlaceholders(arr[i])
|
||||
}
|
||||
|
||||
|
||||
return newArr
|
||||
} else {
|
||||
return data
|
||||
|
||||
@ -22,48 +22,48 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
private let shredder = SocketParser.PacketShredder()
|
||||
|
||||
class SocketParser {
|
||||
private static let shredder = SocketParser.PacketShredder()
|
||||
|
||||
// Translation of socket.io-parser#deconstructPacket
|
||||
private class PacketShredder {
|
||||
var buf = ContiguousArray<NSData>()
|
||||
|
||||
|
||||
func shred(data:AnyObject) -> AnyObject {
|
||||
if let bin = data as? NSData {
|
||||
let placeholder = ["_placeholder" :true, "num": buf.count]
|
||||
|
||||
|
||||
buf.append(bin)
|
||||
|
||||
|
||||
return placeholder
|
||||
} else if let arr = data as? NSArray {
|
||||
var newArr = NSMutableArray(array: arr)
|
||||
|
||||
|
||||
for i in 0..<arr.count {
|
||||
newArr[i] = shred(arr[i])
|
||||
}
|
||||
|
||||
|
||||
return newArr
|
||||
} else if let dict = data as? NSDictionary {
|
||||
var newDict = NSMutableDictionary(dictionary: dict)
|
||||
|
||||
|
||||
for (key, value) in newDict {
|
||||
newDict[key as NSCopying] = shred(value)
|
||||
newDict[key as! NSCopying] = shred(value)
|
||||
}
|
||||
|
||||
|
||||
return newDict
|
||||
} else {
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func deconstructPacket(packet:SocketPacket) {
|
||||
if packet.data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
var data = packet.data!
|
||||
|
||||
|
||||
for i in 0..<data.count {
|
||||
if data[i] is NSArray || data[i] is NSDictionary {
|
||||
data[i] = shred(data[i])
|
||||
@ -72,37 +72,37 @@ class SocketParser {
|
||||
buf.append(bin)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
packet.data = data
|
||||
packet.binary = buf
|
||||
buf.removeAll(keepCapacity: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Translation of socket.io-client#decodeString
|
||||
class func parseString(str:String) -> SocketPacket? {
|
||||
let arr = Array(str)
|
||||
let type = String(arr[0])
|
||||
|
||||
|
||||
if arr.count == 1 {
|
||||
return SocketPacket(type: SocketPacketType(str: type))
|
||||
}
|
||||
|
||||
|
||||
var id = nil as Int?
|
||||
var nsp = ""
|
||||
var i = 0
|
||||
var placeholders = -1
|
||||
|
||||
|
||||
if type == "5" || type == "6" {
|
||||
var buf = ""
|
||||
|
||||
|
||||
while arr[++i] != "-" {
|
||||
buf += String(arr[i])
|
||||
if i == arr.count {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if buf.toInt() == nil || arr[i] != "-" {
|
||||
NSLog("Error parsing \(str)")
|
||||
return nil
|
||||
@ -110,26 +110,26 @@ class SocketParser {
|
||||
placeholders = buf.toInt()!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if arr[i + 1] == "/" {
|
||||
while ++i < arr.count {
|
||||
let c = arr[i]
|
||||
|
||||
|
||||
if c == "," {
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
nsp += String(c)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if i + 1 >= arr.count {
|
||||
return SocketPacket(type: SocketPacketType(str: type),
|
||||
nsp: nsp, placeholders: placeholders, id: id)
|
||||
}
|
||||
|
||||
|
||||
let next = String(arr[i + 1])
|
||||
|
||||
|
||||
if next.toInt() != nil {
|
||||
var c = ""
|
||||
while ++i < arr.count {
|
||||
@ -140,48 +140,48 @@ class SocketParser {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
id = c.toInt()
|
||||
}
|
||||
|
||||
|
||||
if i + 1 < arr.count {
|
||||
let d = String(arr[++i...arr.count-1])
|
||||
let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\""
|
||||
|
||||
let data = SocketParser.parseData(noPlaceholders) as [AnyObject]
|
||||
|
||||
|
||||
let data = SocketParser.parseData(noPlaceholders) as! [AnyObject]
|
||||
|
||||
return SocketPacket(type: SocketPacketType(str: type), data: data,
|
||||
nsp: nsp, placeholders: placeholders, id: id)
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// Parses data for events
|
||||
class func parseData(data:String) -> AnyObject? {
|
||||
var err:NSError?
|
||||
let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
|
||||
let parsed:AnyObject? = NSJSONSerialization.JSONObjectWithData(stringData!,
|
||||
options: NSJSONReadingOptions.AllowFragments, error: &err)
|
||||
|
||||
|
||||
if err != nil {
|
||||
// println(err)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
return parsed
|
||||
}
|
||||
|
||||
|
||||
class func parseForEmit(packet:SocketPacket) {
|
||||
shredder.deconstructPacket(packet)
|
||||
}
|
||||
|
||||
|
||||
// Parses messages recieved
|
||||
class func parseSocketMessage(stringMessage:String, socket:SocketIOClient) {
|
||||
if stringMessage == "" {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
func checkNSP(nsp:String) -> Bool {
|
||||
if nsp == "" && socket.nsp != "/" {
|
||||
return true
|
||||
@ -189,33 +189,33 @@ class SocketParser {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let p = parseString(stringMessage) as SocketPacket!
|
||||
|
||||
|
||||
if p.type == SocketPacketType.EVENT {
|
||||
if checkNSP(p.nsp) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
socket.handleEvent(p.getEvent(), data: p.data,
|
||||
isInternalMessage: false, wantsAck: p.id)
|
||||
} else if p.type == SocketPacketType.ACK {
|
||||
if checkNSP(p.nsp) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
socket.handleAck(p.id!, data: p.data)
|
||||
} else if p.type == SocketPacketType.BINARY_EVENT {
|
||||
if checkNSP(p.nsp) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
socket.waitingData.append(p)
|
||||
} else if p.type == SocketPacketType.BINARY_ACK {
|
||||
if checkNSP(p.nsp) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
p.justAck = true
|
||||
socket.waitingData.append(p)
|
||||
} else if p.type == SocketPacketType.CONNECT {
|
||||
@ -230,25 +230,25 @@ class SocketParser {
|
||||
socket.didForceClose("Got Disconnect")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handles binary data
|
||||
class func parseBinaryData(data:NSData, socket:SocketIOClient) {
|
||||
// NSLog(data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.allZeros))
|
||||
|
||||
|
||||
if socket.waitingData.count == 0 {
|
||||
NSLog("Got data when not remaking packet")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let shouldExecute = socket.waitingData[0].addData(data)
|
||||
|
||||
|
||||
if !shouldExecute {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let packet = socket.waitingData.removeAtIndex(0)
|
||||
packet.fillInPlaceholders()
|
||||
|
||||
|
||||
if !packet.justAck {
|
||||
socket.handleEvent(packet.getEvent(), data: packet.data,
|
||||
wantsAck: packet.id)
|
||||
|
||||
@ -18,7 +18,7 @@ var swiftRegexCache = [String: NSRegularExpression]()
|
||||
public class SwiftRegex: NSObject, BooleanType {
|
||||
var target:String
|
||||
var regex: NSRegularExpression
|
||||
|
||||
|
||||
init(target:String, pattern:String, options:NSRegularExpressionOptions = nil) {
|
||||
self.target = target
|
||||
if let regex = swiftRegexCache[pattern] {
|
||||
@ -36,16 +36,16 @@ public class SwiftRegex: NSObject, BooleanType {
|
||||
}
|
||||
super.init()
|
||||
}
|
||||
|
||||
|
||||
class func failure(message: String) {
|
||||
println("SwiftRegex: "+message)
|
||||
//assert(false,"SwiftRegex: failed")
|
||||
}
|
||||
|
||||
|
||||
final var targetRange: NSRange {
|
||||
return NSRange(location: 0,length: countElements(target.utf16))
|
||||
return NSRange(location: 0,length: count(target.utf16))
|
||||
}
|
||||
|
||||
|
||||
final func substring(range: NSRange) -> String? {
|
||||
if ( range.location != NSNotFound ) {
|
||||
return (target as NSString).substringWithRange(range)
|
||||
@ -53,23 +53,23 @@ public class SwiftRegex: NSObject, BooleanType {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func doesMatch(options: NSMatchingOptions = nil) -> Bool {
|
||||
return range(options: options).location != NSNotFound
|
||||
}
|
||||
|
||||
|
||||
public func range(options: NSMatchingOptions = nil) -> NSRange {
|
||||
return regex.rangeOfFirstMatchInString(target as String, options: nil, range: targetRange)
|
||||
}
|
||||
|
||||
|
||||
public func match(options: NSMatchingOptions = nil) -> String? {
|
||||
return substring(range(options: options))
|
||||
}
|
||||
|
||||
|
||||
public func groups(options: NSMatchingOptions = nil) -> [String]? {
|
||||
return groupsForMatch(regex.firstMatchInString(target as String, options: options, range: targetRange))
|
||||
}
|
||||
|
||||
|
||||
func groupsForMatch(match: NSTextCheckingResult!) -> [String]? {
|
||||
if match != nil {
|
||||
var groups = [String]()
|
||||
@ -85,51 +85,51 @@ public class SwiftRegex: NSObject, BooleanType {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public subscript(groupno: Int) -> String? {
|
||||
get {
|
||||
return groups()?[groupno]
|
||||
}
|
||||
|
||||
|
||||
set(newValue) {
|
||||
if newValue == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
for match in matchResults()!.reverse() {
|
||||
let replacement = regex.replacementStringForResult(match,
|
||||
inString: target as String, offset: 0, template: newValue!)
|
||||
let mut = NSMutableString(string: target)
|
||||
mut.replaceCharactersInRange(match.rangeAtIndex(groupno), withString: replacement)
|
||||
|
||||
|
||||
target = mut as String
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func matchResults(options: NSMatchingOptions = nil) -> [NSTextCheckingResult]? {
|
||||
let matches = regex.matchesInString(target as String, options: options, range: targetRange)
|
||||
as? [NSTextCheckingResult]
|
||||
|
||||
|
||||
if matches != nil {
|
||||
return matches!
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func ranges(options: NSMatchingOptions = nil) -> [NSRange] {
|
||||
return matchResults(options: options)!.map { $0.range }
|
||||
}
|
||||
|
||||
|
||||
public func matches(options: NSMatchingOptions = nil) -> [String] {
|
||||
return matchResults(options: options)!.map( { self.substring($0.range)!})
|
||||
}
|
||||
|
||||
|
||||
public func allGroups(options: NSMatchingOptions = nil) -> [[String]?] {
|
||||
return matchResults(options: options)!.map {self.groupsForMatch($0)}
|
||||
}
|
||||
|
||||
|
||||
public func dictionary(options: NSMatchingOptions = nil) -> Dictionary<String,String> {
|
||||
var out = Dictionary<String,String>()
|
||||
for match in matchResults(options: options)! {
|
||||
@ -137,26 +137,26 @@ public class SwiftRegex: NSObject, BooleanType {
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
|
||||
func substituteMatches(substitution: (NSTextCheckingResult, UnsafeMutablePointer<ObjCBool>) -> String,
|
||||
options:NSMatchingOptions = nil) -> String {
|
||||
let out = NSMutableString()
|
||||
var pos = 0
|
||||
|
||||
|
||||
regex.enumerateMatchesInString(target as String, options: options, range: targetRange ) {
|
||||
(match: NSTextCheckingResult!, flags: NSMatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) in
|
||||
|
||||
|
||||
let matchRange = match.range
|
||||
out.appendString( self.substring(NSRange(location:pos, length:matchRange.location-pos))!)
|
||||
out.appendString( substitution(match, stop) )
|
||||
pos = matchRange.location + matchRange.length
|
||||
}
|
||||
|
||||
|
||||
out.appendString(substring( NSRange(location:pos, length:targetRange.length-pos))!)
|
||||
|
||||
|
||||
return out as String
|
||||
}
|
||||
|
||||
|
||||
public var boolValue: Bool {
|
||||
return doesMatch()
|
||||
}
|
||||
@ -184,11 +184,11 @@ public func ~= (left: SwiftRegex, right: String) -> String {
|
||||
public func ~= (left: SwiftRegex, right: [String]) -> String {
|
||||
var matchNumber = 0
|
||||
return left.substituteMatches({match, stop -> String in
|
||||
|
||||
|
||||
if ++matchNumber == right.count {
|
||||
stop.memory = true
|
||||
}
|
||||
|
||||
|
||||
return left.regex.replacementStringForResult( match,
|
||||
inString: left.target as String, offset: 0, template: right[matchNumber-1] )
|
||||
}, options: nil)
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
import Foundation
|
||||
import CoreFoundation
|
||||
|
||||
public protocol WebSocketDelegate: class {
|
||||
func websocketDidConnect(socket: WebSocket)
|
||||
@ -236,8 +235,8 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
||||
}
|
||||
if self.selfSignedSSL {
|
||||
let settings: Dictionary<NSObject, NSObject> = [kCFStreamSSLValidatesCertificateChain: NSNumber(bool:false), kCFStreamSSLPeerName: kCFNull]
|
||||
inputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings)
|
||||
outputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings)
|
||||
inputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings as String)
|
||||
outputStream!.setProperty(settings, forKey: kCFStreamPropertySSLSettings as String)
|
||||
}
|
||||
isRunLoop = true
|
||||
inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
|
||||
@ -247,18 +246,18 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
||||
let bytes = UnsafePointer<UInt8>(data.bytes)
|
||||
outputStream!.write(bytes, maxLength: data.length)
|
||||
while(isRunLoop) {
|
||||
NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture() as NSDate)
|
||||
NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture() as! NSDate)
|
||||
}
|
||||
}
|
||||
//delegate for the stream methods. Processes incoming bytes
|
||||
func stream(aStream: NSStream!, handleEvent eventCode: NSStreamEvent) {
|
||||
public func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
|
||||
|
||||
if eventCode == .HasBytesAvailable {
|
||||
if(aStream == inputStream) {
|
||||
processInputStream()
|
||||
}
|
||||
} else if eventCode == .ErrorOccurred {
|
||||
disconnectStream(aStream!.streamError)
|
||||
disconnectStream(aStream.streamError)
|
||||
} else if eventCode == .EndEncountered {
|
||||
disconnectStream(nil)
|
||||
}
|
||||
@ -333,7 +332,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
||||
}
|
||||
///Finds the HTTP Packet in the TCP stream, by looking for the CRLF.
|
||||
private func processHTTP(buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Bool {
|
||||
let CRLFBytes = [UInt8("\r"), UInt8("\n"), UInt8("\r"), UInt8("\n")]
|
||||
let CRLFBytes = [UInt8(ascii: "\r"), UInt8(ascii: "\n"), UInt8(ascii: "\r"), UInt8(ascii: "\n")]
|
||||
var k = 0
|
||||
var totalSize = 0
|
||||
for var i = 0; i < bufferLen; i++ {
|
||||
@ -376,7 +375,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
||||
}
|
||||
let cfHeaders = CFHTTPMessageCopyAllHeaderFields(response.takeUnretainedValue())
|
||||
let headers: NSDictionary = cfHeaders.takeUnretainedValue()
|
||||
let acceptKey = headers[headerWSAcceptName] as NSString
|
||||
let acceptKey = headers[headerWSAcceptName] as! NSString
|
||||
if acceptKey.length > 0 {
|
||||
return true
|
||||
}
|
||||
@ -500,7 +499,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
||||
data = NSData(bytes: UnsafePointer<UInt8>((buffer+offset)), length: Int(len))
|
||||
}
|
||||
if receivedOpcode == OpCode.Pong.rawValue {
|
||||
let step = Int(offset+len)
|
||||
let step = offset + Int(len)
|
||||
let extra = bufferLen-step
|
||||
if extra > 0 {
|
||||
processRawMessage((buffer+step), bufferLen: extra)
|
||||
@ -565,7 +564,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
||||
processResponse(response!)
|
||||
}
|
||||
|
||||
let step = Int(offset+len)
|
||||
let step = offset + Int(len)
|
||||
let extra = bufferLen-step
|
||||
if(extra > 0) {
|
||||
processExtra((buffer+step), bufferLen: extra)
|
||||
@ -597,9 +596,9 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
||||
}
|
||||
dispatch_async(queue,{
|
||||
if let textBlock = self.receivedTextBlock{
|
||||
textBlock(str!)
|
||||
textBlock(str! as String)
|
||||
}
|
||||
self.delegate?.websocketDidReceiveMessage(self, text: str!)
|
||||
self.delegate?.websocketDidReceiveMessage(self, text: str! as String)
|
||||
})
|
||||
} else if response.code == .BinaryFrame {
|
||||
let data = response.buffer! //local copy so it is perverse for writing
|
||||
@ -673,7 +672,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
||||
}
|
||||
buffer[1] |= self.MaskMask
|
||||
var maskKey = UnsafeMutablePointer<UInt8>(buffer + offset)
|
||||
SecRandomCopyBytes(kSecRandomDefault, UInt(sizeof(UInt32)), maskKey)
|
||||
SecRandomCopyBytes(kSecRandomDefault, Int(sizeof(UInt32)), maskKey)
|
||||
offset += sizeof(UInt32)
|
||||
|
||||
for (var i = 0; i < dataLength; i++) {
|
||||
@ -711,4 +710,4 @@ public class WebSocket : NSObject, NSStreamDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user