Skip to content

Commit fe9ee60

Browse files
committed
add option for toggling double encoding utf8
1 parent 6fa5ce9 commit fe9ee60

File tree

8 files changed

+84
-104
lines changed

8 files changed

+84
-104
lines changed

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -147,24 +147,24 @@ All options are a case of SocketIOClientOption. To get the Objective-C Option, c
147147

148148
```swift
149149
case ConnectParams([String: AnyObject]) // Dictionary whose contents will be passed with the connection.
150-
case Reconnects(Bool) // Whether to reconnect on server lose. Default is `true`
151-
case ReconnectAttempts(Int) // How many times to reconnect. Default is `-1` (infinite tries)
152-
case ReconnectWait(Int) // Amount of time to wait between reconnects. Default is `10`
150+
case Cookies([NSHTTPCookie]) // An array of NSHTTPCookies. Passed during the handshake. Default is nil.
151+
case DoubleEncodeUTF8(Bool) // Whether or not to double encode utf8. If using the node based server this should be true. Default is true.
152+
case ExtraHeaders([String: String]) // Adds custom headers to the initial request. Default is nil.
153153
case ForcePolling(Bool) // `true` forces the client to use xhr-polling. Default is `false`
154154
case ForceNew(Bool) // Will a create a new engine for each connect. Useful if you find a bug in the engine related to reconnects
155155
case ForceWebsockets(Bool) // `true` forces the client to use WebSockets. Default is `false`
156-
case Nsp(String) // The namespace to connect to. Must begin with /. Default is `/`
157-
case Cookies([NSHTTPCookie]) // An array of NSHTTPCookies. Passed during the handshake. Default is nil.
156+
case HandleQueue(dispatch_queue_t) // The dispatch queue that handlers are run on. Default is the main queue.
158157
case Log(Bool) // If `true` socket will log debug messages. Default is false.
159158
case Logger(SocketLogger) // Custom logger that conforms to SocketLogger. Will use the default logging otherwise.
160-
case SessionDelegate(NSURLSessionDelegate) // Sets an NSURLSessionDelegate for the underlying engine. Useful if you need to handle self-signed certs. Default is nil.
159+
case Nsp(String) // The namespace to connect to. Must begin with /. Default is `/`
161160
case Path(String) // If the server uses a custom path. ex: `"/swift/"`. Default is `""`
162-
case ExtraHeaders([String: String]) // Adds custom headers to the initial request. Default is nil.
163-
case HandleQueue(dispatch_queue_t) // The dispatch queue that handlers are run on. Default is the main queue.
164-
case VoipEnabled(Bool) // Only use this option if you're using the client with VoIP services. Changes the way the WebSocket is created. Default is false
161+
case Reconnects(Bool) // Whether to reconnect on server lose. Default is `true`
162+
case ReconnectAttempts(Int) // How many times to reconnect. Default is `-1` (infinite tries)
163+
case ReconnectWait(Int) // Amount of time to wait between reconnects. Default is `10`
164+
case SessionDelegate(NSURLSessionDelegate) // Sets an NSURLSessionDelegate for the underlying engine. Useful if you need to handle self-signed certs. Default is nil.
165165
case Secure(Bool) // If the connection should use TLS. Default is false.
166166
case SelfSigned(Bool) // Sets WebSocket.selfSignedSSL (Don't do this, iOS will yell at you)
167-
167+
case VoipEnabled(Bool) // Only use this option if you're using the client with VoIP services. Changes the way the WebSocket is created. Default is false
168168
```
169169
Methods
170170
-------

