提交
This commit is contained in:
68
SweetParty/第三方库/SocketRocket/Internal/Delegate/SRDelegateController.h
Executable file
68
SweetParty/第三方库/SocketRocket/Internal/Delegate/SRDelegateController.h
Executable file
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//#import <SocketRocket/SRWebSocket.h>
|
||||
#import "SRWebSocket.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#if OBJC_BOOL_IS_BOOL
|
||||
|
||||
struct SRDelegateAvailableMethods {
|
||||
BOOL didReceiveMessage : 1;
|
||||
BOOL didReceiveMessageWithString : 1;
|
||||
BOOL didReceiveMessageWithData : 1;
|
||||
BOOL didOpen : 1;
|
||||
BOOL didFailWithError : 1;
|
||||
BOOL didCloseWithCode : 1;
|
||||
BOOL didReceivePing : 1;
|
||||
BOOL didReceivePong : 1;
|
||||
BOOL shouldConvertTextFrameToString : 1;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
struct SRDelegateAvailableMethods {
|
||||
BOOL didReceiveMessage;
|
||||
BOOL didReceiveMessageWithString;
|
||||
BOOL didReceiveMessageWithData;
|
||||
BOOL didOpen;
|
||||
BOOL didFailWithError;
|
||||
BOOL didCloseWithCode;
|
||||
BOOL didReceivePing;
|
||||
BOOL didReceivePong;
|
||||
BOOL shouldConvertTextFrameToString;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct SRDelegateAvailableMethods SRDelegateAvailableMethods;
|
||||
|
||||
typedef void(^SRDelegateBlock)(id<SRWebSocketDelegate> _Nullable delegate, SRDelegateAvailableMethods availableMethods);
|
||||
|
||||
@interface SRDelegateController : NSObject
|
||||
|
||||
@property (nonatomic, weak) id<SRWebSocketDelegate> delegate;
|
||||
@property (atomic, readonly) SRDelegateAvailableMethods availableDelegateMethods;
|
||||
|
||||
@property (nullable, nonatomic, strong) dispatch_queue_t dispatchQueue;
|
||||
@property (nullable, nonatomic, strong) NSOperationQueue *operationQueue;
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - Perform
|
||||
///--------------------------------------
|
||||
|
||||
- (void)performDelegateBlock:(SRDelegateBlock)block;
|
||||
- (void)performDelegateQueueBlock:(dispatch_block_t)block;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
138
SweetParty/第三方库/SocketRocket/Internal/Delegate/SRDelegateController.m
Executable file
138
SweetParty/第三方库/SocketRocket/Internal/Delegate/SRDelegateController.m
Executable file
@@ -0,0 +1,138 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRDelegateController.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface SRDelegateController ()
|
||||
|
||||
@property (nonatomic, strong, readonly) dispatch_queue_t accessQueue;
|
||||
|
||||
@property (atomic, assign, readwrite) SRDelegateAvailableMethods availableDelegateMethods;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SRDelegateController
|
||||
|
||||
@synthesize delegate = _delegate;
|
||||
@synthesize dispatchQueue = _dispatchQueue;
|
||||
@synthesize operationQueue = _operationQueue;
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - Init
|
||||
///--------------------------------------
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) return self;
|
||||
|
||||
_accessQueue = dispatch_queue_create("com.facebook.socketrocket.delegate.access", DISPATCH_QUEUE_CONCURRENT);
|
||||
_dispatchQueue = dispatch_get_main_queue();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - Accessors
|
||||
///--------------------------------------
|
||||
|
||||
- (void)setDelegate:(id<SRWebSocketDelegate> _Nullable)delegate
|
||||
{
|
||||
dispatch_barrier_async(self.accessQueue, ^{
|
||||
_delegate = delegate;
|
||||
|
||||
self.availableDelegateMethods = (SRDelegateAvailableMethods){
|
||||
.didReceiveMessage = [delegate respondsToSelector:@selector(webSocket:didReceiveMessage:)],
|
||||
.didReceiveMessageWithString = [delegate respondsToSelector:@selector(webSocket:didReceiveMessageWithString:)],
|
||||
.didReceiveMessageWithData = [delegate respondsToSelector:@selector(webSocket:didReceiveMessageWithData:)],
|
||||
.didOpen = [delegate respondsToSelector:@selector(webSocketDidOpen:)],
|
||||
.didFailWithError = [delegate respondsToSelector:@selector(webSocket:didFailWithError:)],
|
||||
.didCloseWithCode = [delegate respondsToSelector:@selector(webSocket:didCloseWithCode:reason:wasClean:)],
|
||||
.didReceivePing = [delegate respondsToSelector:@selector(webSocket:didReceivePingWithData:)],
|
||||
.didReceivePong = [delegate respondsToSelector:@selector(webSocket:didReceivePong:)],
|
||||
.shouldConvertTextFrameToString = [delegate respondsToSelector:@selector(webSocketShouldConvertTextFrameToString:)]
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
- (id<SRWebSocketDelegate> _Nullable)delegate
|
||||
{
|
||||
__block id<SRWebSocketDelegate> delegate = nil;
|
||||
dispatch_sync(self.accessQueue, ^{
|
||||
delegate = _delegate;
|
||||
});
|
||||
return delegate;
|
||||
}
|
||||
|
||||
- (void)setDispatchQueue:(dispatch_queue_t _Nullable)queue
|
||||
{
|
||||
dispatch_barrier_async(self.accessQueue, ^{
|
||||
_dispatchQueue = queue ?: dispatch_get_main_queue();
|
||||
_operationQueue = nil;
|
||||
});
|
||||
}
|
||||
|
||||
- (dispatch_queue_t _Nullable)dispatchQueue
|
||||
{
|
||||
__block dispatch_queue_t queue = nil;
|
||||
dispatch_sync(self.accessQueue, ^{
|
||||
queue = _dispatchQueue;
|
||||
});
|
||||
return queue;
|
||||
}
|
||||
|
||||
- (void)setOperationQueue:(NSOperationQueue *_Nullable)queue
|
||||
{
|
||||
dispatch_barrier_async(self.accessQueue, ^{
|
||||
_dispatchQueue = queue ? nil : dispatch_get_main_queue();
|
||||
_operationQueue = queue;
|
||||
});
|
||||
}
|
||||
|
||||
- (NSOperationQueue *_Nullable)operationQueue
|
||||
{
|
||||
__block NSOperationQueue *queue = nil;
|
||||
dispatch_sync(self.accessQueue, ^{
|
||||
queue = _operationQueue;
|
||||
});
|
||||
return queue;
|
||||
}
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - Perform
|
||||
///--------------------------------------
|
||||
|
||||
- (void)performDelegateBlock:(SRDelegateBlock)block
|
||||
{
|
||||
__block __strong id<SRWebSocketDelegate> delegate = nil;
|
||||
__block SRDelegateAvailableMethods availableMethods = {};
|
||||
dispatch_sync(self.accessQueue, ^{
|
||||
delegate = _delegate; // Not `OK` to go through `self`, since queue sync.
|
||||
availableMethods = self.availableDelegateMethods; // `OK` to call through `self`, since no queue sync.
|
||||
});
|
||||
[self performDelegateQueueBlock:^{
|
||||
block(delegate, availableMethods);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)performDelegateQueueBlock:(dispatch_block_t)block
|
||||
{
|
||||
dispatch_queue_t dispatchQueue = self.dispatchQueue;
|
||||
if (dispatchQueue) {
|
||||
dispatch_async(dispatchQueue, block);
|
||||
} else {
|
||||
[self.operationQueue addOperationWithBlock:block];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
40
SweetParty/第三方库/SocketRocket/Internal/IOConsumer/SRIOConsumer.h
Executable file
40
SweetParty/第三方库/SocketRocket/Internal/IOConsumer/SRIOConsumer.h
Executable file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class SRWebSocket; // TODO: (nlutsenko) Remove dependency on SRWebSocket here.
|
||||
|
||||
// Returns number of bytes consumed. Returning 0 means you didn't match.
|
||||
// Sends bytes to callback handler;
|
||||
typedef size_t (^stream_scanner)(NSData *collected_data);
|
||||
typedef void (^data_callback)(SRWebSocket *webSocket, NSData *data);
|
||||
|
||||
@interface SRIOConsumer : NSObject {
|
||||
stream_scanner _scanner;
|
||||
data_callback _handler;
|
||||
size_t _bytesNeeded;
|
||||
BOOL _readToCurrentFrame;
|
||||
BOOL _unmaskBytes;
|
||||
}
|
||||
@property (nonatomic, copy, readonly) stream_scanner consumer;
|
||||
@property (nonatomic, copy, readonly) data_callback handler;
|
||||
@property (nonatomic, assign) size_t bytesNeeded;
|
||||
@property (nonatomic, assign, readonly) BOOL readToCurrentFrame;
|
||||
@property (nonatomic, assign, readonly) BOOL unmaskBytes;
|
||||
|
||||
- (void)resetWithScanner:(stream_scanner)scanner
|
||||
handler:(data_callback)handler
|
||||
bytesNeeded:(size_t)bytesNeeded
|
||||
readToCurrentFrame:(BOOL)readToCurrentFrame
|
||||
unmaskBytes:(BOOL)unmaskBytes;
|
||||
|
||||
@end
|
||||
36
SweetParty/第三方库/SocketRocket/Internal/IOConsumer/SRIOConsumer.m
Executable file
36
SweetParty/第三方库/SocketRocket/Internal/IOConsumer/SRIOConsumer.m
Executable file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRIOConsumer.h"
|
||||
|
||||
@implementation SRIOConsumer
|
||||
|
||||
@synthesize bytesNeeded = _bytesNeeded;
|
||||
@synthesize consumer = _scanner;
|
||||
@synthesize handler = _handler;
|
||||
@synthesize readToCurrentFrame = _readToCurrentFrame;
|
||||
@synthesize unmaskBytes = _unmaskBytes;
|
||||
|
||||
- (void)resetWithScanner:(stream_scanner)scanner
|
||||
handler:(data_callback)handler
|
||||
bytesNeeded:(size_t)bytesNeeded
|
||||
readToCurrentFrame:(BOOL)readToCurrentFrame
|
||||
unmaskBytes:(BOOL)unmaskBytes
|
||||
{
|
||||
_scanner = [scanner copy];
|
||||
_handler = [handler copy];
|
||||
_bytesNeeded = bytesNeeded;
|
||||
_readToCurrentFrame = readToCurrentFrame;
|
||||
_unmaskBytes = unmaskBytes;
|
||||
assert(_scanner || _bytesNeeded);
|
||||
}
|
||||
|
||||
@end
|
||||
28
SweetParty/第三方库/SocketRocket/Internal/IOConsumer/SRIOConsumerPool.h
Executable file
28
SweetParty/第三方库/SocketRocket/Internal/IOConsumer/SRIOConsumerPool.h
Executable file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "SRIOConsumer.h" // TODO: (nlutsenko) Convert to @class and constants file for block types
|
||||
|
||||
// This class is not thread-safe, and is expected to always be run on the same queue.
|
||||
@interface SRIOConsumerPool : NSObject
|
||||
|
||||
- (instancetype)initWithBufferCapacity:(NSUInteger)poolSize;
|
||||
|
||||
- (SRIOConsumer *)consumerWithScanner:(stream_scanner)scanner
|
||||
handler:(data_callback)handler
|
||||
bytesNeeded:(size_t)bytesNeeded
|
||||
readToCurrentFrame:(BOOL)readToCurrentFrame
|
||||
unmaskBytes:(BOOL)unmaskBytes;
|
||||
- (void)returnConsumer:(SRIOConsumer *)consumer;
|
||||
|
||||
@end
|
||||
64
SweetParty/第三方库/SocketRocket/Internal/IOConsumer/SRIOConsumerPool.m
Executable file
64
SweetParty/第三方库/SocketRocket/Internal/IOConsumer/SRIOConsumerPool.m
Executable file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRIOConsumerPool.h"
|
||||
|
||||
@implementation SRIOConsumerPool {
|
||||
NSUInteger _poolSize;
|
||||
NSMutableArray<SRIOConsumer *> *_bufferedConsumers;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBufferCapacity:(NSUInteger)poolSize;
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_poolSize = poolSize;
|
||||
_bufferedConsumers = [NSMutableArray arrayWithCapacity:poolSize];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
return [self initWithBufferCapacity:8];
|
||||
}
|
||||
|
||||
- (SRIOConsumer *)consumerWithScanner:(stream_scanner)scanner
|
||||
handler:(data_callback)handler
|
||||
bytesNeeded:(size_t)bytesNeeded
|
||||
readToCurrentFrame:(BOOL)readToCurrentFrame
|
||||
unmaskBytes:(BOOL)unmaskBytes
|
||||
{
|
||||
SRIOConsumer *consumer = nil;
|
||||
if (_bufferedConsumers.count) {
|
||||
consumer = [_bufferedConsumers lastObject];
|
||||
[_bufferedConsumers removeLastObject];
|
||||
} else {
|
||||
consumer = [[SRIOConsumer alloc] init];
|
||||
}
|
||||
|
||||
[consumer resetWithScanner:scanner
|
||||
handler:handler
|
||||
bytesNeeded:bytesNeeded
|
||||
readToCurrentFrame:readToCurrentFrame
|
||||
unmaskBytes:unmaskBytes];
|
||||
|
||||
return consumer;
|
||||
}
|
||||
|
||||
- (void)returnConsumer:(SRIOConsumer *)consumer;
|
||||
{
|
||||
if (_bufferedConsumers.count < _poolSize) {
|
||||
[_bufferedConsumers addObject:consumer];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
14
SweetParty/第三方库/SocketRocket/Internal/NSRunLoop+SRWebSocketPrivate.h
Executable file
14
SweetParty/第三方库/SocketRocket/Internal/NSRunLoop+SRWebSocketPrivate.h
Executable file
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
//#import <SocketRocket/NSRunLoop+SRWebSocket.h>
|
||||
#import "NSRunLoop+SRWebSocket.h"
|
||||
|
||||
// Empty function that force links the object file for the category.
|
||||
extern void import_NSRunLoop_SRWebSocket(void);
|
||||
14
SweetParty/第三方库/SocketRocket/Internal/NSURLRequest+SRWebSocketPrivate.h
Executable file
14
SweetParty/第三方库/SocketRocket/Internal/NSURLRequest+SRWebSocketPrivate.h
Executable file
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
//#import <SocketRocket/NSURLRequest+SRWebSocket.h>
|
||||
#import "NSURLRequest+SRWebSocket.h"
|
||||
|
||||
// Empty function that force links the object file for the category.
|
||||
extern void import_NSURLRequest_SRWebSocket(void);
|
||||
26
SweetParty/第三方库/SocketRocket/Internal/Proxy/SRProxyConnect.h
Executable file
26
SweetParty/第三方库/SocketRocket/Internal/Proxy/SRProxyConnect.h
Executable file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void(^SRProxyConnectCompletion)(NSError *_Nullable error,
|
||||
NSInputStream *_Nullable readStream,
|
||||
NSOutputStream *_Nullable writeStream);
|
||||
|
||||
@interface SRProxyConnect : NSObject
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url;
|
||||
|
||||
- (void)openNetworkStreamWithCompletion:(SRProxyConnectCompletion)completion;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
481
SweetParty/第三方库/SocketRocket/Internal/Proxy/SRProxyConnect.m
Executable file
481
SweetParty/第三方库/SocketRocket/Internal/Proxy/SRProxyConnect.m
Executable file
@@ -0,0 +1,481 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRProxyConnect.h"
|
||||
|
||||
#import "NSRunLoop+SRWebSocket.h"
|
||||
#import "SRConstants.h"
|
||||
#import "SRError.h"
|
||||
#import "SRLog.h"
|
||||
#import "SRURLUtilities.h"
|
||||
|
||||
@interface SRProxyConnect() <NSStreamDelegate>
|
||||
|
||||
@property (nonatomic, strong) NSURL *url;
|
||||
@property (nonatomic, strong) NSInputStream *inputStream;
|
||||
@property (nonatomic, strong) NSOutputStream *outputStream;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SRProxyConnect
|
||||
{
|
||||
SRProxyConnectCompletion _completion;
|
||||
|
||||
NSString *_httpProxyHost;
|
||||
uint32_t _httpProxyPort;
|
||||
|
||||
CFHTTPMessageRef _receivedHTTPHeaders;
|
||||
|
||||
NSString *_socksProxyHost;
|
||||
uint32_t _socksProxyPort;
|
||||
NSString *_socksProxyUsername;
|
||||
NSString *_socksProxyPassword;
|
||||
|
||||
BOOL _connectionRequiresSSL;
|
||||
|
||||
NSMutableArray<NSData *> *_inputQueue;
|
||||
dispatch_queue_t _writeQueue;
|
||||
}
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - Init
|
||||
///--------------------------------------
|
||||
|
||||
-(instancetype)initWithURL:(NSURL *)url
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) return self;
|
||||
|
||||
_url = url;
|
||||
_connectionRequiresSSL = SRURLRequiresSSL(url);
|
||||
|
||||
_writeQueue = dispatch_queue_create("com.facebook.socketrocket.proxyconnect.write", DISPATCH_QUEUE_SERIAL);
|
||||
_inputQueue = [NSMutableArray arrayWithCapacity:2];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
// If we get deallocated before the socket open finishes - we need to cleanup everything.
|
||||
|
||||
[self.inputStream removeFromRunLoop:[NSRunLoop SR_networkRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
self.inputStream.delegate = nil;
|
||||
[self.inputStream close];
|
||||
self.inputStream = nil;
|
||||
|
||||
self.outputStream.delegate = nil;
|
||||
[self.outputStream close];
|
||||
self.outputStream = nil;
|
||||
}
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - Open
|
||||
///--------------------------------------
|
||||
|
||||
- (void)openNetworkStreamWithCompletion:(SRProxyConnectCompletion)completion
|
||||
{
|
||||
_completion = completion;
|
||||
[self _configureProxy];
|
||||
}
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - Flow
|
||||
///--------------------------------------
|
||||
|
||||
- (void)_didConnect
|
||||
{
|
||||
SRDebugLog(@"_didConnect, return streams");
|
||||
if (_connectionRequiresSSL) {
|
||||
if (_httpProxyHost) {
|
||||
// Must set the real peer name before turning on SSL
|
||||
SRDebugLog(@"proxy set peer name to real host %@", self.url.host);
|
||||
[self.outputStream setProperty:self.url.host forKey:@"_kCFStreamPropertySocketPeerName"];
|
||||
}
|
||||
}
|
||||
if (_receivedHTTPHeaders) {
|
||||
CFRelease(_receivedHTTPHeaders);
|
||||
_receivedHTTPHeaders = NULL;
|
||||
}
|
||||
|
||||
NSInputStream *inputStream = self.inputStream;
|
||||
NSOutputStream *outputStream = self.outputStream;
|
||||
|
||||
self.inputStream = nil;
|
||||
self.outputStream = nil;
|
||||
|
||||
[inputStream removeFromRunLoop:[NSRunLoop SR_networkRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
inputStream.delegate = nil;
|
||||
outputStream.delegate = nil;
|
||||
|
||||
_completion(nil, inputStream, outputStream);
|
||||
}
|
||||
|
||||
- (void)_failWithError:(NSError *)error
|
||||
{
|
||||
SRDebugLog(@"_failWithError, return error");
|
||||
if (!error) {
|
||||
error = SRHTTPErrorWithCodeDescription(500, 2132,@"Proxy Error");
|
||||
}
|
||||
|
||||
if (_receivedHTTPHeaders) {
|
||||
CFRelease(_receivedHTTPHeaders);
|
||||
_receivedHTTPHeaders = NULL;
|
||||
}
|
||||
|
||||
self.inputStream.delegate = nil;
|
||||
self.outputStream.delegate = nil;
|
||||
|
||||
[self.inputStream removeFromRunLoop:[NSRunLoop SR_networkRunLoop]
|
||||
forMode:NSDefaultRunLoopMode];
|
||||
[self.inputStream close];
|
||||
[self.outputStream close];
|
||||
self.inputStream = nil;
|
||||
self.outputStream = nil;
|
||||
_completion(error, nil, nil);
|
||||
}
|
||||
|
||||
// get proxy setting from device setting
|
||||
- (void)_configureProxy
|
||||
{
|
||||
SRDebugLog(@"configureProxy");
|
||||
NSDictionary *proxySettings = CFBridgingRelease(CFNetworkCopySystemProxySettings());
|
||||
|
||||
// CFNetworkCopyProxiesForURL doesn't understand ws:// or wss://
|
||||
NSURL *httpURL;
|
||||
if (_connectionRequiresSSL) {
|
||||
httpURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", _url.host]];
|
||||
} else {
|
||||
httpURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@", _url.host]];
|
||||
}
|
||||
|
||||
NSArray *proxies = CFBridgingRelease(CFNetworkCopyProxiesForURL((__bridge CFURLRef)httpURL, (__bridge CFDictionaryRef)proxySettings));
|
||||
if (proxies.count == 0) {
|
||||
SRDebugLog(@"configureProxy no proxies");
|
||||
[self _openConnection];
|
||||
return; // no proxy
|
||||
}
|
||||
NSDictionary *settings = [proxies objectAtIndex:0];
|
||||
NSString *proxyType = settings[(NSString *)kCFProxyTypeKey];
|
||||
if ([proxyType isEqualToString:(NSString *)kCFProxyTypeAutoConfigurationURL]) {
|
||||
NSURL *pacURL = settings[(NSString *)kCFProxyAutoConfigurationURLKey];
|
||||
if (pacURL) {
|
||||
[self _fetchPAC:pacURL withProxySettings:proxySettings];
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ([proxyType isEqualToString:(__bridge NSString *)kCFProxyTypeAutoConfigurationJavaScript]) {
|
||||
NSString *script = settings[(__bridge NSString *)kCFProxyAutoConfigurationJavaScriptKey];
|
||||
if (script) {
|
||||
[self _runPACScript:script withProxySettings:proxySettings];
|
||||
return;
|
||||
}
|
||||
}
|
||||
[self _readProxySettingWithType:proxyType settings:settings];
|
||||
|
||||
[self _openConnection];
|
||||
}
|
||||
|
||||
- (void)_readProxySettingWithType:(NSString *)proxyType settings:(NSDictionary *)settings
|
||||
{
|
||||
if ([proxyType isEqualToString:(NSString *)kCFProxyTypeHTTP] ||
|
||||
[proxyType isEqualToString:(NSString *)kCFProxyTypeHTTPS]) {
|
||||
_httpProxyHost = settings[(NSString *)kCFProxyHostNameKey];
|
||||
NSNumber *portValue = settings[(NSString *)kCFProxyPortNumberKey];
|
||||
if (portValue) {
|
||||
_httpProxyPort = [portValue intValue];
|
||||
}
|
||||
}
|
||||
if ([proxyType isEqualToString:(NSString *)kCFProxyTypeSOCKS]) {
|
||||
_socksProxyHost = settings[(NSString *)kCFProxyHostNameKey];
|
||||
NSNumber *portValue = settings[(NSString *)kCFProxyPortNumberKey];
|
||||
if (portValue)
|
||||
_socksProxyPort = [portValue intValue];
|
||||
_socksProxyUsername = settings[(NSString *)kCFProxyUsernameKey];
|
||||
_socksProxyPassword = settings[(NSString *)kCFProxyPasswordKey];
|
||||
}
|
||||
if (_httpProxyHost) {
|
||||
SRDebugLog(@"Using http proxy %@:%u", _httpProxyHost, _httpProxyPort);
|
||||
} else if (_socksProxyHost) {
|
||||
SRDebugLog(@"Using socks proxy %@:%u", _socksProxyHost, _socksProxyPort);
|
||||
} else {
|
||||
SRDebugLog(@"configureProxy no proxies");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_fetchPAC:(NSURL *)PACurl withProxySettings:(NSDictionary *)proxySettings
|
||||
{
|
||||
SRDebugLog(@"SRWebSocket fetchPAC:%@", PACurl);
|
||||
|
||||
if ([PACurl isFileURL]) {
|
||||
NSError *error = nil;
|
||||
NSString *script = [NSString stringWithContentsOfURL:PACurl
|
||||
usedEncoding:NULL
|
||||
error:&error];
|
||||
|
||||
if (error) {
|
||||
[self _openConnection];
|
||||
} else {
|
||||
[self _runPACScript:script withProxySettings:proxySettings];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *scheme = [PACurl.scheme lowercaseString];
|
||||
if (![scheme isEqualToString:@"http"] && ![scheme isEqualToString:@"https"]) {
|
||||
// Don't know how to read data from this URL, we'll have to give up
|
||||
// We'll simply assume no proxies, and start the request as normal
|
||||
[self _openConnection];
|
||||
return;
|
||||
}
|
||||
__weak typeof(self) wself = self;
|
||||
NSURLRequest *request = [NSURLRequest requestWithURL:PACurl];
|
||||
NSURLSession *session = [NSURLSession sharedSession];
|
||||
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||
__strong typeof(wself) sself = wself;
|
||||
if (!error) {
|
||||
NSString *script = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
[sself _runPACScript:script withProxySettings:proxySettings];
|
||||
} else {
|
||||
[sself _openConnection];
|
||||
}
|
||||
}] resume];
|
||||
}
|
||||
|
||||
- (void)_runPACScript:(NSString *)script withProxySettings:(NSDictionary *)proxySettings
|
||||
{
|
||||
if (!script) {
|
||||
[self _openConnection];
|
||||
return;
|
||||
}
|
||||
SRDebugLog(@"runPACScript");
|
||||
// From: http://developer.apple.com/samplecode/CFProxySupportTool/listing1.html
|
||||
// Work around <rdar://problem/5530166>. This dummy call to
|
||||
// CFNetworkCopyProxiesForURL initialise some state within CFNetwork
|
||||
// that is required by CFNetworkCopyProxiesForAutoConfigurationScript.
|
||||
CFBridgingRelease(CFNetworkCopyProxiesForURL((__bridge CFURLRef)_url, (__bridge CFDictionaryRef)proxySettings));
|
||||
|
||||
// Obtain the list of proxies by running the autoconfiguration script
|
||||
CFErrorRef err = NULL;
|
||||
|
||||
// CFNetworkCopyProxiesForAutoConfigurationScript doesn't understand ws:// or wss://
|
||||
NSURL *httpURL;
|
||||
if (_connectionRequiresSSL)
|
||||
httpURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", _url.host]];
|
||||
else
|
||||
httpURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@", _url.host]];
|
||||
|
||||
NSArray *proxies = CFBridgingRelease(CFNetworkCopyProxiesForAutoConfigurationScript((__bridge CFStringRef)script,(__bridge CFURLRef)httpURL, &err));
|
||||
if (!err && [proxies count] > 0) {
|
||||
NSDictionary *settings = [proxies objectAtIndex:0];
|
||||
NSString *proxyType = settings[(NSString *)kCFProxyTypeKey];
|
||||
[self _readProxySettingWithType:proxyType settings:settings];
|
||||
}
|
||||
[self _openConnection];
|
||||
}
|
||||
|
||||
- (void)_openConnection
|
||||
{
|
||||
[self _initializeStreams];
|
||||
|
||||
[self.inputStream scheduleInRunLoop:[NSRunLoop SR_networkRunLoop]
|
||||
forMode:NSDefaultRunLoopMode];
|
||||
//[self.outputStream scheduleInRunLoop:[NSRunLoop SR_networkRunLoop]
|
||||
// forMode:NSDefaultRunLoopMode];
|
||||
[self.outputStream open];
|
||||
[self.inputStream open];
|
||||
}
|
||||
|
||||
- (void)_initializeStreams
|
||||
{
|
||||
assert(_url.port.unsignedIntValue <= UINT32_MAX);
|
||||
uint32_t port = _url.port.unsignedIntValue;
|
||||
if (port == 0) {
|
||||
port = (_connectionRequiresSSL ? 443 : 80);
|
||||
}
|
||||
NSString *host = _url.host;
|
||||
|
||||
if (_httpProxyHost) {
|
||||
host = _httpProxyHost;
|
||||
port = (_httpProxyPort ?: 80);
|
||||
}
|
||||
|
||||
CFReadStreamRef readStream = NULL;
|
||||
CFWriteStreamRef writeStream = NULL;
|
||||
|
||||
SRDebugLog(@"ProxyConnect connect stream to %@:%u", host, port);
|
||||
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
|
||||
|
||||
self.outputStream = CFBridgingRelease(writeStream);
|
||||
self.inputStream = CFBridgingRelease(readStream);
|
||||
|
||||
if (_socksProxyHost) {
|
||||
SRDebugLog(@"ProxyConnect set sock property stream to %@:%u user %@ password %@", _socksProxyHost, _socksProxyPort, _socksProxyUsername, _socksProxyPassword);
|
||||
NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithCapacity:4];
|
||||
settings[NSStreamSOCKSProxyHostKey] = _socksProxyHost;
|
||||
if (_socksProxyPort) {
|
||||
settings[NSStreamSOCKSProxyPortKey] = @(_socksProxyPort);
|
||||
}
|
||||
if (_socksProxyUsername) {
|
||||
settings[NSStreamSOCKSProxyUserKey] = _socksProxyUsername;
|
||||
}
|
||||
if (_socksProxyPassword) {
|
||||
settings[NSStreamSOCKSProxyPasswordKey] = _socksProxyPassword;
|
||||
}
|
||||
[self.inputStream setProperty:settings forKey:NSStreamSOCKSProxyConfigurationKey];
|
||||
[self.outputStream setProperty:settings forKey:NSStreamSOCKSProxyConfigurationKey];
|
||||
}
|
||||
self.inputStream.delegate = self;
|
||||
self.outputStream.delegate = self;
|
||||
}
|
||||
|
||||
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode;
|
||||
{
|
||||
SRDebugLog(@"stream handleEvent %u", eventCode);
|
||||
switch (eventCode) {
|
||||
case NSStreamEventOpenCompleted: {
|
||||
if (aStream == self.inputStream) {
|
||||
if (_httpProxyHost) {
|
||||
[self _proxyDidConnect];
|
||||
} else {
|
||||
[self _didConnect];
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case NSStreamEventErrorOccurred: {
|
||||
[self _failWithError:aStream.streamError];
|
||||
} break;
|
||||
case NSStreamEventEndEncountered: {
|
||||
[self _failWithError:aStream.streamError];
|
||||
} break;
|
||||
case NSStreamEventHasBytesAvailable: {
|
||||
if (aStream == _inputStream) {
|
||||
[self _processInputStream];
|
||||
}
|
||||
} break;
|
||||
case NSStreamEventHasSpaceAvailable:
|
||||
case NSStreamEventNone:
|
||||
SRDebugLog(@"(default) %@", aStream);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_proxyDidConnect
|
||||
{
|
||||
SRDebugLog(@"Proxy Connected");
|
||||
uint32_t port = _url.port.unsignedIntValue;
|
||||
if (port == 0) {
|
||||
port = (_connectionRequiresSSL ? 443 : 80);
|
||||
}
|
||||
// Send HTTP CONNECT Request
|
||||
NSString *connectRequestStr = [NSString stringWithFormat:@"CONNECT %@:%u HTTP/1.1\r\nHost: %@\r\nConnection: keep-alive\r\nProxy-Connection: keep-alive\r\n\r\n", _url.host, port, _url.host];
|
||||
|
||||
NSData *message = [connectRequestStr dataUsingEncoding:NSUTF8StringEncoding];
|
||||
SRDebugLog(@"Proxy sending %@", connectRequestStr);
|
||||
|
||||
[self _writeData:message];
|
||||
}
|
||||
|
||||
///handles the incoming bytes and sending them to the proper processing method
|
||||
- (void)_processInputStream
|
||||
{
|
||||
NSMutableData *buf = [NSMutableData dataWithCapacity:SRDefaultBufferSize()];
|
||||
uint8_t *buffer = buf.mutableBytes;
|
||||
NSInteger length = [_inputStream read:buffer maxLength:SRDefaultBufferSize()];
|
||||
|
||||
if (length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL process = (_inputQueue.count == 0);
|
||||
[_inputQueue addObject:[NSData dataWithBytes:buffer length:length]];
|
||||
|
||||
if (process) {
|
||||
[self _dequeueInput];
|
||||
}
|
||||
}
|
||||
|
||||
// dequeue the incoming input so it is processed in order
|
||||
|
||||
- (void)_dequeueInput
|
||||
{
|
||||
while (_inputQueue.count > 0) {
|
||||
NSData *data = _inputQueue.firstObject;
|
||||
[_inputQueue removeObjectAtIndex:0];
|
||||
|
||||
// No need to process any data further, we got the full header data.
|
||||
if ([self _proxyProcessHTTPResponseWithData:data]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//handle checking the proxy connection status
|
||||
- (BOOL)_proxyProcessHTTPResponseWithData:(NSData *)data
|
||||
{
|
||||
if (_receivedHTTPHeaders == NULL) {
|
||||
_receivedHTTPHeaders = CFHTTPMessageCreateEmpty(NULL, NO);
|
||||
}
|
||||
|
||||
CFHTTPMessageAppendBytes(_receivedHTTPHeaders, (const UInt8 *)data.bytes, data.length);
|
||||
if (CFHTTPMessageIsHeaderComplete(_receivedHTTPHeaders)) {
|
||||
SRDebugLog(@"Finished reading headers %@", CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(_receivedHTTPHeaders)));
|
||||
[self _proxyHTTPHeadersDidFinish];
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)_proxyHTTPHeadersDidFinish
|
||||
{
|
||||
NSInteger responseCode = CFHTTPMessageGetResponseStatusCode(_receivedHTTPHeaders);
|
||||
|
||||
if (responseCode >= 299) {
|
||||
SRDebugLog(@"Connect to Proxy Request failed with response code %d", responseCode);
|
||||
NSError *error = SRHTTPErrorWithCodeDescription(responseCode, 2132,
|
||||
[NSString stringWithFormat:@"Received bad response code from proxy server: %d.",
|
||||
(int)responseCode]);
|
||||
[self _failWithError:error];
|
||||
return;
|
||||
}
|
||||
SRDebugLog(@"proxy connect return %d, call socket connect", responseCode);
|
||||
[self _didConnect];
|
||||
}
|
||||
|
||||
static NSTimeInterval const SRProxyConnectWriteTimeout = 5.0;
|
||||
|
||||
- (void)_writeData:(NSData *)data
|
||||
{
|
||||
const uint8_t * bytes = data.bytes;
|
||||
__block NSInteger timeout = (NSInteger)(SRProxyConnectWriteTimeout * 1000000); // wait timeout before giving up
|
||||
__weak typeof(self) wself = self;
|
||||
dispatch_async(_writeQueue, ^{
|
||||
__strong typeof(wself) sself = self;
|
||||
if (!sself) {
|
||||
return;
|
||||
}
|
||||
NSOutputStream *outStream = sself.outputStream;
|
||||
if (!outStream) {
|
||||
return;
|
||||
}
|
||||
while (![outStream hasSpaceAvailable]) {
|
||||
usleep(100); //wait until the socket is ready
|
||||
timeout -= 100;
|
||||
if (timeout < 0) {
|
||||
NSError *error = SRHTTPErrorWithCodeDescription(408, 2132, @"Proxy timeout");
|
||||
[sself _failWithError:error];
|
||||
} else if (outStream.streamError != nil) {
|
||||
[sself _failWithError:outStream.streamError];
|
||||
}
|
||||
}
|
||||
[outStream write:bytes maxLength:data.length];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
24
SweetParty/第三方库/SocketRocket/Internal/RunLoop/SRRunLoopThread.h
Executable file
24
SweetParty/第三方库/SocketRocket/Internal/RunLoop/SRRunLoopThread.h
Executable file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface SRRunLoopThread : NSThread
|
||||
|
||||
@property (nonatomic, strong, readonly) NSRunLoop *runLoop;
|
||||
|
||||
+ (instancetype)sharedThread;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
83
SweetParty/第三方库/SocketRocket/Internal/RunLoop/SRRunLoopThread.m
Executable file
83
SweetParty/第三方库/SocketRocket/Internal/RunLoop/SRRunLoopThread.m
Executable file
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRRunLoopThread.h"
|
||||
|
||||
@interface SRRunLoopThread ()
|
||||
{
|
||||
dispatch_group_t _waitGroup;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong, readwrite) NSRunLoop *runLoop;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SRRunLoopThread
|
||||
|
||||
+ (instancetype)sharedThread
|
||||
{
|
||||
static SRRunLoopThread *thread;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
thread = [[SRRunLoopThread alloc] init];
|
||||
thread.name = @"com.facebook.SocketRocket.NetworkThread";
|
||||
[thread start];
|
||||
});
|
||||
return thread;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_waitGroup = dispatch_group_create();
|
||||
dispatch_group_enter(_waitGroup);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)main
|
||||
{
|
||||
@autoreleasepool {
|
||||
_runLoop = [NSRunLoop currentRunLoop];
|
||||
dispatch_group_leave(_waitGroup);
|
||||
|
||||
// Add an empty run loop source to prevent runloop from spinning.
|
||||
CFRunLoopSourceContext sourceCtx = {
|
||||
.version = 0,
|
||||
.info = NULL,
|
||||
.retain = NULL,
|
||||
.release = NULL,
|
||||
.copyDescription = NULL,
|
||||
.equal = NULL,
|
||||
.hash = NULL,
|
||||
.schedule = NULL,
|
||||
.cancel = NULL,
|
||||
.perform = NULL
|
||||
};
|
||||
CFRunLoopSourceRef source = CFRunLoopSourceCreate(NULL, 0, &sourceCtx);
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
|
||||
CFRelease(source);
|
||||
|
||||
while ([_runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) {
|
||||
|
||||
}
|
||||
assert(NO);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSRunLoop *)runLoop;
|
||||
{
|
||||
dispatch_group_wait(_waitGroup, DISPATCH_TIME_FOREVER);
|
||||
return _runLoop;
|
||||
}
|
||||
|
||||
@end
|
||||
26
SweetParty/第三方库/SocketRocket/Internal/SRConstants.h
Executable file
26
SweetParty/第三方库/SocketRocket/Internal/SRConstants.h
Executable file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, SROpCode)
|
||||
{
|
||||
SROpCodeTextFrame = 0x1,
|
||||
SROpCodeBinaryFrame = 0x2,
|
||||
// 3-7 reserved.
|
||||
SROpCodeConnectionClose = 0x8,
|
||||
SROpCodePing = 0x9,
|
||||
SROpCodePong = 0xA,
|
||||
// B-F reserved.
|
||||
};
|
||||
|
||||
/**
|
||||
Default buffer size that is used for reading/writing to streams.
|
||||
*/
|
||||
extern size_t SRDefaultBufferSize(void);
|
||||
19
SweetParty/第三方库/SocketRocket/Internal/SRConstants.m
Executable file
19
SweetParty/第三方库/SocketRocket/Internal/SRConstants.m
Executable file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRConstants.h"
|
||||
|
||||
size_t SRDefaultBufferSize(void) {
|
||||
static size_t size;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
size = getpagesize();
|
||||
});
|
||||
return size;
|
||||
}
|
||||
28
SweetParty/第三方库/SocketRocket/Internal/Security/SRPinningSecurityPolicy.h
Executable file
28
SweetParty/第三方库/SocketRocket/Internal/Security/SRPinningSecurityPolicy.h
Executable file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//#import <SocketRocket/SRSecurityPolicy.h>
|
||||
#import "SRSecurityPolicy.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* NOTE: While publicly, SocketRocket does not support configuring the security policy with pinned certificates,
|
||||
* it is still possible to manually construct a security policy of this class. If you do this, note that you may
|
||||
* be open to MitM attacks, and we will not support any issues you may have. Dive at your own risk.
|
||||
*/
|
||||
@interface SRPinningSecurityPolicy : SRSecurityPolicy
|
||||
|
||||
- (instancetype)initWithCertificates:(NSArray *)pinnedCertificates;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
73
SweetParty/第三方库/SocketRocket/Internal/Security/SRPinningSecurityPolicy.m
Executable file
73
SweetParty/第三方库/SocketRocket/Internal/Security/SRPinningSecurityPolicy.m
Executable file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRPinningSecurityPolicy.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "SRLog.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface SRPinningSecurityPolicy ()
|
||||
|
||||
@property (nonatomic, copy, readonly) NSArray *pinnedCertificates;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SRPinningSecurityPolicy
|
||||
|
||||
- (instancetype)initWithCertificates:(NSArray *)pinnedCertificates
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
|
||||
// Do not validate certificate chain since we're pinning to specific certificates.
|
||||
self = [super initWithCertificateChainValidationEnabled:NO];
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
if (!self) { return self; }
|
||||
|
||||
if (pinnedCertificates.count == 0) {
|
||||
@throw [NSException exceptionWithName:@"Creating security policy failed."
|
||||
reason:@"Must specify at least one certificate when creating a pinning policy."
|
||||
userInfo:nil];
|
||||
}
|
||||
_pinnedCertificates = [pinnedCertificates copy];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain
|
||||
{
|
||||
SRDebugLog(@"Pinned cert count: %d", self.pinnedCertificates.count);
|
||||
NSUInteger requiredCertCount = self.pinnedCertificates.count;
|
||||
|
||||
NSUInteger validatedCertCount = 0;
|
||||
CFIndex serverCertCount = SecTrustGetCertificateCount(serverTrust);
|
||||
for (CFIndex i = 0; i < serverCertCount; i++) {
|
||||
SecCertificateRef cert = SecTrustGetCertificateAtIndex(serverTrust, i);
|
||||
NSData *data = CFBridgingRelease(SecCertificateCopyData(cert));
|
||||
for (id ref in self.pinnedCertificates) {
|
||||
SecCertificateRef trustedCert = (__bridge SecCertificateRef)ref;
|
||||
// TODO: (nlutsenko) Add caching, so we don't copy the data for every pinned cert all the time.
|
||||
NSData *trustedCertData = CFBridgingRelease(SecCertificateCopyData(trustedCert));
|
||||
if ([trustedCertData isEqualToData:data]) {
|
||||
validatedCertCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (requiredCertCount == validatedCertCount);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
20
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRError.h
Executable file
20
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRError.h
Executable file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern NSError *SRErrorWithDomainCodeDescription(NSString *domain, NSInteger code, NSString *description);
|
||||
extern NSError *SRErrorWithCodeDescription(NSInteger code, NSString *description);
|
||||
extern NSError *SRErrorWithCodeDescriptionUnderlyingError(NSInteger code, NSString *description, NSError *underlyingError);
|
||||
|
||||
extern NSError *SRHTTPErrorWithCodeDescription(NSInteger httpCode, NSInteger errorCode, NSString *description);
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
42
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRError.m
Executable file
42
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRError.m
Executable file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRError.h"
|
||||
|
||||
#import "SRWebSocket.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSError *SRErrorWithDomainCodeDescription(NSString *domain, NSInteger code, NSString *description)
|
||||
{
|
||||
return [NSError errorWithDomain:domain code:code userInfo:@{ NSLocalizedDescriptionKey: description }];
|
||||
}
|
||||
|
||||
NSError *SRErrorWithCodeDescription(NSInteger code, NSString *description)
|
||||
{
|
||||
return SRErrorWithDomainCodeDescription(SRWebSocketErrorDomain, code, description);
|
||||
}
|
||||
|
||||
NSError *SRErrorWithCodeDescriptionUnderlyingError(NSInteger code, NSString *description, NSError *underlyingError)
|
||||
{
|
||||
return [NSError errorWithDomain:SRWebSocketErrorDomain
|
||||
code:code
|
||||
userInfo:@{ NSLocalizedDescriptionKey: description,
|
||||
NSUnderlyingErrorKey: underlyingError }];
|
||||
}
|
||||
|
||||
NSError *SRHTTPErrorWithCodeDescription(NSInteger httpCode, NSInteger errorCode, NSString *description)
|
||||
{
|
||||
return [NSError errorWithDomain:SRWebSocketErrorDomain
|
||||
code:errorCode
|
||||
userInfo:@{ NSLocalizedDescriptionKey: description,
|
||||
SRHTTPResponseErrorKey: @(httpCode) }];
|
||||
}
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
20
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRHTTPConnectMessage.h
Executable file
20
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRHTTPConnectMessage.h
Executable file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern CFHTTPMessageRef SRHTTPConnectMessageCreate(NSURLRequest *request,
|
||||
NSString *securityKey,
|
||||
uint8_t webSocketProtocolVersion,
|
||||
NSArray<NSHTTPCookie *> *_Nullable cookies,
|
||||
NSArray<NSString *> *_Nullable requestedProtocols);
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
79
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRHTTPConnectMessage.m
Executable file
79
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRHTTPConnectMessage.m
Executable file
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRHTTPConnectMessage.h"
|
||||
|
||||
#import "SRURLUtilities.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
static NSString *_SRHTTPConnectMessageHost(NSURL *url)
|
||||
{
|
||||
NSString *host = url.host;
|
||||
if (url.port) {
|
||||
host = [host stringByAppendingFormat:@":%@", url.port];
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
CFHTTPMessageRef SRHTTPConnectMessageCreate(NSURLRequest *request,
|
||||
NSString *securityKey,
|
||||
uint8_t webSocketProtocolVersion,
|
||||
NSArray<NSHTTPCookie *> *_Nullable cookies,
|
||||
NSArray<NSString *> *_Nullable requestedProtocols)
|
||||
{
|
||||
NSURL *url = request.URL;
|
||||
|
||||
CFHTTPMessageRef message = CFHTTPMessageCreateRequest(NULL, CFSTR("GET"), (__bridge CFURLRef)url, kCFHTTPVersion1_1);
|
||||
|
||||
// Set host first so it defaults
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Host"), (__bridge CFStringRef)_SRHTTPConnectMessageHost(url));
|
||||
|
||||
NSMutableData *keyBytes = [[NSMutableData alloc] initWithLength:16];
|
||||
int result = SecRandomCopyBytes(kSecRandomDefault, keyBytes.length, keyBytes.mutableBytes);
|
||||
if (result != 0) {
|
||||
//TODO: (nlutsenko) Check if there was an error.
|
||||
}
|
||||
|
||||
// Apply cookies if any have been provided
|
||||
if (cookies) {
|
||||
NSDictionary<NSString *, NSString *> *messageCookies = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
|
||||
[messageCookies enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
|
||||
if (key.length && obj.length) {
|
||||
CFHTTPMessageSetHeaderFieldValue(message, (__bridge CFStringRef)key, (__bridge CFStringRef)obj);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
// set header for http basic auth
|
||||
NSString *basicAuthorizationString = SRBasicAuthorizationHeaderFromURL(url);
|
||||
if (basicAuthorizationString) {
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Authorization"), (__bridge CFStringRef)basicAuthorizationString);
|
||||
}
|
||||
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Upgrade"), CFSTR("websocket"));
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Connection"), CFSTR("Upgrade"));
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Sec-WebSocket-Key"), (__bridge CFStringRef)securityKey);
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Sec-WebSocket-Version"), (__bridge CFStringRef)@(webSocketProtocolVersion).stringValue);
|
||||
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Origin"), (__bridge CFStringRef)SRURLOrigin(url));
|
||||
|
||||
if (requestedProtocols.count) {
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Sec-WebSocket-Protocol"),
|
||||
(__bridge CFStringRef)[requestedProtocols componentsJoinedByString:@", "]);
|
||||
}
|
||||
|
||||
[request.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
||||
CFHTTPMessageSetHeaderFieldValue(message, (__bridge CFStringRef)key, (__bridge CFStringRef)obj);
|
||||
}];
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
19
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRHash.h
Executable file
19
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRHash.h
Executable file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern NSData *SRSHA1HashFromString(NSString *string);
|
||||
extern NSData *SRSHA1HashFromBytes(const char *bytes, size_t length);
|
||||
|
||||
extern NSString *SRBase64EncodedStringFromData(NSData *data);
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
43
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRHash.m
Executable file
43
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRHash.m
Executable file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRHash.h"
|
||||
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSData *SRSHA1HashFromString(NSString *string)
|
||||
{
|
||||
size_t length = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
return SRSHA1HashFromBytes(string.UTF8String, length);
|
||||
}
|
||||
|
||||
NSData *SRSHA1HashFromBytes(const char *bytes, size_t length)
|
||||
{
|
||||
uint8_t outputLength = CC_SHA1_DIGEST_LENGTH;
|
||||
unsigned char output[outputLength];
|
||||
CC_SHA1(bytes, (CC_LONG)length, output);
|
||||
|
||||
return [NSData dataWithBytes:output length:outputLength];
|
||||
}
|
||||
|
||||
NSString *SRBase64EncodedStringFromData(NSData *data)
|
||||
{
|
||||
if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
|
||||
return [data base64EncodedStringWithOptions:0];
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
return [data base64Encoding];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
20
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRLog.h
Executable file
20
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRLog.h
Executable file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// Uncomment this line to enable debug logging
|
||||
//#define SR_DEBUG_LOG_ENABLED
|
||||
|
||||
extern void SRErrorLog(NSString *format, ...);
|
||||
extern void SRDebugLog(NSString *format, ...);
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
33
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRLog.m
Executable file
33
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRLog.m
Executable file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRLog.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern void SRErrorLog(NSString *format, ...)
|
||||
{
|
||||
__block va_list arg_list;
|
||||
va_start (arg_list, format);
|
||||
|
||||
NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arg_list];
|
||||
|
||||
va_end(arg_list);
|
||||
|
||||
NSLog(@"[SocketRocket] %@", formattedString);
|
||||
}
|
||||
|
||||
extern void SRDebugLog(NSString *format, ...)
|
||||
{
|
||||
#ifdef SR_DEBUG_LOG_ENABLED
|
||||
SRErrorLog(tag, format);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
22
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRMutex.h
Executable file
22
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRMutex.h
Executable file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef __attribute__((capability("mutex"))) pthread_mutex_t *SRMutex;
|
||||
|
||||
extern SRMutex SRMutexInitRecursive(void);
|
||||
extern void SRMutexDestroy(SRMutex mutex);
|
||||
|
||||
extern void SRMutexLock(SRMutex mutex) __attribute__((acquire_capability(mutex)));
|
||||
extern void SRMutexUnlock(SRMutex mutex) __attribute__((release_capability(mutex)));
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
47
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRMutex.m
Executable file
47
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRMutex.m
Executable file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRMutex.h"
|
||||
|
||||
#import <pthread/pthread.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
SRMutex SRMutexInitRecursive(void)
|
||||
{
|
||||
pthread_mutex_t *mutex = malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutexattr_t attributes;
|
||||
|
||||
pthread_mutexattr_init(&attributes);
|
||||
pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(mutex, &attributes);
|
||||
pthread_mutexattr_destroy(&attributes);
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
void SRMutexDestroy(SRMutex mutex)
|
||||
{
|
||||
pthread_mutex_destroy(mutex);
|
||||
free(mutex);
|
||||
}
|
||||
|
||||
__attribute__((no_thread_safety_analysis))
|
||||
void SRMutexLock(SRMutex mutex)
|
||||
{
|
||||
pthread_mutex_lock(mutex);
|
||||
}
|
||||
|
||||
__attribute__((no_thread_safety_analysis))
|
||||
void SRMutexUnlock(SRMutex mutex)
|
||||
{
|
||||
pthread_mutex_unlock(mutex);
|
||||
}
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
16
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRRandom.h
Executable file
16
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRRandom.h
Executable file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern NSData *SRRandomData(NSUInteger length);
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
26
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRRandom.m
Executable file
26
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRRandom.m
Executable file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRRandom.h"
|
||||
|
||||
#import <Security/SecRandom.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSData *SRRandomData(NSUInteger length)
|
||||
{
|
||||
NSMutableData *data = [NSMutableData dataWithLength:length];
|
||||
int result = SecRandomCopyBytes(kSecRandomDefault, data.length, data.mutableBytes);
|
||||
if (result != 0) {
|
||||
[NSException raise:NSInternalInconsistencyException format:@"Failed to generate random bytes with OSStatus: %d", result];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
19
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRSIMDHelpers.h
Executable file
19
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRSIMDHelpers.h
Executable file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
Unmask bytes using XOR via SIMD.
|
||||
|
||||
@param bytes The bytes to unmask.
|
||||
@param length The number of bytes to unmask.
|
||||
@param maskKey The mask to XOR with MUST be of length sizeof(uint32_t).
|
||||
*/
|
||||
void SRMaskBytesSIMD(uint8_t *bytes, size_t length, uint8_t *maskKey);
|
||||
73
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRSIMDHelpers.m
Executable file
73
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRSIMDHelpers.m
Executable file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRSIMDHelpers.h"
|
||||
|
||||
typedef uint8_t uint8x32_t __attribute__((vector_size(32)));
|
||||
|
||||
static void SRMaskBytesManual(uint8_t *bytes, size_t length, uint8_t *maskKey) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
bytes[i] = bytes[i] ^ maskKey[i % sizeof(uint32_t)];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Right-shift the elements of a vector, circularly.
|
||||
|
||||
@param vector The vector to circular shift.
|
||||
@param by The number of elements to shift by.
|
||||
|
||||
@return A shifted vector.
|
||||
*/
|
||||
static uint8x32_t SRShiftVector(uint8x32_t vector, size_t by) {
|
||||
uint8x32_t vectorCopy = vector;
|
||||
by = by % _Alignof(uint8x32_t);
|
||||
|
||||
uint8_t *vectorPointer = (uint8_t *)&vector;
|
||||
uint8_t *vectorCopyPointer = (uint8_t *)&vectorCopy;
|
||||
|
||||
memmove(vectorPointer + by, vectorPointer, sizeof(vector) - by);
|
||||
memcpy(vectorPointer, vectorCopyPointer + (sizeof(vector) - by), by);
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
void SRMaskBytesSIMD(uint8_t *bytes, size_t length, uint8_t *maskKey) {
|
||||
size_t alignmentBytes = _Alignof(uint8x32_t) - ((uintptr_t)bytes % _Alignof(uint8x32_t));
|
||||
if (alignmentBytes == _Alignof(uint8x32_t)) {
|
||||
alignmentBytes = 0;
|
||||
}
|
||||
|
||||
// If the number of bytes that can be processed after aligning is
|
||||
// less than the number of bytes we can put into a vector,
|
||||
// then there's no work to do with SIMD, just call the manual version.
|
||||
if (alignmentBytes > length || (length - alignmentBytes) < sizeof(uint8x32_t)) {
|
||||
SRMaskBytesManual(bytes, length, maskKey);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t vectorLength = (length - alignmentBytes) / sizeof(uint8x32_t);
|
||||
size_t manualStartOffset = alignmentBytes + (vectorLength * sizeof(uint8x32_t));
|
||||
size_t manualLength = length - manualStartOffset;
|
||||
|
||||
uint8x32_t *vector = (uint8x32_t *)(bytes + alignmentBytes);
|
||||
uint8x32_t maskVector = { };
|
||||
|
||||
memset_pattern4(&maskVector, maskKey, sizeof(uint8x32_t));
|
||||
maskVector = SRShiftVector(maskVector, alignmentBytes);
|
||||
|
||||
SRMaskBytesManual(bytes, alignmentBytes, maskKey);
|
||||
|
||||
for (size_t vectorIndex = 0; vectorIndex < vectorLength; vectorIndex++) {
|
||||
vector[vectorIndex] = vector[vectorIndex] ^ maskVector;
|
||||
}
|
||||
|
||||
// Use the shifted mask for the final manual part.
|
||||
SRMaskBytesManual(bytes + manualStartOffset, manualLength, (uint8_t *) &maskVector);
|
||||
}
|
||||
26
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRURLUtilities.h
Executable file
26
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRURLUtilities.h
Executable file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// The origin isn't really applicable for a native application.
|
||||
// So instead, just map ws -> http and wss -> https.
|
||||
extern NSString *SRURLOrigin(NSURL *url);
|
||||
|
||||
extern BOOL SRURLRequiresSSL(NSURL *url);
|
||||
|
||||
// Extracts `user` and `password` from url (if available) into `Basic base64(user:password)`.
|
||||
extern NSString *_Nullable SRBasicAuthorizationHeaderFromURL(NSURL *url);
|
||||
|
||||
// Returns a valid value for `NSStreamNetworkServiceType` or `nil`.
|
||||
extern NSString *_Nullable SRStreamNetworkServiceTypeFromURLRequest(NSURLRequest *request);
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
77
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRURLUtilities.m
Executable file
77
SweetParty/第三方库/SocketRocket/Internal/Utilities/SRURLUtilities.m
Executable file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRURLUtilities.h"
|
||||
|
||||
#import "SRHash.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSString *SRURLOrigin(NSURL *url)
|
||||
{
|
||||
NSMutableString *origin = [NSMutableString string];
|
||||
|
||||
NSString *scheme = url.scheme.lowercaseString;
|
||||
if ([scheme isEqualToString:@"wss"]) {
|
||||
scheme = @"https";
|
||||
} else if ([scheme isEqualToString:@"ws"]) {
|
||||
scheme = @"http";
|
||||
}
|
||||
[origin appendFormat:@"%@://%@", scheme, url.host];
|
||||
|
||||
NSNumber *port = url.port;
|
||||
BOOL portIsDefault = (!port ||
|
||||
([scheme isEqualToString:@"http"] && port.integerValue == 80) ||
|
||||
([scheme isEqualToString:@"https"] && port.integerValue == 443));
|
||||
if (!portIsDefault) {
|
||||
[origin appendFormat:@":%@", port.stringValue];
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
|
||||
extern BOOL SRURLRequiresSSL(NSURL *url)
|
||||
{
|
||||
NSString *scheme = url.scheme.lowercaseString;
|
||||
return ([scheme isEqualToString:@"wss"] || [scheme isEqualToString:@"https"]);
|
||||
}
|
||||
|
||||
extern NSString *_Nullable SRBasicAuthorizationHeaderFromURL(NSURL *url)
|
||||
{
|
||||
NSData *data = [[NSString stringWithFormat:@"%@:%@", url.user, url.password] dataUsingEncoding:NSUTF8StringEncoding];
|
||||
return [NSString stringWithFormat:@"Basic %@", SRBase64EncodedStringFromData(data)];
|
||||
}
|
||||
|
||||
extern NSString *_Nullable SRStreamNetworkServiceTypeFromURLRequest(NSURLRequest *request)
|
||||
{
|
||||
NSString *networkServiceType = nil;
|
||||
switch (request.networkServiceType) {
|
||||
case NSURLNetworkServiceTypeDefault:
|
||||
break;
|
||||
case NSURLNetworkServiceTypeVoIP:
|
||||
networkServiceType = NSStreamNetworkServiceTypeVoIP;
|
||||
break;
|
||||
case NSURLNetworkServiceTypeVideo:
|
||||
networkServiceType = NSStreamNetworkServiceTypeVideo;
|
||||
break;
|
||||
case NSURLNetworkServiceTypeBackground:
|
||||
networkServiceType = NSStreamNetworkServiceTypeBackground;
|
||||
break;
|
||||
case NSURLNetworkServiceTypeVoice:
|
||||
networkServiceType = NSStreamNetworkServiceTypeVoice;
|
||||
break;
|
||||
#if (__MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 || __TV_OS_VERSION_MAX_ALLOWED >= 100000 || __WATCH_OS_VERSION_MAX_ALLOWED >= 30000)
|
||||
case NSURLNetworkServiceTypeCallSignaling:
|
||||
networkServiceType = NSStreamNetworkServiceTypeCallSignaling;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return networkServiceType;
|
||||
}
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
27
SweetParty/第三方库/SocketRocket/NSRunLoop+SRWebSocket.h
Executable file
27
SweetParty/第三方库/SocketRocket/NSRunLoop+SRWebSocket.h
Executable file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NSRunLoop (SRWebSocket)
|
||||
|
||||
/**
|
||||
Default run loop that will be used to schedule all instances of `SRWebSocket`.
|
||||
|
||||
@return An instance of `NSRunLoop`.
|
||||
*/
|
||||
+ (NSRunLoop *)SR_networkRunLoop;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
27
SweetParty/第三方库/SocketRocket/NSRunLoop+SRWebSocket.m
Executable file
27
SweetParty/第三方库/SocketRocket/NSRunLoop+SRWebSocket.m
Executable file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "NSRunLoop+SRWebSocket.h"
|
||||
#import "NSRunLoop+SRWebSocketPrivate.h"
|
||||
|
||||
#import "SRRunLoopThread.h"
|
||||
|
||||
// Required for object file to always be linked.
|
||||
void import_NSRunLoop_SRWebSocket() { }
|
||||
|
||||
@implementation NSRunLoop (SRWebSocket)
|
||||
|
||||
+ (NSRunLoop *)SR_networkRunLoop
|
||||
{
|
||||
return [SRRunLoopThread sharedThread].runLoop;
|
||||
}
|
||||
|
||||
@end
|
||||
38
SweetParty/第三方库/SocketRocket/NSURLRequest+SRWebSocket.h
Executable file
38
SweetParty/第三方库/SocketRocket/NSURLRequest+SRWebSocket.h
Executable file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NSURLRequest (SRWebSocket)
|
||||
|
||||
/**
|
||||
An array of pinned `SecCertificateRef` SSL certificates that `SRWebSocket` will use for validation.
|
||||
*/
|
||||
@property (nullable, nonatomic, copy, readonly) NSArray *SR_SSLPinnedCertificates
|
||||
DEPRECATED_MSG_ATTRIBUTE("Using pinned certificates is neither secure nor supported in SocketRocket, "
|
||||
"and leads to security issues. Please use a proper, trust chain validated certificate.");
|
||||
|
||||
@end
|
||||
|
||||
@interface NSMutableURLRequest (SRWebSocket)
|
||||
|
||||
/**
|
||||
An array of pinned `SecCertificateRef` SSL certificates that `SRWebSocket` will use for validation.
|
||||
*/
|
||||
@property (nullable, nonatomic, copy) NSArray *SR_SSLPinnedCertificates
|
||||
DEPRECATED_MSG_ATTRIBUTE("Using pinned certificates is neither secure nor supported in SocketRocket, "
|
||||
"and leads to security issues. Please use a proper, trust chain validated certificate.");
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
42
SweetParty/第三方库/SocketRocket/NSURLRequest+SRWebSocket.m
Executable file
42
SweetParty/第三方库/SocketRocket/NSURLRequest+SRWebSocket.m
Executable file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "NSURLRequest+SRWebSocket.h"
|
||||
#import "NSURLRequest+SRWebSocketPrivate.h"
|
||||
|
||||
// Required for object file to always be linked.
|
||||
void import_NSURLRequest_SRWebSocket() { }
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
static NSString *const SRSSLPinnnedCertificatesKey = @"SocketRocket_SSLPinnedCertificates";
|
||||
|
||||
@implementation NSURLRequest (SRWebSocket)
|
||||
|
||||
- (nullable NSArray *)SR_SSLPinnedCertificates
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSMutableURLRequest (SRWebSocket)
|
||||
|
||||
- (void)setSR_SSLPinnedCertificates:(nullable NSArray *)SR_SSLPinnedCertificates
|
||||
{
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"Using pinned certificates is neither secure nor supported in SocketRocket, "
|
||||
"and leads to security issues. Please use a proper, trust chain validated certificate."];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
26
SweetParty/第三方库/SocketRocket/Resources/Info.plist
Executable file
26
SweetParty/第三方库/SocketRocket/Resources/Info.plist
Executable file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
72
SweetParty/第三方库/SocketRocket/SRSecurityPolicy.h
Executable file
72
SweetParty/第三方库/SocketRocket/SRSecurityPolicy.h
Executable file
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Security/Security.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface SRSecurityPolicy : NSObject
|
||||
|
||||
/**
|
||||
A default `SRSecurityPolicy` implementation specifies socket security and
|
||||
validates the certificate chain.
|
||||
|
||||
Use a subclass of `SRSecurityPolicy` for more fine grained customization.
|
||||
*/
|
||||
+ (instancetype)defaultPolicy;
|
||||
|
||||
/**
|
||||
Specifies socket security and provider certificate pinning, disregarding certificate
|
||||
chain validation.
|
||||
|
||||
@param pinnedCertificates Array of `SecCertificateRef` SSL certificates to use for validation.
|
||||
*/
|
||||
+ (instancetype)pinnningPolicyWithCertificates:(NSArray *)pinnedCertificates
|
||||
DEPRECATED_MSG_ATTRIBUTE("Using pinned certificates is neither secure nor supported in SocketRocket, "
|
||||
"and leads to security issues. Please use a proper, trust chain validated certificate.");
|
||||
|
||||
/**
|
||||
Specifies socket security and optional certificate chain validation.
|
||||
|
||||
@param enabled Whether or not to validate the SSL certificate chain. If you
|
||||
are considering using this method because your certificate was not issued by a
|
||||
recognized certificate authority, consider using `pinningPolicyWithCertificates` instead.
|
||||
*/
|
||||
- (instancetype)initWithCertificateChainValidationEnabled:(BOOL)enabled
|
||||
DEPRECATED_MSG_ATTRIBUTE("Disabling certificate chain validation is unsafe. "
|
||||
"Please use a proper Certificate Authority to issue your TLS certificates.")
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
Updates all the security options for input and output streams, for example you
|
||||
can set your socket security level here.
|
||||
|
||||
@param stream Stream to update the options in.
|
||||
*/
|
||||
- (void)updateSecurityOptionsInStream:(NSStream *)stream;
|
||||
|
||||
/**
|
||||
Whether or not the specified server trust should be accepted, based on the security policy.
|
||||
|
||||
This method should be used when responding to an authentication challenge from
|
||||
a server. In the default implemenation, no further validation is done here, but
|
||||
you're free to override it in a subclass. See `SRPinningSecurityPolicy.h` for
|
||||
an example.
|
||||
|
||||
@param serverTrust The X.509 certificate trust of the server.
|
||||
@param domain The domain of serverTrust.
|
||||
|
||||
@return Whether or not to trust the server.
|
||||
*/
|
||||
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
75
SweetParty/第三方库/SocketRocket/SRSecurityPolicy.m
Executable file
75
SweetParty/第三方库/SocketRocket/SRSecurityPolicy.m
Executable file
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// Copyright (c) 2016-present, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import "SRSecurityPolicy.h"
|
||||
#import "SRPinningSecurityPolicy.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface SRSecurityPolicy ()
|
||||
|
||||
@property (nonatomic, assign, readonly) BOOL certificateChainValidationEnabled;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SRSecurityPolicy
|
||||
|
||||
+ (instancetype)defaultPolicy
|
||||
{
|
||||
return [self new];
|
||||
}
|
||||
|
||||
+ (instancetype)pinnningPolicyWithCertificates:(NSArray *)pinnedCertificates
|
||||
{
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"Using pinned certificates is neither secure nor supported in SocketRocket, "
|
||||
"and leads to security issues. Please use a proper, trust chain validated certificate."];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCertificateChainValidationEnabled:(BOOL)enabled
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) { return self; }
|
||||
|
||||
_certificateChainValidationEnabled = enabled;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
|
||||
return [self initWithCertificateChainValidationEnabled:YES];
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
- (void)updateSecurityOptionsInStream:(NSStream *)stream
|
||||
{
|
||||
// Enforce TLS 1.2
|
||||
[stream setProperty:(__bridge id)CFSTR("kCFStreamSocketSecurityLevelTLSv1_2") forKey:(__bridge id)kCFStreamPropertySocketSecurityLevel];
|
||||
|
||||
// Validate certificate chain for this stream if enabled.
|
||||
NSDictionary<NSString *, id> *sslOptions = @{ (__bridge NSString *)kCFStreamSSLValidatesCertificateChain : @(self.certificateChainValidationEnabled) };
|
||||
[stream setProperty:sslOptions forKey:(__bridge NSString *)kCFStreamPropertySSLSettings];
|
||||
}
|
||||
|
||||
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain
|
||||
{
|
||||
// No further evaluation happens in the default policy.
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
417
SweetParty/第三方库/SocketRocket/SRWebSocket.h
Executable file
417
SweetParty/第三方库/SocketRocket/SRWebSocket.h
Executable file
@@ -0,0 +1,417 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSInteger, SRReadyState) {
|
||||
SR_CONNECTING = 0,
|
||||
SR_OPEN = 1,
|
||||
SR_CLOSING = 2,
|
||||
SR_CLOSED = 3,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, SRStatusCode) {
|
||||
// 0-999: Reserved and not used.
|
||||
SRStatusCodeNormal = 1000,
|
||||
SRStatusCodeGoingAway = 1001,
|
||||
SRStatusCodeProtocolError = 1002,
|
||||
SRStatusCodeUnhandledType = 1003,
|
||||
// 1004 reserved.
|
||||
SRStatusNoStatusReceived = 1005,
|
||||
SRStatusCodeAbnormal = 1006,
|
||||
SRStatusCodeInvalidUTF8 = 1007,
|
||||
SRStatusCodePolicyViolated = 1008,
|
||||
SRStatusCodeMessageTooBig = 1009,
|
||||
SRStatusCodeMissingExtension = 1010,
|
||||
SRStatusCodeInternalError = 1011,
|
||||
SRStatusCodeServiceRestart = 1012,
|
||||
SRStatusCodeTryAgainLater = 1013,
|
||||
// 1014: Reserved for future use by the WebSocket standard.
|
||||
SRStatusCodeTLSHandshake = 1015,
|
||||
// 1016-1999: Reserved for future use by the WebSocket standard.
|
||||
// 2000-2999: Reserved for use by WebSocket extensions.
|
||||
// 3000-3999: Available for use by libraries and frameworks. May not be used by applications. Available for registration at the IANA via first-come, first-serve.
|
||||
// 4000-4999: Available for use by applications.
|
||||
};
|
||||
|
||||
@class SRWebSocket;
|
||||
@class SRSecurityPolicy;
|
||||
|
||||
/**
|
||||
Error domain used for errors reported by SRWebSocket.
|
||||
*/
|
||||
extern NSString *const SRWebSocketErrorDomain;
|
||||
|
||||
/**
|
||||
Key used for HTTP status code if bad response was received from the server.
|
||||
*/
|
||||
extern NSString *const SRHTTPResponseErrorKey;
|
||||
|
||||
@protocol SRWebSocketDelegate;
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - SRWebSocket
|
||||
///--------------------------------------
|
||||
|
||||
/**
|
||||
A `SRWebSocket` object lets you connect, send and receive data to a remote Web Socket.
|
||||
*/
|
||||
@interface SRWebSocket : NSObject <NSStreamDelegate>
|
||||
|
||||
/**
|
||||
The delegate of the web socket.
|
||||
|
||||
The web socket delegate is notified on all state changes that happen to the web socket.
|
||||
*/
|
||||
@property (nonatomic, weak) id <SRWebSocketDelegate> delegate;
|
||||
|
||||
/**
|
||||
A dispatch queue for scheduling the delegate calls. The queue doesn't need be a serial queue.
|
||||
|
||||
If `nil` and `delegateOperationQueue` is `nil`, the socket uses main queue for performing all delegate method calls.
|
||||
*/
|
||||
@property (nullable, nonatomic, strong) dispatch_queue_t delegateDispatchQueue;
|
||||
|
||||
/**
|
||||
An operation queue for scheduling the delegate calls.
|
||||
|
||||
If `nil` and `delegateOperationQueue` is `nil`, the socket uses main queue for performing all delegate method calls.
|
||||
*/
|
||||
@property (nullable, nonatomic, strong) NSOperationQueue *delegateOperationQueue;
|
||||
|
||||
/**
|
||||
Current ready state of the socket. Default: `SR_CONNECTING`.
|
||||
|
||||
This property is Key-Value Observable and fully thread-safe.
|
||||
*/
|
||||
@property (atomic, assign, readonly) SRReadyState readyState;
|
||||
|
||||
/**
|
||||
An instance of `NSURL` that this socket connects to.
|
||||
*/
|
||||
@property (nullable, nonatomic, strong, readonly) NSURL *url;
|
||||
|
||||
/**
|
||||
All HTTP headers that were received by socket or `nil` if none were received so far.
|
||||
*/
|
||||
@property (nullable, nonatomic, assign, readonly) CFHTTPMessageRef receivedHTTPHeaders;
|
||||
|
||||
/**
|
||||
Array of `NSHTTPCookie` cookies to apply to the connection.
|
||||
*/
|
||||
@property (nullable, nonatomic, copy) NSArray<NSHTTPCookie *> *requestCookies;
|
||||
|
||||
/**
|
||||
The negotiated web socket protocol or `nil` if handshake did not yet complete.
|
||||
*/
|
||||
@property (nullable, nonatomic, copy, readonly) NSString *protocol;
|
||||
|
||||
/**
|
||||
A boolean value indicating whether this socket will allow connection without SSL trust chain evaluation.
|
||||
For DEBUG builds this flag is ignored, and SSL connections are allowed regardless of the certificate trust configuration
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) BOOL allowsUntrustedSSLCertificates;
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - Constructors
|
||||
///--------------------------------------
|
||||
|
||||
/**
|
||||
Initializes a web socket with a given `NSURLRequest`.
|
||||
|
||||
@param request Request to initialize with.
|
||||
*/
|
||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request;
|
||||
|
||||
/**
|
||||
Initializes a web socket with a given `NSURLRequest`, specifying a transport security policy (e.g. SSL configuration).
|
||||
|
||||
@param request Request to initialize with.
|
||||
@param securityPolicy Policy object describing transport security behavior.
|
||||
*/
|
||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request securityPolicy:(SRSecurityPolicy *)securityPolicy;
|
||||
|
||||
/**
|
||||
Initializes a web socket with a given `NSURLRequest` and list of sub-protocols.
|
||||
|
||||
@param request Request to initialize with.
|
||||
@param protocols An array of strings that turn into `Sec-WebSocket-Protocol`. Default: `nil`.
|
||||
*/
|
||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(nullable NSArray<NSString *> *)protocols;
|
||||
|
||||
/**
|
||||
Initializes a web socket with a given `NSURLRequest`, list of sub-protocols and whether untrusted SSL certificates are allowed.
|
||||
|
||||
@param request Request to initialize with.
|
||||
@param protocols An array of strings that turn into `Sec-WebSocket-Protocol`. Default: `nil`.
|
||||
@param allowsUntrustedSSLCertificates Boolean value indicating whether untrusted SSL certificates are allowed. Default: `false`.
|
||||
*/
|
||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(nullable NSArray<NSString *> *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates
|
||||
DEPRECATED_MSG_ATTRIBUTE("Disabling certificate chain validation is unsafe. "
|
||||
"Please use a proper Certificate Authority to issue your TLS certificates.");
|
||||
|
||||
/**
|
||||
Initializes a web socket with a given `NSURLRequest`, list of sub-protocols and whether untrusted SSL certificates are allowed.
|
||||
|
||||
@param request Request to initialize with.
|
||||
@param protocols An array of strings that turn into `Sec-WebSocket-Protocol`. Default: `nil`.
|
||||
@param securityPolicy Policy object describing transport security behavior.
|
||||
*/
|
||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(nullable NSArray<NSString *> *)protocols securityPolicy:(SRSecurityPolicy *)securityPolicy NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
Initializes a web socket with a given `NSURL`.
|
||||
|
||||
@param url URL to initialize with.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url;
|
||||
|
||||
/**
|
||||
Initializes a web socket with a given `NSURL` and list of sub-protocols.
|
||||
|
||||
@param url URL to initialize with.
|
||||
@param protocols An array of strings that turn into `Sec-WebSocket-Protocol`. Default: `nil`.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url protocols:(nullable NSArray<NSString *> *)protocols;
|
||||
|
||||
/**
|
||||
Initializes a web socket with a given `NSURL`, specifying a transport security policy (e.g. SSL configuration).
|
||||
|
||||
@param url URL to initialize with.
|
||||
@param securityPolicy Policy object describing transport security behavior.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url securityPolicy:(SRSecurityPolicy *)securityPolicy;
|
||||
|
||||
/**
|
||||
Initializes a web socket with a given `NSURL`, list of sub-protocols and whether untrusted SSL certificates are allowed.
|
||||
|
||||
@param url URL to initialize with.
|
||||
@param protocols An array of strings that turn into `Sec-WebSocket-Protocol`. Default: `nil`.
|
||||
@param allowsUntrustedSSLCertificates Boolean value indicating whether untrusted SSL certificates are allowed. Default: `false`.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url protocols:(nullable NSArray<NSString *> *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates
|
||||
DEPRECATED_MSG_ATTRIBUTE("Disabling certificate chain validation is unsafe. "
|
||||
"Please use a proper Certificate Authority to issue your TLS certificates.");
|
||||
|
||||
/**
|
||||
Unavailable initializer. Please use any other initializer.
|
||||
*/
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Unavailable constructor. Please use any other initializer.
|
||||
*/
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - Schedule
|
||||
///--------------------------------------
|
||||
|
||||
/**
|
||||
Schedules a received on a given run loop in a given mode.
|
||||
By default, a web socket will schedule itself on `+[NSRunLoop SR_networkRunLoop]` using `NSDefaultRunLoopMode`.
|
||||
|
||||
@param runLoop The run loop on which to schedule the receiver.
|
||||
@param mode The mode for the run loop.
|
||||
*/
|
||||
- (void)scheduleInRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode NS_SWIFT_NAME(schedule(in:forMode:));
|
||||
|
||||
/**
|
||||
Removes the receiver from a given run loop running in a given mode.
|
||||
|
||||
@param runLoop The run loop on which the receiver was scheduled.
|
||||
@param mode The mode for the run loop.
|
||||
*/
|
||||
- (void)unscheduleFromRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode NS_SWIFT_NAME(unschedule(from:forMode:));
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - Open / Close
|
||||
///--------------------------------------
|
||||
|
||||
/**
|
||||
Opens web socket, which will trigger connection, authentication and start receiving/sending events.
|
||||
An instance of `SRWebSocket` is intended for one-time-use only. This method should be called once and only once.
|
||||
*/
|
||||
- (void)open;
|
||||
|
||||
/**
|
||||
Closes a web socket using `SRStatusCodeNormal` code and no reason.
|
||||
*/
|
||||
- (void)close;
|
||||
|
||||
/**
|
||||
Closes a web socket using a given code and reason.
|
||||
|
||||
@param code Code to close the socket with.
|
||||
@param reason Reason to send to the server or `nil`.
|
||||
*/
|
||||
- (void)closeWithCode:(NSInteger)code reason:(nullable NSString *)reason;
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark Send
|
||||
///--------------------------------------
|
||||
|
||||
/**
|
||||
Send a UTF-8 string or binary data to the server.
|
||||
|
||||
@param message UTF-8 String or Data to send.
|
||||
|
||||
@deprecated Please use `sendString:` or `sendData` instead.
|
||||
*/
|
||||
- (void)send:(nullable id)message __attribute__((deprecated("Please use `sendString:error:` or `sendData:error:` instead.")));
|
||||
|
||||
/**
|
||||
Send a UTF-8 String to the server.
|
||||
|
||||
@param string String to send.
|
||||
@param error On input, a pointer to variable for an `NSError` object.
|
||||
If an error occurs, this pointer is set to an `NSError` object containing information about the error.
|
||||
You may specify `nil` to ignore the error information.
|
||||
|
||||
@return `YES` if the string was scheduled to send, otherwise - `NO`.
|
||||
*/
|
||||
- (BOOL)sendString:(NSString *)string error:(NSError **)error NS_SWIFT_NAME(send(string:));
|
||||
|
||||
/**
|
||||
Send binary data to the server.
|
||||
|
||||
@param data Data to send.
|
||||
@param error On input, a pointer to variable for an `NSError` object.
|
||||
If an error occurs, this pointer is set to an `NSError` object containing information about the error.
|
||||
You may specify `nil` to ignore the error information.
|
||||
|
||||
@return `YES` if the string was scheduled to send, otherwise - `NO`.
|
||||
*/
|
||||
- (BOOL)sendData:(nullable NSData *)data error:(NSError **)error NS_SWIFT_NAME(send(data:));
|
||||
|
||||
/**
|
||||
Send binary data to the server, without making a defensive copy of it first.
|
||||
|
||||
@param data Data to send.
|
||||
@param error On input, a pointer to variable for an `NSError` object.
|
||||
If an error occurs, this pointer is set to an `NSError` object containing information about the error.
|
||||
You may specify `nil` to ignore the error information.
|
||||
|
||||
@return `YES` if the string was scheduled to send, otherwise - `NO`.
|
||||
*/
|
||||
- (BOOL)sendDataNoCopy:(nullable NSData *)data error:(NSError **)error NS_SWIFT_NAME(send(dataNoCopy:));
|
||||
|
||||
/**
|
||||
Send Ping message to the server with optional data.
|
||||
|
||||
@param data Instance of `NSData` or `nil`.
|
||||
@param error On input, a pointer to variable for an `NSError` object.
|
||||
If an error occurs, this pointer is set to an `NSError` object containing information about the error.
|
||||
You may specify `nil` to ignore the error information.
|
||||
|
||||
@return `YES` if the string was scheduled to send, otherwise - `NO`.
|
||||
*/
|
||||
- (BOOL)sendPing:(nullable NSData *)data error:(NSError **)error NS_SWIFT_NAME(sendPing(_:));
|
||||
|
||||
@end
|
||||
|
||||
///--------------------------------------
|
||||
#pragma mark - SRWebSocketDelegate
|
||||
///--------------------------------------
|
||||
|
||||
/**
|
||||
The `SRWebSocketDelegate` protocol describes the methods that `SRWebSocket` objects
|
||||
call on their delegates to handle status and messsage events.
|
||||
*/
|
||||
@protocol SRWebSocketDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
#pragma mark Receive Messages
|
||||
|
||||
/**
|
||||
Called when any message was received from a web socket.
|
||||
This method is suboptimal and might be deprecated in a future release.
|
||||
|
||||
@param webSocket An instance of `SRWebSocket` that received a message.
|
||||
@param message Received message. Either a `String` or `NSData`.
|
||||
*/
|
||||
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;
|
||||
|
||||
/**
|
||||
Called when a frame was received from a web socket.
|
||||
|
||||
@param webSocket An instance of `SRWebSocket` that received a message.
|
||||
@param string Received text in a form of UTF-8 `String`.
|
||||
*/
|
||||
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithString:(NSString *)string;
|
||||
|
||||
/**
|
||||
Called when a frame was received from a web socket.
|
||||
|
||||
@param webSocket An instance of `SRWebSocket` that received a message.
|
||||
@param data Received data in a form of `NSData`.
|
||||
*/
|
||||
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessageWithData:(NSData *)data;
|
||||
|
||||
#pragma mark Status & Connection
|
||||
|
||||
/**
|
||||
Called when a given web socket was open and authenticated.
|
||||
|
||||
@param webSocket An instance of `SRWebSocket` that was open.
|
||||
*/
|
||||
- (void)webSocketDidOpen:(SRWebSocket *)webSocket;
|
||||
|
||||
/**
|
||||
Called when a given web socket encountered an error.
|
||||
|
||||
@param webSocket An instance of `SRWebSocket` that failed with an error.
|
||||
@param error An instance of `NSError`.
|
||||
*/
|
||||
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;
|
||||
|
||||
/**
|
||||
Called when a given web socket was closed.
|
||||
|
||||
@param webSocket An instance of `SRWebSocket` that was closed.
|
||||
@param code Code reported by the server.
|
||||
@param reason Reason in a form of a String that was reported by the server or `nil`.
|
||||
@param wasClean Boolean value indicating whether a socket was closed in a clean state.
|
||||
*/
|
||||
- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(nullable NSString *)reason wasClean:(BOOL)wasClean;
|
||||
|
||||
/**
|
||||
Called on receive of a ping message from the server.
|
||||
|
||||
@param webSocket An instance of `SRWebSocket` that received a ping frame.
|
||||
@param data Payload that was received or `nil` if there was no payload.
|
||||
*/
|
||||
- (void)webSocket:(SRWebSocket *)webSocket didReceivePingWithData:(nullable NSData *)data;
|
||||
|
||||
/**
|
||||
Called when a pong data was received in response to ping.
|
||||
|
||||
@param webSocket An instance of `SRWebSocket` that received a pong frame.
|
||||
@param pongData Payload that was received or `nil` if there was no payload.
|
||||
*/
|
||||
- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(nullable NSData *)pongData;
|
||||
|
||||
/**
|
||||
Sent before reporting a text frame to be able to configure if it shuold be convert to a UTF-8 String or passed as `NSData`.
|
||||
If the method is not implemented - it will always convert text frames to String.
|
||||
|
||||
@param webSocket An instance of `SRWebSocket` that received a text frame.
|
||||
|
||||
@return `YES` if text frame should be converted to UTF-8 String, otherwise - `NO`. Default: `YES`.
|
||||
*/
|
||||
- (BOOL)webSocketShouldConvertTextFrameToString:(SRWebSocket *)webSocket NS_SWIFT_NAME(webSocketShouldConvertTextFrameToString(_:));
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
1628
SweetParty/第三方库/SocketRocket/SRWebSocket.m
Executable file
1628
SweetParty/第三方库/SocketRocket/SRWebSocket.m
Executable file
File diff suppressed because it is too large
Load Diff
19
SweetParty/第三方库/SocketRocket/SocketRocket.h
Executable file
19
SweetParty/第三方库/SocketRocket/SocketRocket.h
Executable file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright 2012 Square Inc.
|
||||
// Portions Copyright (c) 2016-present, Facebook, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
|
||||
//#import <SocketRocket/NSRunLoop+SRWebSocket.h>
|
||||
#import "NSRunLoop+SRWebSocket.h"
|
||||
#import "NSURLRequest+SRWebSocket.h"
|
||||
#import "SRSecurityPolicy.h"
|
||||
#import "SRWebSocket.h"
|
||||
//#import <SocketRocket/NSURLRequest+SRWebSocket.h>
|
||||
//#import <SocketRocket/SRSecurityPolicy.h>
|
||||
//#import <SocketRocket/SRWebSocket.h>
|
||||
Reference in New Issue
Block a user