From c757ede90e470909e6533b6d5dc22b7b2795dab3 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 28 Sep 2015 12:41:47 -0400 Subject: [PATCH 1/9] don't request if closed --- SocketIOClientSwift/SocketEngine.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SocketIOClientSwift/SocketEngine.swift b/SocketIOClientSwift/SocketEngine.swift index a152cf3..dc3234c 100644 --- a/SocketIOClientSwift/SocketEngine.swift +++ b/SocketIOClientSwift/SocketEngine.swift @@ -229,7 +229,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } private func doPoll() { - if websocket || waitingForPoll || !connected { + if websocket || waitingForPoll || !connected || closed { return } @@ -251,7 +251,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } private func doRequest(req: NSMutableURLRequest) { - if !polling { + if !polling || closed { return } From 166d59341cbc22b3d6487ca0aaae2f5e176736e1 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 28 Sep 2015 13:44:16 -0400 Subject: [PATCH 2/9] bump websocket --- SocketIOClientSwift/WebSocket.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SocketIOClientSwift/WebSocket.swift b/SocketIOClientSwift/WebSocket.swift index 7e4fc7d..21245cb 100644 --- a/SocketIOClientSwift/WebSocket.swift +++ b/SocketIOClientSwift/WebSocket.swift @@ -319,9 +319,12 @@ public class WebSocket : NSObject, NSStreamDelegate { let length = inputStream!.read(buffer, maxLength: BUFFER_MAX) if length > 0 { if !connected { - let status = processHTTP(buffer, bufferLen: length) - if !status { - doDisconnect(errorWithDetail("Invalid HTTP upgrade", code: 1)) + connected = processHTTP(buffer, bufferLen: length) + if !connected { + let response = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, false).takeRetainedValue() + CFHTTPMessageAppendBytes(response, buffer, length) + let code = CFHTTPMessageGetResponseStatusCode(response) + doDisconnect(errorWithDetail("Invalid HTTP upgrade", code: UInt16(code))) } } else { var process = false @@ -372,7 +375,6 @@ public class WebSocket : NSObject, NSStreamDelegate { if validateResponse(buffer, bufferLen: totalSize) { dispatch_async(queue,{ [weak self] in guard let s = self else { return } - s.connected = true if let connectBlock = s.onConnect { connectBlock() } From 9241bf869f1888134339a86bc3898210f04a3331 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 28 Sep 2015 20:52:03 -0400 Subject: [PATCH 3/9] fix another crash case --- SocketIOClientSwift/SocketEngine.swift | 1 + SocketIOClientSwift/SocketIOClient.swift | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/SocketIOClientSwift/SocketEngine.swift b/SocketIOClientSwift/SocketEngine.swift index dc3234c..0d964d4 100644 --- a/SocketIOClientSwift/SocketEngine.swift +++ b/SocketIOClientSwift/SocketEngine.swift @@ -99,6 +99,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { deinit { Logger.log("Engine is being deinit", type: logType) + stopPolling() } private func checkIfMessageIsBase64Binary(var message: String) { diff --git a/SocketIOClientSwift/SocketIOClient.swift b/SocketIOClientSwift/SocketIOClient.swift index 3c716b9..dbbec13 100644 --- a/SocketIOClientSwift/SocketIOClient.swift +++ b/SocketIOClientSwift/SocketIOClient.swift @@ -111,7 +111,6 @@ public final class SocketIOClient: NSObject, SocketEngineClient { deinit { Logger.log("Client is being deinit", type: logType) - engine?.close(fast: true) } private func addEngine() -> SocketEngine { From 798d8a62aebdf39434b4261b81e1ac6315022f99 Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 29 Sep 2015 08:52:46 -0400 Subject: [PATCH 4/9] bump version --- README.md | 4 ++-- Socket.IO-Client-Swift.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ddd28c2..fc4ebdf 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Carthage ----------------- Add this line to your `Cartfile`: ``` -github "socketio/socket.io-client-swift" ~> 3.1.2 # Or latest version +github "socketio/socket.io-client-swift" ~> 3.1.3 # Or latest version ``` Run `carthage update --platform ios,macosx`. @@ -83,7 +83,7 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' use_frameworks! -pod 'Socket.IO-Client-Swift', '~> 3.1.2' # Or latest version +pod 'Socket.IO-Client-Swift', '~> 3.1.3' # Or latest version ``` Install pods: diff --git a/Socket.IO-Client-Swift.podspec b/Socket.IO-Client-Swift.podspec index 168d637..bd58a5a 100644 --- a/Socket.IO-Client-Swift.podspec +++ b/Socket.IO-Client-Swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Socket.IO-Client-Swift" - s.version = "3.1.2" + s.version = "3.1.3" s.summary = "Socket.IO-client for iOS and OS X" s.description = <<-DESC Socket.IO-client for iOS and OS X. @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.author = { "Erik" => "nuclear.ace@gmail.com" } s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.10' - s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v3.1.2' } + s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v3.1.3' } s.source_files = "SocketIOClientSwift/**/*.swift" s.requires_arc = true # s.dependency 'Starscream', '~> 0.9' # currently this repo includes Starscream swift files From 718dc2708904045eb506f306349d95d7f5b27573 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 30 Sep 2015 09:26:23 -0400 Subject: [PATCH 5/9] tweaks to polling --- SocketIOClientSwift/SocketEngine.swift | 49 +++++++++++++++----------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/SocketIOClientSwift/SocketEngine.swift b/SocketIOClientSwift/SocketEngine.swift index 0d964d4..ba68de9 100644 --- a/SocketIOClientSwift/SocketEngine.swift +++ b/SocketIOClientSwift/SocketEngine.swift @@ -41,6 +41,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { private var fastUpgrade = false private var forcePolling = false private var forceWebsockets = false + private var invalidated = false private var pingInterval: Double? private var pingTimer: NSTimer? private var pingTimeout = 0.0 { @@ -99,6 +100,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { deinit { Logger.log("Engine is being deinit", type: logType) + closed = true stopPolling() } @@ -248,19 +250,23 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } } - doRequest(req) + doLongPoll(req) + } + + private func doRequest(req: NSMutableURLRequest, + withCallback callback: (NSData?, NSURLResponse?, NSError?) -> Void) { + if !polling || closed || invalidated { + return + } + + Logger.log("Doing polling request", type: logType) + + req.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData + session.dataTaskWithRequest(req, completionHandler: callback).resume() } - private func doRequest(req: NSMutableURLRequest) { - if !polling || closed { - return - } - - req.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData - - Logger.log("Doing polling request", type: logType) - - session.dataTaskWithRequest(req) {[weak self] data, res, err in + private func doLongPoll(req: NSMutableURLRequest) { + doRequest(req) {[weak self] data, res, err in if let this = self { if err != nil || data == nil { if this.polling { @@ -270,23 +276,24 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } return } - + Logger.log("Got polling response", type: this.logType) - + if let str = NSString(data: data!, encoding: NSUTF8StringEncoding) as? String { dispatch_async(this.parseQueue) {[weak this] in this?.parsePollingMessage(str) } } - + this.waitingForPoll = false - + if this.fastUpgrade { this.doFastUpgrade() } else if !this.closed && this.polling { this.doPoll() } - }}.resume() + } + } } private func flushProbeWait() { @@ -345,13 +352,13 @@ public final class SocketEngine: NSObject, WebSocketDelegate { Logger.log("POSTing: %@", type: logType, args: postStr) - session.dataTaskWithRequest(req) {[weak self] data, res, err in + doRequest(req) {[weak self] data, res, err in if let this = self { if err != nil && this.polling { this.handlePollingFailed(err?.localizedDescription ?? "Error") return } else if err != nil { - NSLog(err?.localizedDescription ?? "Error") + Logger.error(err?.localizedDescription ?? "Error", type: this.logType) return } @@ -363,7 +370,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { this?.doPoll() } } - }}.resume() + } + } } // We had packets waiting for send when we upgraded @@ -488,7 +496,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } } - doRequest(reqPolling) + doLongPoll(reqPolling) } private func parsePollingMessage(str: String) { @@ -627,6 +635,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } func stopPolling() { + invalidated = true session.finishTasksAndInvalidate() } From ccc3745bb882c255f2806080315d30cc4171a53d Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 30 Sep 2015 18:38:39 -0400 Subject: [PATCH 6/9] fix for socketio/socket.io-client-swift#196 --- SocketIO-iOSTests/SocketParserTest.swift | 14 +++++++++++++- SocketIOClientSwift/SocketEngine.swift | 6 +++--- SocketIOClientSwift/SocketIOClient.swift | 2 +- SocketIOClientSwift/SocketParser.swift | 16 +++++++++++++--- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/SocketIO-iOSTests/SocketParserTest.swift b/SocketIO-iOSTests/SocketParserTest.swift index 0eff01d..0e42f6f 100644 --- a/SocketIO-iOSTests/SocketParserTest.swift +++ b/SocketIO-iOSTests/SocketParserTest.swift @@ -19,7 +19,9 @@ class SocketParserTest: XCTestCase { "61-/swift,19[[1,2],{\"test\":\"bob\"},25,\"polo\",{\"_placeholder\":true,\"num\":0}]": ("/swift", [ [1, 2], ["test": "bob"], 25, "polo", "~~0"], [], 19), "4/swift,": ("/swift", [], [], -1), "0/swift": ("/swift", [], [], -1), - "1/swift": ("/swift", [], [], -1)] + "1/swift": ("/swift", [], [], -1), + "4\"ERROR\"": ("/", ["ERROR"], [], -1), + "41": ("/", [1], [], -1)] func testDisconnect() { let message = "1" @@ -66,6 +68,16 @@ class SocketParserTest: XCTestCase { validateParseResult(message) } + func testErrorTypeString() { + let message = "4\"ERROR\"" + validateParseResult(message) + } + + func testErrorTypeInt() { + let message = "41" + validateParseResult(message) + } + func testInvalidInput() { let message = "8" switch SocketParser.parseString(message) { diff --git a/SocketIOClientSwift/SocketEngine.swift b/SocketIOClientSwift/SocketEngine.swift index ba68de9..6d3eae9 100644 --- a/SocketIOClientSwift/SocketEngine.swift +++ b/SocketIOClientSwift/SocketEngine.swift @@ -29,10 +29,10 @@ public final class SocketEngine: NSObject, WebSocketDelegate { private typealias ProbeWaitQueue = [Probe] private let allowedCharacterSet = NSCharacterSet(charactersInString: "!*'();:@&=+$,/?%#[]\" {}").invertedSet - private let emitQueue = dispatch_queue_create("engineEmitQueue", DISPATCH_QUEUE_SERIAL) - private let handleQueue = dispatch_queue_create("engineHandleQueue", DISPATCH_QUEUE_SERIAL) + private let emitQueue = dispatch_queue_create("com.socketio.engineEmitQueue", DISPATCH_QUEUE_SERIAL) + private let handleQueue = dispatch_queue_create("com.socketio.engineHandleQueue", DISPATCH_QUEUE_SERIAL) private let logType = "SocketEngine" - private let parseQueue = dispatch_queue_create("engineParseQueue", DISPATCH_QUEUE_SERIAL) + private let parseQueue = dispatch_queue_create("com.socketio.engineParseQueue", DISPATCH_QUEUE_SERIAL) private let session: NSURLSession! private let workQueue = NSOperationQueue() diff --git a/SocketIOClientSwift/SocketIOClient.swift b/SocketIOClientSwift/SocketIOClient.swift index dbbec13..ef1de9f 100644 --- a/SocketIOClientSwift/SocketIOClient.swift +++ b/SocketIOClientSwift/SocketIOClient.swift @@ -25,7 +25,7 @@ import Foundation public final class SocketIOClient: NSObject, SocketEngineClient { - private let emitQueue = dispatch_queue_create("emitQueue", DISPATCH_QUEUE_SERIAL) + private let emitQueue = dispatch_queue_create("com.socketio.emitQueue", DISPATCH_QUEUE_SERIAL) private let handleQueue: dispatch_queue_t! public let socketURL: String diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index 64d359d..b25d8d0 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -54,7 +54,7 @@ class SocketParser { case .Disconnect: socket.didDisconnect("Got Disconnect") case .Error: - socket.didError("Error: \(pack.data)") + socket.didError(pack.data) default: Logger.log("Got invalid packet: %@", type: "SocketParser", args: pack.description) } @@ -93,7 +93,11 @@ class SocketParser { var idString = "" - while parser.hasNext { + if type == .Error { + parser.advanceIndexBy(-1) + } + + while parser.hasNext && type != .Error { if let int = Int(parser.read(1)) { idString += String(int) } else { @@ -107,7 +111,13 @@ class SocketParser { switch parseData(noPlaceholders) { case .Left(let err): - return .Left(err) + // If first you don't succeed, try again + if case let .Right(data) = parseData("\([noPlaceholders as AnyObject])") { + return .Right(SocketPacket(type: type, data: data, id: Int(idString) ?? -1, + nsp: namespace ?? "/", placeholders: placeholders)) + } else { + return .Left(err) + } case .Right(let data): return .Right(SocketPacket(type: type, data: data, id: Int(idString) ?? -1, nsp: namespace ?? "/", placeholders: placeholders)) From 4dd882b8ad87e284996ab61584c0d5d586802256 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 30 Sep 2015 21:08:23 -0400 Subject: [PATCH 7/9] bump version --- README.md | 4 ++-- Socket.IO-Client-Swift.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fc4ebdf..7c6f2ba 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Carthage ----------------- Add this line to your `Cartfile`: ``` -github "socketio/socket.io-client-swift" ~> 3.1.3 # Or latest version +github "socketio/socket.io-client-swift" ~> 3.1.4 # Or latest version ``` Run `carthage update --platform ios,macosx`. @@ -83,7 +83,7 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' use_frameworks! -pod 'Socket.IO-Client-Swift', '~> 3.1.3' # Or latest version +pod 'Socket.IO-Client-Swift', '~> 3.1.4' # Or latest version ``` Install pods: diff --git a/Socket.IO-Client-Swift.podspec b/Socket.IO-Client-Swift.podspec index bd58a5a..f09d17b 100644 --- a/Socket.IO-Client-Swift.podspec +++ b/Socket.IO-Client-Swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Socket.IO-Client-Swift" - s.version = "3.1.3" + s.version = "3.1.4" s.summary = "Socket.IO-client for iOS and OS X" s.description = <<-DESC Socket.IO-client for iOS and OS X. @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.author = { "Erik" => "nuclear.ace@gmail.com" } s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.10' - s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v3.1.3' } + s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v3.1.4' } s.source_files = "SocketIOClientSwift/**/*.swift" s.requires_arc = true # s.dependency 'Starscream', '~> 0.9' # currently this repo includes Starscream swift files From 877db516c242625c397ba8c8b5a9b6afe88d1ff0 Mon Sep 17 00:00:00 2001 From: Erik Date: Thu, 1 Oct 2015 09:53:20 -0400 Subject: [PATCH 8/9] fix socketio/socket.io-client-swift#197 --- SocketIOClientSwift/SocketIOClient.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SocketIOClientSwift/SocketIOClient.swift b/SocketIOClientSwift/SocketIOClient.swift index ef1de9f..f787864 100644 --- a/SocketIOClientSwift/SocketIOClient.swift +++ b/SocketIOClientSwift/SocketIOClient.swift @@ -171,10 +171,10 @@ public final class SocketIOClient: NSObject, SocketEngineClient { let time = dispatch_time(DISPATCH_TIME_NOW, Int64(timeoutAfter) * Int64(NSEC_PER_SEC)) - dispatch_after(time, dispatch_get_main_queue()) { - if self.status != .Connected { - self.status = .Closed - self.engine?.close(fast: true) + dispatch_after(time, dispatch_get_main_queue()) {[weak self] in + if self != nil && self?.status != .Connected { + self?.status = .Closed + self?.engine?.close(fast: true) handler?() } From de20099c07f580cae9114fdd47961f77c8f4b303 Mon Sep 17 00:00:00 2001 From: Erik Date: Thu, 1 Oct 2015 12:59:27 -0400 Subject: [PATCH 9/9] style --- SocketIOClientSwift/SocketEngine.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SocketIOClientSwift/SocketEngine.swift b/SocketIOClientSwift/SocketEngine.swift index 6d3eae9..ec9ec07 100644 --- a/SocketIOClientSwift/SocketEngine.swift +++ b/SocketIOClientSwift/SocketEngine.swift @@ -261,7 +261,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { Logger.log("Doing polling request", type: logType) - req.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData + req.cachePolicy = .ReloadIgnoringLocalAndRemoteCacheData session.dataTaskWithRequest(req, completionHandler: callback).resume() }