Socket.IO-Client-Swift.xcodeproj/project.pbxproj

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,6 @@
6060
74171E8F1C10CD240062D398 /* SocketEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E571C10CD240062D398 /* SocketEventHandler.swift */; };
6161
74171E911C10CD240062D398 /* SocketEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E571C10CD240062D398 /* SocketEventHandler.swift */; };
6262
74171E921C10CD240062D398 /* SocketEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E571C10CD240062D398 /* SocketEventHandler.swift */; };
63-
74171E931C10CD240062D398 /* SocketFixUTF8.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E581C10CD240062D398 /* SocketFixUTF8.swift */; };
64-
74171E941C10CD240062D398 /* SocketFixUTF8.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E581C10CD240062D398 /* SocketFixUTF8.swift */; };
65-
74171E951C10CD240062D398 /* SocketFixUTF8.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E581C10CD240062D398 /* SocketFixUTF8.swift */; };
66-
74171E971C10CD240062D398 /* SocketFixUTF8.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E581C10CD240062D398 /* SocketFixUTF8.swift */; };
67-
74171E981C10CD240062D398 /* SocketFixUTF8.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E581C10CD240062D398 /* SocketFixUTF8.swift */; };
6863
74171E991C10CD240062D398 /* SocketIOClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E591C10CD240062D398 /* SocketIOClient.swift */; };
6964
74171E9A1C10CD240062D398 /* SocketIOClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E591C10CD240062D398 /* SocketIOClient.swift */; };
7065
74171E9B1C10CD240062D398 /* SocketIOClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74171E591C10CD240062D398 /* SocketIOClient.swift */; };
@@ -180,7 +175,6 @@
180175
74171E551C10CD240062D398 /* SocketEnginePacketType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketEnginePacketType.swift; path = Source/SocketEnginePacketType.swift; sourceTree = "<group>"; };
181176
74171E561C10CD240062D398 /* SocketEngineSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketEngineSpec.swift; path = Source/SocketEngineSpec.swift; sourceTree = "<group>"; };
182177
74171E571C10CD240062D398 /* SocketEventHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketEventHandler.swift; path = Source/SocketEventHandler.swift; sourceTree = "<group>"; };
183-
74171E581C10CD240062D398 /* SocketFixUTF8.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketFixUTF8.swift; path = Source/SocketFixUTF8.swift; sourceTree = "<group>"; };
184178
74171E591C10CD240062D398 /* SocketIOClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketIOClient.swift; path = Source/SocketIOClient.swift; sourceTree = "<group>"; };
185179
74171E5A1C10CD240062D398 /* SocketIOClientOption.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketIOClientOption.swift; path = Source/SocketIOClientOption.swift; sourceTree = "<group>"; };
186180
74171E5B1C10CD240062D398 /* SocketIOClientStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketIOClientStatus.swift; path = Source/SocketIOClientStatus.swift; sourceTree = "<group>"; };
@@ -361,7 +355,6 @@
361355
74171E561C10CD240062D398 /* SocketEngineSpec.swift */,
362356
740CA11F1C496EEB00CB98F4 /* SocketEngineWebsocket.swift */,
363357
74171E571C10CD240062D398 /* SocketEventHandler.swift */,
364-
74171E581C10CD240062D398 /* SocketFixUTF8.swift */,
365358
74171E591C10CD240062D398 /* SocketIOClient.swift */,
366359
74171E5A1C10CD240062D398 /* SocketIOClientOption.swift */,
367360
74171E5B1C10CD240062D398 /* SocketIOClientStatus.swift */,
@@ -610,7 +603,6 @@
610603
buildActionMask = 2147483647;
611604
files = (
612605
740CA1221C496EF700CB98F4 /* SocketEngineWebsocket.swift in Sources */,
613-
74171E931C10CD240062D398 /* SocketFixUTF8.swift in Sources */,
614606
74171EA51C10CD240062D398 /* SocketIOClientStatus.swift in Sources */,
615607
74171E751C10CD240062D398 /* SocketEngine.swift in Sources */,
616608
74171E691C10CD240062D398 /* SocketAckManager.swift in Sources */,
@@ -647,7 +639,6 @@
647639
74171EC41C10CD240062D398 /* SocketTypes.swift in Sources */,
648640
74171E8E1C10CD240062D398 /* SocketEventHandler.swift in Sources */,
649641
74171E7C1C10CD240062D398 /* SocketEngineClient.swift in Sources */,
650-
74171E941C10CD240062D398 /* SocketFixUTF8.swift in Sources */,
651642
74171E821C10CD240062D398 /* SocketEnginePacketType.swift in Sources */,
652643
74171ECA1C10CD240062D398 /* SwiftRegex.swift in Sources */,
653644
74171EB21C10CD240062D398 /* SocketPacket.swift in Sources */,
@@ -670,7 +661,6 @@
670661
files = (
671662
740CA1211C496EF200CB98F4 /* SocketEngineWebsocket.swift in Sources */,
672663
7471CCEA1C39926300364B59 /* SocketClientSpec.swift in Sources */,
673-
74171E951C10CD240062D398 /* SocketFixUTF8.swift in Sources */,
674664
74171EA71C10CD240062D398 /* SocketIOClientStatus.swift in Sources */,
675665
74171E771C10CD240062D398 /* SocketEngine.swift in Sources */,
676666
7420CB7A1C49629E00956AA4 /* SocketEnginePollable.swift in Sources */,
@@ -713,7 +703,6 @@
713703
files = (
714704
740CA1201C496EEB00CB98F4 /* SocketEngineWebsocket.swift in Sources */,
715705
7471CCEB1C39926C00364B59 /* SocketClientSpec.swift in Sources */,
716-
74171E971C10CD240062D398 /* SocketFixUTF8.swift in Sources */,
717706
74171EA91C10CD240062D398 /* SocketIOClientStatus.swift in Sources */,
718707
74171E791C10CD240062D398 /* SocketEngine.swift in Sources */,
719708
7420CB7B1C49629E00956AA4 /* SocketEnginePollable.swift in Sources */,
@@ -749,7 +738,6 @@
749738
74171EC81C10CD240062D398 /* SocketTypes.swift in Sources */,
750739
74171E921C10CD240062D398 /* SocketEventHandler.swift in Sources */,
751740
74171E801C10CD240062D398 /* SocketEngineClient.swift in Sources */,
752-
74171E981C10CD240062D398 /* SocketFixUTF8.swift in Sources */,
753741
74171E861C10CD240062D398 /* SocketEnginePacketType.swift in Sources */,
754742
74171ECE1C10CD240062D398 /* SwiftRegex.swift in Sources */,
755743
74171EB61C10CD240062D398 /* SocketPacket.swift in Sources */,

Source/SocketEngine.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
4141
public private(set) var closed = false
4242
public private(set) var connected = false
4343
public private(set) var cookies: [NSHTTPCookie]?
44+
public private(set) var doubleEncodeUTF8 = true
4445
public private(set) var extraHeaders: [String: String]?
4546
public private(set) var fastUpgrade = false
4647
public private(set) var forcePolling = false
@@ -88,18 +89,20 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
8889
switch option {
8990
case let .ConnectParams(params):
9091
connectParams = params
92+
case let .Cookies(cookies):
93+
self.cookies = cookies
94+
case let .DoubleEncodeUTF8(encode):
95+
doubleEncodeUTF8 = encode
96+
case let .ExtraHeaders(headers):
97+
extraHeaders = headers
9198
case let .SessionDelegate(delegate):
9299
sessionDelegate = delegate
93100
case let .ForcePolling(force):
94101
forcePolling = force
95102
case let .ForceWebsockets(force):
96103
forceWebsockets = force
97-
case let .Cookies(cookies):
98-
self.cookies = cookies
99104
case let .Path(path):
100105
socketPath = path
101-
case let .ExtraHeaders(headers):
102-
extraHeaders = headers
103106
case let .VoipEnabled(enable):
104107
voipEnabled = enable
105108
case let .Secure(secure):
@@ -432,7 +435,7 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
432435
return
433436
}
434437

435-
if fromPolling && type != .Noop {
438+
if fromPolling && type != .Noop && doubleEncodeUTF8 {
436439
fixedString = fixDoubleUTF8(message)
437440
} else {
438441
fixedString = message

Source/SocketEnginePollable.swift

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -206,21 +206,28 @@ extension SocketEnginePollable {
206206
/// Send polling message.
207207
/// Only call on emitQueue
208208
public func sendPollMessage(message: String, withType type: SocketEnginePacketType, withData datas: [NSData]) {
209-
DefaultSocketLogger.Logger.log("Sending poll: %@ as type: %@", type: "SocketEnginePolling", args: message, type.rawValue)
210-
let fixedMessage = doubleEncodeUTF8(message)
211-
let strMsg = "\(type.rawValue)\(fixedMessage)"
212-
213-
postWait.append(strMsg)
214-
215-
for data in datas {
216-
if case let .Right(bin) = createBinaryDataForSend(data) {
217-
postWait.append(bin)
218-
}
219-
}
220-
221-
if !waitingForPost {
222-
flushWaitingForPost()
209+
DefaultSocketLogger.Logger.log("Sending poll: %@ as type: %@", type: "SocketEnginePolling", args: message, type.rawValue)
210+
let fixedMessage: String
211+
212+
if doubleEncodeUTF8 {
213+
fixedMessage = doubleEncodeUTF8(message)
214+
} else {
215+
fixedMessage = message
216+
}
217+
218+
let strMsg = "\(type.rawValue)\(fixedMessage)"
219+
220+
postWait.append(strMsg)
221+
222+
for data in datas {
223+
if case let .Right(bin) = createBinaryDataForSend(data) {
224+
postWait.append(bin)
223225
}
226+
}
227+
228+
if !waitingForPost {
229+
flushWaitingForPost()
230+
}
224231
}
225232

226233
public func stopPolling() {

Source/SocketEngineSpec.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import Foundation
3030
var closed: Bool { get }
3131
var connected: Bool { get }
3232
var connectParams: [String: AnyObject]? { get set }
33+
var doubleEncodeUTF8: Bool { get }
3334
var cookies: [NSHTTPCookie]? { get }
3435
var extraHeaders: [String: String]? { get }
3536
var fastUpgrade: Bool { get }
@@ -89,6 +90,24 @@ extension SocketEngineSpec {
8990
}
9091
}
9192

93+
func doubleEncodeUTF8(string: String) -> String {
94+
if let latin1 = string.dataUsingEncoding(NSUTF8StringEncoding),
95+
utf8 = NSString(data: latin1, encoding: NSISOLatin1StringEncoding) {
96+
return utf8 as String
97+
} else {
98+
return string
99+
}
100+
}
101+
102+
func fixDoubleUTF8(string: String) -> String {
103+
if let utf8 = string.dataUsingEncoding(NSISOLatin1StringEncoding),
104+
latin1 = NSString(data: utf8, encoding: NSUTF8StringEncoding) {
105+
return latin1 as String
106+
} else {
107+
return string
108+
}
109+
}
110+
92111
/// Send an engine message (4)
93112
func send(msg: String, withData datas: [NSData]) {
94113
write(msg, withType: .Message, withData: datas)

Source/SocketFixUTF8.swift

Lines changed: 0 additions & 44 deletions
This file was deleted.

Source/SocketIOClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketParsable
165165
} else {
166166
engine?.open()
167167
}
168-
168+
169169
guard timeoutAfter != 0 else { return }
170170

171171
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(timeoutAfter) * Int64(NSEC_PER_SEC))

Source/SocketIOClientOption.swift

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ protocol ClientOption: CustomStringConvertible, Hashable {
3131
public enum SocketIOClientOption: ClientOption {
3232
case ConnectParams([String: AnyObject])
3333
case Cookies([NSHTTPCookie])
34+
case DoubleEncodeUTF8(Bool)
3435
case ExtraHeaders([String: String])
3536
case ForceNew(Bool)
3637
case ForcePolling(Bool)
@@ -56,6 +57,8 @@ public enum SocketIOClientOption: ClientOption {
5657
description = "connectParams"
5758
case .Cookies:
5859
description = "cookies"
60+
case .DoubleEncodeUTF8:
61+
description = "doubleEncodeUTF8"
5962
case .ExtraHeaders:
6063
description = "extraHeaders"
6164
case .ForceNew:
@@ -105,6 +108,8 @@ public enum SocketIOClientOption: ClientOption {
105108
value = params
106109
case let .Cookies(cookies):
107110
value = cookies
111+
case let .DoubleEncodeUTF8(encode):
112+
value = encode
108113
case let .ExtraHeaders(headers):
109114
value = headers
110115
case let .ForceNew(force):
@@ -160,40 +165,42 @@ extension NSDictionary {
160165
switch (key, value) {
161166
case let ("connectParams", params as [String: AnyObject]):
162167
return .ConnectParams(params)
163-
case let ("reconnects", reconnects as Bool):
164-
return .Reconnects(reconnects)
165-
case let ("reconnectAttempts", attempts as Int):
166-
return .ReconnectAttempts(attempts)
167-
case let ("reconnectWait", wait as Int):
168-
return .ReconnectWait(wait)
168+
case let ("cookies", cookies as [NSHTTPCookie]):
169+
return .Cookies(cookies)
170+
case let ("doubleEncodeUTF8", encode as Bool):
171+
return .DoubleEncodeUTF8(encode)
172+
case let ("extraHeaders", headers as [String: String]):
173+
return .ExtraHeaders(headers)
169174
case let ("forceNew", force as Bool):
170175
return .ForceNew(force)
171176
case let ("forcePolling", force as Bool):
172177
return .ForcePolling(force)
173178
case let ("forceWebsockets", force as Bool):
174179
return .ForceWebsockets(force)
175-
case let ("nsp", nsp as String):
176-
return .Nsp(nsp)
177-
case let ("cookies", cookies as [NSHTTPCookie]):
178-
return .Cookies(cookies)
180+
case let ("handleQueue", queue as dispatch_queue_t):
181+
return .HandleQueue(queue)
179182
case let ("log", log as Bool):
180183
return .Log(log)
181184
case let ("logger", logger as SocketLogger):
182185
return .Logger(logger)
183-
case let ("sessionDelegate", delegate as NSURLSessionDelegate):
184-
return .SessionDelegate(delegate)
186+
case let ("nsp", nsp as String):
187+
return .Nsp(nsp)
185188
case let ("path", path as String):
186189
return .Path(path)
187-
case let ("extraHeaders", headers as [String: String]):
188-
return .ExtraHeaders(headers)
189-
case let ("handleQueue", queue as dispatch_queue_t):
190-
return .HandleQueue(queue)
191-
case let ("voipEnabled", enable as Bool):
192-
return .VoipEnabled(enable)
190+
case let ("reconnects", reconnects as Bool):
191+
return .Reconnects(reconnects)
192+
case let ("reconnectAttempts", attempts as Int):
193+
return .ReconnectAttempts(attempts)
194+
case let ("reconnectWait", wait as Int):
195+
return .ReconnectWait(wait)
193196
case let ("secure", secure as Bool):
194197
return .Secure(secure)
195198
case let ("selfSigned", selfSigned as Bool):
196199
return .SelfSigned(selfSigned)
200+
case let ("sessionDelegate", delegate as NSURLSessionDelegate):
201+
return .SessionDelegate(delegate)
202+
case let ("voipEnabled", enable as Bool):
203+
return .VoipEnabled(enable)
197204
default:
198205
return nil
199206
}

0 commit comments

Comments
 (0)