Backed out changeset 183744d2415b

Reviewed By: nicklockwood

Differential Revision: D3053067

fb-gh-sync-id: de20718b5bf82eae433637847143e32b7a4bb216
shipit-source-id: de20718b5bf82eae433637847143e32b7a4bb216
This commit is contained in:
Alexey Dodonov 2016-03-15 11:48:42 -07:00 committed by Facebook Github Bot 6
parent fe7fcdb227
commit cc2068e201
5 changed files with 73 additions and 30 deletions

View File

@ -60,12 +60,10 @@ 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;

View File

@ -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);
}]; }];

View File

@ -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) {

View File

@ -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);
} }

View File

@ -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,15 +78,26 @@ 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"));
if (!headers.hasKey("origin")) {
builder.addHeader("origin", setDefaultOrigin(url));
}
while (iterator.hasNextKey()) {
String key = iterator.nextKey();
if (ReadableType.String.equals(headers.getType(key))) {
builder.addHeader(key, headers.getString(key));
} else { } else {
FLog.w( FLog.w(
ReactConstants.TAG, ReactConstants.TAG,
"Ignoring: requested origin, value not a string"); "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.");
}
}
} }