Backed out changeset 183744d2415b
Reviewed By: nicklockwood Differential Revision: D3053067 fb-gh-sync-id: de20718b5bf82eae433637847143e32b7a4bb216 shipit-source-id: de20718b5bf82eae433637847143e32b7a4bb216
This commit is contained in:
parent
fe7fcdb227
commit
cc2068e201
|
@ -60,19 +60,17 @@ extern NSString *const RCTSRHTTPResponseErrorKey;
|
||||||
@property (nonatomic, readonly, copy) NSString *protocol;
|
@property (nonatomic, readonly, copy) NSString *protocol;
|
||||||
|
|
||||||
// Protocols should be an array of strings that turn into Sec-WebSocket-Protocol.
|
// Protocols should be an array of strings that turn into Sec-WebSocket-Protocol.
|
||||||
// options can contain a custom "origin" NSString
|
- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols NS_DESIGNATED_INITIALIZER;
|
||||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols options:(NSDictionary<NSString *, NSString *> *)options NS_DESIGNATED_INITIALIZER;
|
|
||||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request;
|
- (instancetype)initWithURLRequest:(NSURLRequest *)request;
|
||||||
|
|
||||||
// Some helper constructors.
|
// Some helper constructors.
|
||||||
- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray<NSString *> *)protocols options:(NSDictionary<NSString *, NSString *> *)options;
|
|
||||||
- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray<NSString *> *)protocols;
|
- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray<NSString *> *)protocols;
|
||||||
- (instancetype)initWithURL:(NSURL *)url;
|
- (instancetype)initWithURL:(NSURL *)url;
|
||||||
|
|
||||||
// Delegate queue will be dispatch_main_queue by default.
|
// Delegate queue will be dispatch_main_queue by default.
|
||||||
// You cannot set both OperationQueue and dispatch_queue.
|
// You cannot set both OperationQueue and dispatch_queue.
|
||||||
- (void)setDelegateOperationQueue:(NSOperationQueue*) queue;
|
- (void)setDelegateOperationQueue:(NSOperationQueue *)queue;
|
||||||
- (void)setDelegateDispatchQueue:(dispatch_queue_t) queue;
|
- (void)setDelegateDispatchQueue:(dispatch_queue_t)queue;
|
||||||
|
|
||||||
// By default, it will schedule itself on +[NSRunLoop RCTSR_networkRunLoop] using defaultModes.
|
// By default, it will schedule itself on +[NSRunLoop RCTSR_networkRunLoop] using defaultModes.
|
||||||
- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;
|
- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;
|
||||||
|
|
|
@ -234,7 +234,6 @@ typedef void (^data_callback)(RCTSRWebSocket *webSocket, NSData *data);
|
||||||
__strong RCTSRWebSocket *_selfRetain;
|
__strong RCTSRWebSocket *_selfRetain;
|
||||||
|
|
||||||
NSArray<NSString *> *_requestedProtocols;
|
NSArray<NSString *> *_requestedProtocols;
|
||||||
NSDictionary<NSString *, NSString *> *_requestedOptions;
|
|
||||||
RCTSRIOConsumerPool *_consumerPool;
|
RCTSRIOConsumerPool *_consumerPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +244,7 @@ static __strong NSData *CRLFCRLF;
|
||||||
CRLFCRLF = [[NSData alloc] initWithBytes:"\r\n\r\n" length:4];
|
CRLFCRLF = [[NSData alloc] initWithBytes:"\r\n\r\n" length:4];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols options:(NSDictionary<NSString *, NSString *> *)options
|
- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols
|
||||||
{
|
{
|
||||||
RCTAssertParam(request);
|
RCTAssertParam(request);
|
||||||
|
|
||||||
|
@ -254,7 +253,6 @@ static __strong NSData *CRLFCRLF;
|
||||||
_urlRequest = request;
|
_urlRequest = request;
|
||||||
|
|
||||||
_requestedProtocols = [protocols copy];
|
_requestedProtocols = [protocols copy];
|
||||||
_requestedOptions = [options copy];
|
|
||||||
|
|
||||||
[self _RCTSR_commonInit];
|
[self _RCTSR_commonInit];
|
||||||
}
|
}
|
||||||
|
@ -265,20 +263,15 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||||
|
|
||||||
- (instancetype)initWithURLRequest:(NSURLRequest *)request;
|
- (instancetype)initWithURLRequest:(NSURLRequest *)request;
|
||||||
{
|
{
|
||||||
return [self initWithURLRequest:request protocols:nil options: nil];
|
return [self initWithURLRequest:request protocols:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithURL:(NSURL *)URL;
|
- (instancetype)initWithURL:(NSURL *)URL;
|
||||||
{
|
{
|
||||||
return [self initWithURL:URL protocols:nil options:nil];
|
return [self initWithURL:URL protocols:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithURL:(NSURL *)URL protocols:(NSArray<NSString *> *)protocols;
|
- (instancetype)initWithURL:(NSURL *)URL protocols:(NSArray<NSString *> *)protocols;
|
||||||
{
|
|
||||||
return [self initWithURL:URL protocols:protocols options:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (instancetype)initWithURL:(NSURL *)URL protocols:(NSArray<NSString *> *)protocols options:(NSDictionary<NSString *, id> *)options
|
|
||||||
{
|
{
|
||||||
NSMutableURLRequest *request;
|
NSMutableURLRequest *request;
|
||||||
if (URL) {
|
if (URL) {
|
||||||
|
@ -297,7 +290,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||||
NSArray<NSHTTPCookie *> *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:components.URL];
|
NSArray<NSHTTPCookie *> *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:components.URL];
|
||||||
[request setAllHTTPHeaderFields:[NSHTTPCookie requestHeaderFieldsWithCookies:cookies]];
|
[request setAllHTTPHeaderFields:[NSHTTPCookie requestHeaderFieldsWithCookies:cookies]];
|
||||||
}
|
}
|
||||||
return [self initWithURLRequest:request protocols:protocols options:options];
|
return [self initWithURLRequest:request protocols:protocols];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)_RCTSR_commonInit;
|
- (void)_RCTSR_commonInit;
|
||||||
|
@ -488,12 +481,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||||
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Key"), (__bridge CFStringRef)_secKey);
|
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Key"), (__bridge CFStringRef)_secKey);
|
||||||
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Version"), (__bridge CFStringRef)[NSString stringWithFormat:@"%ld", (long)_webSocketVersion]);
|
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Version"), (__bridge CFStringRef)[NSString stringWithFormat:@"%ld", (long)_webSocketVersion]);
|
||||||
|
|
||||||
|
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Origin"), (__bridge CFStringRef)_url.RCTSR_origin);
|
||||||
|
|
||||||
if (_requestedProtocols) {
|
if (_requestedProtocols) {
|
||||||
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Protocol"), (__bridge CFStringRef)[_requestedProtocols componentsJoinedByString:@", "]);
|
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Protocol"), (__bridge CFStringRef)[_requestedProtocols componentsJoinedByString:@", "]);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Origin"), (__bridge CFStringRef)(_requestedOptions[@"origin"] ?: _url.RCTSR_origin));
|
|
||||||
|
|
||||||
[_urlRequest.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
[_urlRequest.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
||||||
CFHTTPMessageSetHeaderFieldValue(request, (__bridge CFStringRef)key, (__bridge CFStringRef)obj);
|
CFHTTPMessageSetHeaderFieldValue(request, (__bridge CFStringRef)key, (__bridge CFStringRef)obj);
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#import "RCTBridge.h"
|
#import "RCTBridge.h"
|
||||||
#import "RCTEventDispatcher.h"
|
#import "RCTEventDispatcher.h"
|
||||||
|
#import "RCTConvert.h"
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
|
|
||||||
@implementation RCTSRWebSocket (React)
|
@implementation RCTSRWebSocket (React)
|
||||||
|
@ -44,9 +45,14 @@ RCT_EXPORT_MODULE()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(connect:(NSURL *)URL protocols:(NSArray *)protocols options:(NSDictionary *)options socketID:(nonnull NSNumber *)socketID)
|
RCT_EXPORT_METHOD(connect:(NSURL *)URL protocols:(NSArray *)protocols headers:(NSDictionary *)headers socketID:(nonnull NSNumber *)socketID)
|
||||||
{
|
{
|
||||||
RCTSRWebSocket *webSocket = [[RCTSRWebSocket alloc] initWithURL:URL protocols:protocols options:options];
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
|
||||||
|
[headers enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
|
||||||
|
[request addValue:[RCTConvert NSString:value] forHTTPHeaderField:key];
|
||||||
|
}];
|
||||||
|
|
||||||
|
RCTSRWebSocket *webSocket = [[RCTSRWebSocket alloc] initWithURLRequest:request protocols:protocols];
|
||||||
webSocket.delegate = self;
|
webSocket.delegate = self;
|
||||||
webSocket.reactTag = socketID;
|
webSocket.reactTag = socketID;
|
||||||
if (!_sockets) {
|
if (!_sockets) {
|
||||||
|
|
|
@ -33,10 +33,10 @@ class WebSocket extends WebSocketBase {
|
||||||
_socketId: number;
|
_socketId: number;
|
||||||
_subs: any;
|
_subs: any;
|
||||||
|
|
||||||
connectToSocketImpl(url: string, protocols: ?Array<string>, options: ?{origin?: string}): void {
|
connectToSocketImpl(url: string, protocols: ?Array<string>, headers: ?Object): void {
|
||||||
this._socketId = WebSocketId++;
|
this._socketId = WebSocketId++;
|
||||||
|
|
||||||
RCTWebSocketModule.connect(url, protocols, options, this._socketId);
|
RCTWebSocketModule.connect(url, protocols, headers, this._socketId);
|
||||||
|
|
||||||
this._registerEvents(this._socketId);
|
this._registerEvents(this._socketId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ import com.squareup.okhttp.ws.WebSocket;
|
||||||
import com.squareup.okhttp.ws.WebSocketCall;
|
import com.squareup.okhttp.ws.WebSocketCall;
|
||||||
import com.squareup.okhttp.ws.WebSocketListener;
|
import com.squareup.okhttp.ws.WebSocketListener;
|
||||||
|
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -63,7 +65,7 @@ public class WebSocketModule extends ReactContextBaseJavaModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void connect(final String url, @Nullable final ReadableArray protocols, @Nullable final ReadableMap options, final int id) {
|
public void connect(final String url, @Nullable final ReadableArray protocols, @Nullable final ReadableMap headers, final int id) {
|
||||||
// ignoring protocols, since OKHttp overrides them.
|
// ignoring protocols, since OKHttp overrides them.
|
||||||
OkHttpClient client = new OkHttpClient();
|
OkHttpClient client = new OkHttpClient();
|
||||||
|
|
||||||
|
@ -76,14 +78,25 @@ public class WebSocketModule extends ReactContextBaseJavaModule {
|
||||||
.tag(id)
|
.tag(id)
|
||||||
.url(url);
|
.url(url);
|
||||||
|
|
||||||
if (options != null && options.hasKey("origin")) {
|
if (headers != null) {
|
||||||
if (ReadableType.String.equals(options.getType("origin"))) {
|
ReadableMapKeySetIterator iterator = headers.keySetIterator();
|
||||||
builder.addHeader("Origin", options.getString("origin"));
|
|
||||||
} else {
|
if (!headers.hasKey("origin")) {
|
||||||
FLog.w(
|
builder.addHeader("origin", setDefaultOrigin(url));
|
||||||
ReactConstants.TAG,
|
|
||||||
"Ignoring: requested origin, value not a string");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (iterator.hasNextKey()) {
|
||||||
|
String key = iterator.nextKey();
|
||||||
|
if (ReadableType.String.equals(headers.getType(key))) {
|
||||||
|
builder.addHeader(key, headers.getString(key));
|
||||||
|
} else {
|
||||||
|
FLog.w(
|
||||||
|
ReactConstants.TAG,
|
||||||
|
"Ignoring: requested " + key + ", value not a string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.addHeader("origin", setDefaultOrigin(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketCall.create(client, builder.build()).enqueue(new WebSocketListener() {
|
WebSocketCall.create(client, builder.build()).enqueue(new WebSocketListener() {
|
||||||
|
@ -188,4 +201,37 @@ public class WebSocketModule extends ReactContextBaseJavaModule {
|
||||||
params.putString("message", message);
|
params.putString("message", message);
|
||||||
sendEvent("websocketFailed", params);
|
sendEvent("websocketFailed", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a default origin
|
||||||
|
*
|
||||||
|
* @param Websocket connection endpoint
|
||||||
|
* @return A string of the endpoint converted to HTTP protocol
|
||||||
|
*/
|
||||||
|
|
||||||
|
private static String setDefaultOrigin(String uri) {
|
||||||
|
try {
|
||||||
|
String defaultOrigin;
|
||||||
|
String scheme = "";
|
||||||
|
|
||||||
|
URI requestURI = new URI(uri);
|
||||||
|
if (requestURI.getScheme().equals("wss")) {
|
||||||
|
scheme += "https";
|
||||||
|
} else if (requestURI.getScheme().equals("ws")) {
|
||||||
|
scheme += "http";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestURI.getPort() != -1) {
|
||||||
|
defaultOrigin = String.format("%s://%s:%s", scheme, requestURI.getHost(), requestURI.getPort());
|
||||||
|
} else {
|
||||||
|
defaultOrigin = String.format("%s://%s/", scheme, requestURI.getHost());
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultOrigin;
|
||||||
|
|
||||||
|
} catch(URISyntaxException e) {
|
||||||
|
throw new IllegalArgumentException("Unable to set " + uri + " as default origin header.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue