Skip to content

Commit e450032

Browse files
committed
revert to unbroken websocket version
1 parent 4d07d29 commit e450032

File tree

3 files changed

+70
-78
lines changed

3 files changed

+70
-78
lines changed

Source/SocketEngine.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
115115
deinit {
116116
DefaultSocketLogger.Logger.log("Engine is being deinit", type: logType)
117117
closed = true
118+
ws?.disconnect()
118119
stopPolling()
119120
}
120121

Source/SocketEngineSpec.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ import Foundation
6161

6262
extension SocketEngineSpec {
6363
func createBinaryDataForSend(data: NSData) -> Either<NSData, String> {
64-
if websocket {
64+
if websocket {
6565
var byteArray = [UInt8](count: 1, repeatedValue: 0x4)
6666
let mutData = NSMutableData(bytes: &byteArray, length: 1)
6767

Source/WebSocket.swift

Lines changed: 68 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,13 @@ public class WebSocket : NSObject, NSStreamDelegate {
111111
public var selfSignedSSL = false
112112
private var security: SSLSecurity?
113113
public var enabledSSLCipherSuites: [SSLCipherSuite]?
114-
public var origin: String?
115114
public var isConnected :Bool {
116115
return connected
117116
}
118-
public var currentURL: NSURL {return url}
119117
private var url: NSURL
120118
private var inputStream: NSInputStream?
121119
private var outputStream: NSOutputStream?
120+
private var isRunLoop = false
122121
private var connected = false
123122
private var isCreated = false
124123
private var writeQueue = NSOperationQueue()
@@ -127,24 +126,26 @@ public class WebSocket : NSObject, NSStreamDelegate {
127126
private var fragBuffer: NSData?
128127
private var certValidated = false
129128
private var didDisconnect = false
130-
//the shared processing queue used for all websocket
131-
private static let sharedWorkQueue = dispatch_queue_create("com.vluxe.starscream.websocket", DISPATCH_QUEUE_SERIAL)
132129

133130
//used for setting protocols.
134131
public init(url: NSURL, protocols: [String]? = nil) {
135132
self.url = url
136-
self.origin = url.absoluteString
137133
writeQueue.maxConcurrentOperationCount = 1
138134
optionalProtocols = protocols
139135
}
140136

141137
///Connect to the websocket server on a background thread
142138
public func connect() {
143139
guard !isCreated else { return }
144-
didDisconnect = false
145-
isCreated = true
146-
createHTTPRequest()
147-
isCreated = false
140+
141+
dispatch_async(queue) { [weak self] in
142+
self?.didDisconnect = false
143+
}
144+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)) { [weak self] in
145+
self?.isCreated = true
146+
self?.createHTTPRequest()
147+
self?.isCreated = false
148+
}
148149
}
149150

150151
/**
@@ -174,22 +175,20 @@ public class WebSocket : NSObject, NSStreamDelegate {
174175

175176
///write a string to the websocket. This sends it as a text frame.
176177
public func writeString(str: String) {
177-
guard isConnected else { return }
178178
dequeueWrite(str.dataUsingEncoding(NSUTF8StringEncoding)!, code: .TextFrame)
179179
}
180180

181181
///write binary data to the websocket. This sends it as a binary frame.
182182
public func writeData(data: NSData) {
183-
guard isConnected else { return }
184183
dequeueWrite(data, code: .BinaryFrame)
185184
}
186185

187186
//write a ping to the websocket. This sends it as a control frame.
188187
//yodel a sound to the planet. This sends it as an astroid. http://youtu.be/Eu5ZJELRiJ8?t=42s
189188
public func writePing(data: NSData) {
190-
guard isConnected else { return }
191189
dequeueWrite(data, code: .Ping)
192190
}
191+
//private methods below!
193192

194193
//private method that starts the connection
195194
private func createHTTPRequest() {
@@ -212,9 +211,7 @@ public class WebSocket : NSObject, NSStreamDelegate {
212211
}
213212
addHeader(urlRequest, key: headerWSVersionName, val: headerWSVersionValue)
214213
addHeader(urlRequest, key: headerWSKeyName, val: generateWebSocketKey())
215-
if let origin = origin {
216-
addHeader(urlRequest, key: headerOriginName, val: origin)
217-
}
214+
addHeader(urlRequest, key: headerOriginName, val: url.absoluteString)
218215
addHeader(urlRequest, key: headerWSHostName, val: "\(url.host!):\(port!)")
219216
for (key,value) in headers {
220217
addHeader(urlRequest, key: key, val: value)
@@ -224,12 +221,10 @@ public class WebSocket : NSObject, NSStreamDelegate {
224221
initStreamsWithData(serializedRequest, Int(port!))
225222
}
226223
}
227-
228224
//Add a header to the CFHTTPMessage by using the NSString bridges to CFString
229225
private func addHeader(urlRequest: CFHTTPMessage, key: NSString, val: NSString) {
230226
CFHTTPMessageSetHeaderFieldValue(urlRequest, key, val)
231227
}
232-
233228
//generate a websocket key as needed in rfc
234229
private func generateWebSocketKey() -> String {
235230
var key = ""
@@ -242,7 +237,6 @@ public class WebSocket : NSObject, NSStreamDelegate {
242237
let baseKey = data?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
243238
return baseKey!
244239
}
245-
246240
//Start the stream connection and write the data to the output stream
247241
private func initStreamsWithData(data: NSData, _ port: Int) {
248242
//higher level API we will cut over to at some point
@@ -289,16 +283,15 @@ public class WebSocket : NSObject, NSStreamDelegate {
289283
}
290284
}
291285
}
292-
CFReadStreamSetDispatchQueue(inStream, WebSocket.sharedWorkQueue)
293-
CFWriteStreamSetDispatchQueue(outStream, WebSocket.sharedWorkQueue)
286+
isRunLoop = true
287+
inStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
288+
outStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
294289
inStream.open()
295290
outStream.open()
296291
let bytes = UnsafePointer<UInt8>(data.bytes)
297-
writeQueue.addOperationWithBlock {
298-
while !outStream.hasSpaceAvailable {
299-
usleep(100) //wait until the socket is ready
300-
}
301-
outStream.write(bytes, maxLength: data.length)
292+
outStream.write(bytes, maxLength: data.length)
293+
while(isRunLoop) {
294+
NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture() as NSDate)
302295
}
303296
}
304297
//delegate for the stream methods. Processes incoming bytes
@@ -331,16 +324,18 @@ public class WebSocket : NSObject, NSStreamDelegate {
331324
private func disconnectStream(error: NSError?) {
332325
writeQueue.waitUntilAllOperationsAreFinished()
333326
if let stream = inputStream {
334-
CFReadStreamSetDispatchQueue(stream, nil)
327+
stream.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
335328
stream.close()
336329
}
337330
if let stream = outputStream {
338-
CFWriteStreamSetDispatchQueue(stream, nil)
331+
stream.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
339332
stream.close()
340333
}
341334
outputStream = nil
335+
isRunLoop = false
342336
certValidated = false
343337
doDisconnect(error)
338+
connected = false
344339
}
345340

346341
///handles the incoming bytes and sending them to the proper processing method
@@ -350,13 +345,24 @@ public class WebSocket : NSObject, NSStreamDelegate {
350345
let length = inputStream!.read(buffer, maxLength: BUFFER_MAX)
351346

352347
guard length > 0 else { return }
353-
var process = false
354-
if inputQueue.count == 0 {
355-
process = true
356-
}
357-
inputQueue.append(NSData(bytes: buffer, length: length))
358-
if process {
359-
dequeueInput()
348+
349+
if !connected {
350+
connected = processHTTP(buffer, bufferLen: length)
351+
if !connected {
352+
let response = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, false).takeRetainedValue()
353+
CFHTTPMessageAppendBytes(response, buffer, length)
354+
let code = CFHTTPMessageGetResponseStatusCode(response)
355+
doDisconnect(errorWithDetail("Invalid HTTP upgrade", code: UInt16(code)))
356+
}
357+
} else {
358+
var process = false
359+
if inputQueue.count == 0 {
360+
process = true
361+
}
362+
inputQueue.append(NSData(bytes: buffer, length: length))
363+
if process {
364+
dequeueInput()
365+
}
360366
}
361367
}
362368
///dequeue the incoming input so it is processed in order
@@ -372,36 +378,13 @@ public class WebSocket : NSObject, NSStreamDelegate {
372378
self.fragBuffer = nil
373379
}
374380
let buffer = UnsafePointer<UInt8>(work.bytes)
375-
let length = work.length
376-
if !connected {
377-
processTCPHandshake(buffer, bufferLen: length)
378-
} else {
379-
processRawMessage(buffer, bufferLen: length)
380-
}
381+
processRawMessage(buffer, bufferLen: work.length)
381382
inputQueue = inputQueue.filter{$0 != data}
382383
dequeueInput()
383384
}
384385

385-
//handle checking the inital connection status
386-
private func processTCPHandshake(buffer: UnsafePointer<UInt8>, bufferLen: Int) {
387-
let code = processHTTP(buffer, bufferLen: bufferLen)
388-
switch code {
389-
case 0:
390-
connected = true
391-
dispatch_async(queue) { [weak self] in
392-
guard let s = self else { return }
393-
s.onConnect?()
394-
s.delegate?.websocketDidConnect(s)
395-
}
396-
case -1:
397-
fragBuffer = NSData(bytes: buffer, length: bufferLen)
398-
break //do nothing, we are going to collect more data
399-
default:
400-
doDisconnect(errorWithDetail("Invalid HTTP upgrade", code: UInt16(code)))
401-
}
402-
}
403386
///Finds the HTTP Packet in the TCP stream, by looking for the CRLF.
404-
private func processHTTP(buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Int {
387+
private func processHTTP(buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Bool {
405388
let CRLFBytes = [UInt8(ascii: "\r"), UInt8(ascii: "\n"), UInt8(ascii: "\r"), UInt8(ascii: "\n")]
406389
var k = 0
407390
var totalSize = 0
@@ -417,37 +400,39 @@ public class WebSocket : NSObject, NSStreamDelegate {
417400
}
418401
}
419402
if totalSize > 0 {
420-
let code = validateResponse(buffer, bufferLen: totalSize)
421-
if code != 0 {
422-
return code
423-
}
424-
totalSize += 1 //skip the last \n
425-
let restSize = bufferLen - totalSize
426-
if restSize > 0 {
427-
processRawMessage((buffer+totalSize),bufferLen: restSize)
403+
if validateResponse(buffer, bufferLen: totalSize) {
404+
dispatch_async(queue) { [weak self] in
405+
guard let s = self else { return }
406+
s.onConnect?()
407+
s.delegate?.websocketDidConnect(s)
408+
}
409+
totalSize += 1 //skip the last \n
410+
let restSize = bufferLen - totalSize
411+
if restSize > 0 {
412+
processRawMessage((buffer+totalSize),bufferLen: restSize)
413+
}
414+
return true
428415
}
429-
return 0 //success
430416
}
431-
return -1 //was unable to find the full TCP header
417+
return false
432418
}
433419

434420
///validates the HTTP is a 101 as per the RFC spec
435-
private func validateResponse(buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Int {
421+
private func validateResponse(buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Bool {
436422
let response = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, false).takeRetainedValue()
437423
CFHTTPMessageAppendBytes(response, buffer, bufferLen)
438-
let code = CFHTTPMessageGetResponseStatusCode(response)
439-
if code != 101 {
440-
return code
424+
if CFHTTPMessageGetResponseStatusCode(response) != 101 {
425+
return false
441426
}
442427
if let cfHeaders = CFHTTPMessageCopyAllHeaderFields(response) {
443428
let headers = cfHeaders.takeRetainedValue() as NSDictionary
444429
if let acceptKey = headers[headerWSAcceptName] as? NSString {
445430
if acceptKey.length > 0 {
446-
return 0
431+
return true
447432
}
448433
}
449434
}
450-
return -1
435+
return false
451436
}
452437

453438
///read a 16 bit big endian value from a buffer
@@ -703,6 +688,8 @@ public class WebSocket : NSObject, NSStreamDelegate {
703688
}
704689
///used to write things to the stream
705690
private func dequeueWrite(data: NSData, code: OpCode) {
691+
guard isConnected else { return }
692+
706693
writeQueue.addOperationWithBlock { [weak self] in
707694
//stream isn't ready, let's wait
708695
guard let s = self else { return }
@@ -734,6 +721,9 @@ public class WebSocket : NSObject, NSStreamDelegate {
734721
}
735722
var total = 0
736723
while true {
724+
if !s.isConnected {
725+
break
726+
}
737727
guard let outStream = s.outputStream else { break }
738728
let writeBuffer = UnsafePointer<UInt8>(frame!.bytes+total)
739729
let len = outStream.write(writeBuffer, maxLength: offset-total)
@@ -761,16 +751,17 @@ public class WebSocket : NSObject, NSStreamDelegate {
761751
///used to preform the disconnect delegate
762752
private func doDisconnect(error: NSError?) {
763753
guard !didDisconnect else { return }
764-
didDisconnect = true
765-
connected = false
754+
766755
dispatch_async(queue) { [weak self] in
767756
guard let s = self else { return }
757+
s.didDisconnect = true
768758
s.onDisconnect?(error)
769759
s.delegate?.websocketDidDisconnect(s, error: error)
770760
}
771761
}
772762

773763
}
764+
774765
private class SSLCert {
775766
var certData: NSData?
776767
var key: SecKeyRef?

0 commit comments

Comments
 (0)