Skip to content

Commit a856b68

Browse files
committed
Added OS X framework
1 parent 9a0be0b commit a856b68

3 files changed

Lines changed: 153 additions & 15 deletions

File tree

README.rst

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,14 @@ SocketRocket currently conforms to all ~300 of `Autobahn
1111
<http://www.tavendo.de/autobahn/testsuite.html>`_'s fuzzing tests (aside from
1212
two UTF-8 ones where it is merely *non-strict*. tests 6.4.2 and 6.4.4)
1313

14-
15-
It should work on OS X too. There are no UIKit dependencies.
16-
17-
.. Warning::
18-
This is not production-quality software yet. It has only been used in
19-
devlopment environments.
20-
21-
**USE AT YOUR OWN RISK**
22-
23-
(it will mature quickly… I am just conservative)
14+
Now has (32-bit only) OS X support. ``SocketRocket.framework`` inside Xcode
15+
project is for OS X only. It should be identical in function aside from the
16+
unicode validation. ICU isn't shipped with OS X which is what the original
17+
implementation used for unicode validation. The workaround is much more
18+
rhudimentary and less robust.
2419

2520
Features/Design
2621
---------------
27-
2822
- TLS (wss) support. It uses CFStream so we get this for "free"
2923
- Uses NSStream/CFNetworking. Earlier implementations used ``dispatch_io``,
3024
however, this proved to be make TLS nearly impossible. Also I wanted this to

