Skip to content

Commit 0f4718b

Browse files
authored
Merge pull request #121 from pusher/fix-channel-name-auth-escpaing
Assortment of fixes
2 parents 180ddc4 + 45bebf7 commit 0f4718b

File tree

6 files changed

+231
-145
lines changed

6 files changed

+231
-145
lines changed

Source/PusherConnection.swift

Lines changed: 70 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,24 @@ open class PusherConnection: NSObject {
3838

3939
open lazy var reachability: Reachability? = {
4040
let reachability = Reachability.init()
41-
reachability?.whenReachable = { [unowned self] reachability in
42-
self.delegate?.debugLog?(message: "[PUSHER DEBUG] Network reachable")
43-
if self.connectionState == .disconnected || self.connectionState == .reconnectingWhenNetworkBecomesReachable {
44-
self.attemptReconnect()
41+
reachability?.whenReachable = { [weak self] reachability in
42+
guard self != nil else {
43+
print("Your Pusher instance has probably become deallocated. See https://github.com/pusher/pusher-websocket-swift/issues/109 for more information")
44+
return
45+
}
46+
47+
self!.delegate?.debugLog?(message: "[PUSHER DEBUG] Network reachable")
48+
if self!.connectionState == .disconnected || self!.connectionState == .reconnectingWhenNetworkBecomesReachable {
49+
self!.attemptReconnect()
4550
}
4651
}
47-
reachability?.whenUnreachable = { [unowned self] reachability in
48-
self.delegate?.debugLog?(message: "[PUSHER DEBUG] Network unreachable")
52+
reachability?.whenUnreachable = { [weak self] reachability in
53+
guard self != nil else {
54+
print("Your Pusher instance has probably become deallocated. See https://github.com/pusher/pusher-websocket-swift/issues/109 for more information")
55+
return
56+
}
57+
58+
self!.delegate?.debugLog?(message: "[PUSHER DEBUG] Network unreachable")
4959
}
5060
return reachability
5161
}()
@@ -488,7 +498,7 @@ open class PusherConnection: NSObject {
488498
} else if let eData = jsonObject["data"] as? [String: AnyObject] {
489499
globalChannel.handleErrorEvent(name: eventName, data: eData)
490500
}
491-
}
501+
}
492502
}
493503

494504
/**
@@ -506,68 +516,68 @@ open class PusherConnection: NSObject {
506516
subscribeToNormalChannel(channel)
507517
return true
508518
} else {
509-
if let socketID = self.socketId {
510-
switch self.options.authMethod {
511-
case .noMethod:
512-
let errorMessage = "Authentication method required for private / presence channels but none provided."
513-
let error = NSError(domain: "com.pusher.PusherSwift", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey: errorMessage])
519+
guard let socketId = self.socketId else {
520+
print("socketId value not found. You may not be connected.")
521+
return false
522+
}
514523

515-
print(errorMessage)
524+
switch self.options.authMethod {
525+
case .noMethod:
526+
let errorMessage = "Authentication method required for private / presence channels but none provided."
527+
let error = NSError(domain: "com.pusher.PusherSwift", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey: errorMessage])
516528

517-
handleAuthorizationError(forChannel: channel.name, response: nil, data: nil, error: error)
529+
print(errorMessage)
518530

519-
return false
520-
case .endpoint(authEndpoint: let authEndpoint):
521-
let request = requestForAuthValue(from: authEndpoint, socketID: socketID, channel: channel)
522-
sendAuthorisationRequest(request: request, channel: channel, callback: callback)
523-
return true
531+
handleAuthorizationError(forChannel: channel.name, response: nil, data: nil, error: error)
524532

525-
case .authRequestBuilder(authRequestBuilder: let builder):
526-
if let request = builder.requestFor?(socketID: socketID, channel: channel) {
527-
sendAuthorisationRequest(request: request as URLRequest, channel: channel, callback: callback)
533+
return false
534+
case .endpoint(authEndpoint: let authEndpoint):
535+
let request = requestForAuthValue(from: authEndpoint, socketId: socketId, channelName: channel.name)
536+
sendAuthorisationRequest(request: request, channel: channel, callback: callback)
537+
return true
528538

529-
return true
530-
} else if let request = builder.requestFor?(socketID: socketID, channelName: channel.name) {
531-
sendAuthorisationRequest(request: request, channel: channel, callback: callback)
539+
case .authRequestBuilder(authRequestBuilder: let builder):
540+
if let request = builder.requestFor?(socketID: socketId, channel: channel) {
541+
sendAuthorisationRequest(request: request as URLRequest, channel: channel, callback: callback)
532542

533-
return true
534-
} else {
535-
let errorMessage = "Authentication request could not be built"
536-
let error = NSError(domain: "com.pusher.PusherSwift", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey: errorMessage])
543+
return true
544+
} else if let request = builder.requestFor?(socketID: socketId, channelName: channel.name) {
545+
sendAuthorisationRequest(request: request, channel: channel, callback: callback)
537546

538-
handleAuthorizationError(forChannel: channel.name, response: nil, data: nil, error: error)
547+
return true
548+
} else {
549+
let errorMessage = "Authentication request could not be built"
550+
let error = NSError(domain: "com.pusher.PusherSwift", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey: errorMessage])
539551

540-
return false
541-
}
542-
case .inline(secret: let secret):
543-
var msg = ""
544-
var channelData = ""
545-
if channel.type == .presence {
546-
channelData = getUserDataJSON()
547-
msg = "\(self.socketId!):\(channel.name):\(channelData)"
548-
} else {
549-
msg = "\(self.socketId!):\(channel.name)"
550-
}
552+
handleAuthorizationError(forChannel: channel.name, response: nil, data: nil, error: error)
551553

552-
let secretBuff: [UInt8] = Array(secret.utf8)
553-
let msgBuff: [UInt8] = Array(msg.utf8)
554+
return false
555+
}
556+
case .inline(secret: let secret):
557+
var msg = ""
558+
var channelData = ""
559+
if channel.type == .presence {
560+
channelData = getUserDataJSON()
561+
msg = "\(self.socketId!):\(channel.name):\(channelData)"
562+
} else {
563+
msg = "\(self.socketId!):\(channel.name)"
564+
}
554565

555-
if let hmac = try? HMAC(key: secretBuff, variant: .sha256).authenticate(msgBuff) {
556-
let signature = Data(bytes: hmac).toHexString()
557-
let auth = "\(self.key):\(signature)".lowercased()
566+
let secretBuff: [UInt8] = Array(secret.utf8)
567+
let msgBuff: [UInt8] = Array(msg.utf8)
558568

559-
if channel.type == .private {
560-
self.handlePrivateChannelAuth(authValue: auth, channel: channel, callback: callback)
561-
} else {
562-
self.handlePresenceChannelAuth(authValue: auth, channel: channel, channelData: channelData, callback: callback)
563-
}
564-
}
569+
if let hmac = try? HMAC(key: secretBuff, variant: .sha256).authenticate(msgBuff) {
570+
let signature = Data(bytes: hmac).toHexString()
571+
let auth = "\(self.key):\(signature)".lowercased()
565572

566-
return true
573+
if channel.type == .private {
574+
self.handlePrivateChannelAuth(authValue: auth, channel: channel, callback: callback)
575+
} else {
576+
self.handlePresenceChannelAuth(authValue: auth, channel: channel, channelData: channelData, callback: callback)
577+
}
567578
}
568-
} else {
569-
print("socketId value not found. You may not be connected.")
570-
return false
579+
580+
return true
571581
}
572582
}
573583
}
@@ -614,18 +624,18 @@ open class PusherConnection: NSObject {
614624
Creates an authentication request for the given authEndpoint
615625

616626
- parameter endpoint: The authEndpoint to which the request will be made
617-
- parameter socketID: The socketId of the connection's websocket
627+
- parameter socketId: The socketId of the connection's websocket
618628
- parameter channel: The PusherChannel to authenticate subsciption for
619629

620630
- returns: URLRequest object to be used by the function making the auth request
621631
*/
622-
fileprivate func requestForAuthValue(from endpoint: String, socketID: String, channel: PusherChannel) -> URLRequest {
632+
fileprivate func requestForAuthValue(from endpoint: String, socketId: String, channelName: String) -> URLRequest {
623633
let allowedCharacterSet = CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted
624-
let encodedChannelName = channel.name.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet)
634+
let encodedChannelName = channelName.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? channelName
625635

626636
var request = URLRequest(url: URL(string: endpoint)!)
627637
request.httpMethod = "POST"
628-
request.httpBody = "socket_id=\(socketID)&channel_name=\(encodedChannelName!)".data(using: String.Encoding.utf8)
638+
request.httpBody = "socket_id=\(socketId)&channel_name=\(encodedChannelName)".data(using: String.Encoding.utf8)
629639

630640
return request
631641
}

Source/PusherSwift.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ let CLIENT_NAME = "pusher-websocket-swift"
4040
self.key = key
4141
let urlString = constructUrl(key: key, options: options)
4242
let ws = WebSocket(url: URL(string: urlString)!)
43+
ws.callbackQueue = DispatchQueue(label: "com.pusher.starscream.websocket.callback")
4344
connection = PusherConnection(key: key, socket: ws, url: urlString, options: options)
4445
connection.createGlobalChannel()
4546
self.nativePusher = nativePusher

0 commit comments

Comments
 (0)