SocketRocket.xcodeproj/project.pbxproj

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626
F624180314D53449003CE997 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD51451231B00C1D980 /* CFNetwork.framework */; };
2727
F624180414D53449003CE997 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6A12CD3145122FC00C1D980 /* Security.framework */; };
2828
F624180614D53451003CE997 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F6C41C95145F7C4700641356 /* libicucore.dylib */; };
29+
F6396B86153E67EC00345B5E /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.m */; };
30+
F6396B87153E67EC00345B5E /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = F6016C7B146124B20037BB3D /* base64.c */; };
31+
F6396B88153E67EC00345B5E /* NSData+SRB64Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = F6572124146C7B6A00D6B8A9 /* NSData+SRB64Additions.m */; };
32+
F6396B8F153E67EC00345B5E /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; };
33+
F6396B90153E67EC00345B5E /* base64.h in Headers */ = {isa = PBXBuildFile; fileRef = F6016C7E146124ED0037BB3D /* base64.h */; };
34+
F6396BA0153E6D3700345B5E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6396B9F153E6D3700345B5E /* Security.framework */; };
35+
F6396BA2153E6D4800345B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6396BA1153E6D4800345B5E /* Foundation.framework */; };
36+
F6396BA5153E6D7400345B5E /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6396BA4153E6D7400345B5E /* CoreServices.framework */; };
2937
F6572126146C7B6A00D6B8A9 /* NSData+SRB64Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = F6572124146C7B6A00D6B8A9 /* NSData+SRB64Additions.m */; };
3038
F6A12CD1145119B700C1D980 /* SRWebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = F6A12CCF145119B700C1D980 /* SRWebSocket.h */; };
3139
F6A12CD2145119B700C1D980 /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = F6A12CD0145119B700C1D980 /* SRWebSocket.m */; };
@@ -70,6 +78,10 @@
7078
F62417FA14D52F3C003CE997 /* TCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TCViewController.m; sourceTree = "<group>"; };
7179
F62417FF14D5300C003CE997 /* TCChatCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCChatCell.h; sourceTree = "<group>"; };
7280
F624180014D5300C003CE997 /* TCChatCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCChatCell.m; sourceTree = "<group>"; };
81+
F6396B94153E67EC00345B5E /* SocketRocket.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SocketRocket.framework; sourceTree = BUILT_PRODUCTS_DIR; };
82+
F6396B9F153E6D3700345B5E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; };
83+
F6396BA1153E6D4800345B5E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
84+
F6396BA4153E6D7400345B5E /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/CoreServices.framework; sourceTree = DEVELOPER_DIR; };
7385
F6572123146C7B6A00D6B8A9 /* NSData+SRB64Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+SRB64Additions.h"; sourceTree = "<group>"; };
7486
F6572124146C7B6A00D6B8A9 /* NSData+SRB64Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+SRB64Additions.m"; sourceTree = "<group>"; };
7587
F6A12CCF145119B700C1D980 /* SRWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRWebSocket.h; sourceTree = "<group>"; };
@@ -105,6 +117,16 @@
105117
);
106118
runOnlyForDeploymentPostprocessing = 0;
107119
};
120+
F6396B89153E67EC00345B5E /* Frameworks */ = {
121+
isa = PBXFrameworksBuildPhase;
122+
buildActionMask = 2147483647;
123+
files = (
124+
F6396BA5153E6D7400345B5E /* CoreServices.framework in Frameworks */,
125+
F6396BA2153E6D4800345B5E /* Foundation.framework in Frameworks */,
126+
F6396BA0153E6D3700345B5E /* Security.framework in Frameworks */,
127+
);
128+
runOnlyForDeploymentPostprocessing = 0;
129+
};
108130
F6B2082A1450F597009315AF /* Frameworks */ = {
109131
isa = PBXFrameworksBuildPhase;
110132
buildActionMask = 2147483647;
@@ -158,6 +180,16 @@
158180
name = "Supporting Files";
159181
sourceTree = "<group>";
160182
};
183+
F6396BA3153E6D4D00345B5E /* OSX Frameworks */ = {
184+
isa = PBXGroup;
185+
children = (
186+
F6396BA4153E6D7400345B5E /* CoreServices.framework */,
187+
F6396BA1153E6D4800345B5E /* Foundation.framework */,
188+
F6396B9F153E6D3700345B5E /* Security.framework */,
189+
);
190+
name = "OSX Frameworks";
191+
sourceTree = "<group>";
192+
};
161193
F6B208221450F597009315AF = {
162194
isa = PBXGroup;
163195
children = (
@@ -177,13 +209,15 @@
177209
F6B2082D1450F597009315AF /* libSocketRocket.a */,
178210
F6BDA802145900D200FE3253 /* SRWebSocketTests.octest */,
179211
F62417E314D52F3C003CE997 /* TestChat.app */,
212+
F6396B94153E67EC00345B5E /* SocketRocket.framework */,
180213
);
181214
name = Products;
182215
sourceTree = "<group>";
183216
};
184217
F6B2082F1450F597009315AF /* Frameworks */ = {
185218
isa = PBXGroup;
186219
children = (
220+
F6396BA3153E6D4D00345B5E /* OSX Frameworks */,
187221
F6C41C95145F7C4700641356 /* libicucore.dylib */,
188222
F6A12CD51451231B00C1D980 /* CFNetwork.framework */,
189223
F6A12CD3145122FC00C1D980 /* Security.framework */,
@@ -243,6 +277,15 @@
243277
/* End PBXGroup section */
244278

245279
/* Begin PBXHeadersBuildPhase section */
280+
F6396B8E153E67EC00345B5E /* Headers */ = {
281+
isa = PBXHeadersBuildPhase;
282+
buildActionMask = 2147483647;
283+
files = (
284+
F6396B8F153E67EC00345B5E /* SRWebSocket.h in Headers */,
285+
F6396B90153E67EC00345B5E /* base64.h in Headers */,
286+
);
287+
runOnlyForDeploymentPostprocessing = 0;
288+
};
246289
F6B2082B1450F597009315AF /* Headers */ = {
247290
isa = PBXHeadersBuildPhase;
248291
buildActionMask = 2147483647;
@@ -272,6 +315,23 @@
272315
productReference = F62417E314D52F3C003CE997 /* TestChat.app */;
273316
productType = "com.apple.product-type.application";
274317
};
318+
F6396B84153E67EC00345B5E /* SocketRocketOSX */ = {
319+
isa = PBXNativeTarget;
320+
buildConfigurationList = F6396B91153E67EC00345B5E /* Build configuration list for PBXNativeTarget "SocketRocketOSX" */;
321+
buildPhases = (
322+
F6396B85153E67EC00345B5E /* Sources */,
323+
F6396B89153E67EC00345B5E /* Frameworks */,
324+
F6396B8E153E67EC00345B5E /* Headers */,
325+
);
326+
buildRules = (
327+
);
328+
dependencies = (
329+
);
330+
name = SocketRocketOSX;
331+
productName = SocketRocket;
332+
productReference = F6396B94153E67EC00345B5E /* SocketRocket.framework */;
333+
productType = "com.apple.product-type.framework";
334+
};
275335
F6B2082C1450F597009315AF /* SocketRocket */ = {
276336
isa = PBXNativeTarget;
277337
buildConfigurationList = F6B2083A1450F597009315AF /* Build configuration list for PBXNativeTarget "SocketRocket" */;
@@ -330,6 +390,7 @@
330390
targets = (
331391
F6B2082C1450F597009315AF /* SocketRocket */,
332392
F6BDA801145900D200FE3253 /* SRWebSocketTests */,
393+
F6396B84153E67EC00345B5E /* SocketRocketOSX */,
333394
F62417E214D52F3C003CE997 /* TestChat */,
334395
);
335396
};
@@ -383,6 +444,16 @@
383444
);
384445
runOnlyForDeploymentPostprocessing = 0;
385446
};
447+
F6396B85153E67EC00345B5E /* Sources */ = {
448+
isa = PBXSourcesBuildPhase;
449+
buildActionMask = 2147483647;
450+
files = (
451+
F6396B86153E67EC00345B5E /* SRWebSocket.m in Sources */,
452+
F6396B87153E67EC00345B5E /* base64.c in Sources */,
453+
F6396B88153E67EC00345B5E /* NSData+SRB64Additions.m in Sources */,
454+
);
455+
runOnlyForDeploymentPostprocessing = 0;
456+
};
386457
F6B208291450F597009315AF /* Sources */ = {
387458
isa = PBXSourcesBuildPhase;
388459
buildActionMask = 2147483647;
@@ -482,6 +553,37 @@
482553
};
483554
name = Release;
484555
};
556+
F6396B92153E67EC00345B5E /* Debug */ = {
557+
isa = XCBuildConfiguration;
558+
buildSettings = {
559+
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
560+
CLANG_ENABLE_OBJC_ARC = YES;
561+
DSTROOT = /tmp/SocketRocket.dst;
562+
GCC_PRECOMPILE_PREFIX_HEADER = YES;
563+
GCC_PREFIX_HEADER = "SocketRocket/SocketRocket-Prefix.pch";
564+
ONLY_ACTIVE_ARCH = YES;
565+
OTHER_LDFLAGS = "-ObjC";
566+
PRODUCT_NAME = SocketRocket;
567+
SDKROOT = macosx;
568+
SKIP_INSTALL = YES;
569+
};
570+
name = Debug;
571+
};
572+
F6396B93153E67EC00345B5E /* Release */ = {
573+
isa = XCBuildConfiguration;
574+
buildSettings = {
575+
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
576+
CLANG_ENABLE_OBJC_ARC = YES;
577+
DSTROOT = /tmp/SocketRocket.dst;
578+
GCC_PRECOMPILE_PREFIX_HEADER = YES;
579+
GCC_PREFIX_HEADER = "SocketRocket/SocketRocket-Prefix.pch";
580+
OTHER_LDFLAGS = "-ObjC";
581+
PRODUCT_NAME = SocketRocket;
582+
SDKROOT = macosx;
583+
SKIP_INSTALL = YES;
584+
};
585+
name = Release;
586+
};
485587
F6B208381450F597009315AF /* Debug */ = {
486588
isa = XCBuildConfiguration;
487589
buildSettings = {
@@ -626,6 +728,15 @@
626728
defaultConfigurationIsVisible = 0;
627729
defaultConfigurationName = Release;
628730
};
731+
F6396B91153E67EC00345B5E /* Build configuration list for PBXNativeTarget "SocketRocketOSX" */ = {
732+
isa = XCConfigurationList;
733+
buildConfigurations = (
734+
F6396B92153E67EC00345B5E /* Debug */,
735+
F6396B93153E67EC00345B5E /* Release */,
736+
);
737+
defaultConfigurationIsVisible = 0;
738+
defaultConfigurationName = Release;
739+
};
629740
F6B208271450F597009315AF /* Build configuration list for PBXProject "SocketRocket" */ = {
630741
isa = XCConfigurationList;
631742
buildConfigurations = (

SocketRocket/SRWebSocket.m

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,22 @@
1717

1818
#import "SRWebSocket.h"
1919

20+
#if TARGET_OS_IPHONE
21+
#define HAS_ICU
22+
#endif
23+
24+
#ifdef HAS_ICU
2025
#import <unicode/utf8.h>
26+
#endif
27+
28+
#if TARGET_OS_IPHONE
2129
#import <Endian.h>
30+
#else
31+
#import <CoreServices/CoreServices.h>
32+
#endif
33+
2234
#import <CommonCrypto/CommonDigest.h>
35+
#import <Security/SecRandom.h>
2336
#import "base64.h"
2437
#import "NSData+SRB64Additions.h"
2538

@@ -85,13 +98,15 @@ static inline void SRFastLog(NSString *format, ...) {
8598

8699
static NSString *const SRWebSocketAppendToSecKeyString = @"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
87100

101+
#ifdef HAS_ICU
102+
88103
static inline int32_t validate_dispatch_data_partial_string(NSData *data) {
89104

90105
const void * contents = [data bytes];
91106
long size = [data length];
92107

93108
const uint8_t *str = (const uint8_t *)contents;
94-
109+
95110

96111
UChar32 codepoint = 1;
97112
int32_t offset = 0;
@@ -109,27 +124,45 @@ static inline int32_t validate_dispatch_data_partial_string(NSData *data) {
109124
} else {
110125
uint8_t leadByte = str[lastOffset];
111126
U8_MASK_LEAD_BYTE(leadByte, U8_COUNT_TRAIL_BYTES(leadByte));
112-
127+
113128
for (int i = lastOffset + 1; i < offset; i++) {
114129

115130
if (U8_IS_SINGLE(str[i]) || U8_IS_LEAD(str[i]) || !U8_IS_TRAIL(str[i])) {
116131
size = -1;
117132
}
118133
}
119-
134+
120135
if (size != -1) {
121136
size = lastOffset;
122137
}
123138
}
124139
}
125-
140+
126141
if (size != -1 && ![[NSString alloc] initWithBytesNoCopy:(char *)[data bytes] length:size encoding:NSUTF8StringEncoding freeWhenDone:NO]) {
127142
size = -1;
128143
}
129144

130145
return size;
131146
}
132147

148+
#else
149+
150+
// This is a hack, and probably not optimal
151+
static inline int32_t validate_dispatch_data_partial_string(NSData *data) {
152+
static const int maxCodepointSize = 3;
153+
154+
for (int i = 0; i < maxCodepointSize; i++) {
155+
NSString *str = [[NSString alloc] initWithBytesNoCopy:(char *)data.bytes length:data.length - i encoding:NSUTF8StringEncoding freeWhenDone:NO];
156+
if (str) {
157+
return data.length - i;
158+
}
159+
}
160+
161+
return -1;
162+
}
163+
164+
#endif
165+
133166

134167
@interface NSData (SRWebSocket)
135168

0 commit comments

Comments
 (0)