-
Notifications
You must be signed in to change notification settings - Fork 24.8k
[Websocket] Update options parameter to headers. Update to spec. #6016
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
fe9534c
to
dca5e85
Compare
return defaultOrigin; | ||
|
||
} catch(URISyntaxException e) { | ||
// Handle error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@christopherdro Since this is a user error, we should throw the error to show a redbox (IllegalArgumentException
). This matches the behaviour on the web where it throws an error.
dca5e85
to
f22fa6a
Compare
@christopherdro updated the pull request. |
@satya164 I updated the PR to handle the error message. However, it appears that passing a invalid url scheme will be caught beforehand through Request.Builder |
@@ -61,11 +61,11 @@ extern NSString *const RCTSRHTTPResponseErrorKey; | |||
|
|||
// 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 options:(NSDictionary<NSString *, NSString *> *)options NS_DESIGNATED_INITIALIZER; | |||
- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols headers:(NSDictionary<NSString *, NSString *> *)headers NS_DESIGNATED_INITIALIZER; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah this used to be called options but it's really HTTP headers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, these were recently merged via 9b87e6c
I noticed that his original implementation did have an option for using headers but was asked to remove it because only the origin
header was required by the contributor.
@christopherdro updated the pull request. |
f22fa6a
to
2be04cb
Compare
@christopherdro updated the pull request. |
@@ -245,7 +245,7 @@ + (void)initialize; | |||
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 headers:(NSDictionary<NSString *, NSString *> *)headers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since NSURLRequest already includes headers, is there any reason for the seperate headers parameter? Can't we just include them in the request?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nicklockwood That makes sense but it appears there are two other places that headers are being set.
react-native/Libraries/WebSocket/RCTSRWebSocket.m
Lines 478 to 489 in debcac5
// Set host first so it defaults CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Host"), (__bridge CFStringRef)(_url.port ? [NSString stringWithFormat:@"%@:%@", _url.host, _url.port] : _url.host)); NSMutableData *keyBytes = [[NSMutableData alloc] initWithLength:16]; SecRandomCopyBytes(kSecRandomDefault, keyBytes.length, keyBytes.mutableBytes); _secKey = [keyBytes base64EncodedStringWithOptions:0]; assert([_secKey length] == 24); CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Upgrade"), CFSTR("websocket")); CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Connection"), CFSTR("Upgrade")); CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Key"), (__bridge CFStringRef)_secKey); CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Sec-WebSocket-Version"), (__bridge CFStringRef)[NSString stringWithFormat:@"%ld", (long)_webSocketVersion]); [request setAllHTTPHeaderFields:[NSHTTPCookie requestHeaderFieldsWithCookies:cookies]];
So im not sure the best way to handle this.
We talked about this briefly at React.js conf but don't remember the conclusion. Regarding the |
@mkonicek Your are right that it is browser specfic. I was just trying to make things consistent across platform. If it's unnecessary then we should remove it from iOS as well. @nicklockwood Thoughts on whether we need to have a default origin on iOS? |
Cool, thanks for the explanation! I vote for getting rid of the origin headers if they're not needed on mobile. |
5fb2301
to
66d7682
Compare
@christopherdro updated the pull request. |
@nicklockwood Updated the PR based on some of your comments and made further notes on ones that I wasn't sure about. |
Is the method |
Technically no since RN is not a browser client.
I was waiting to see what @nicklockwood thought about removing the default origin header from iOS. |
66d7682
to
c7450a9
Compare
@christopherdro updated the pull request. |
@nicklockwood Any chance you can chime in here again so I can go ahead and wrap up this PR? Thanks! |
This PR does two things which makes it a bit harder to review and land:
Do you think you could send the "Allows custom headers on connection request" part separately especially since we're not sure 2. is needed? Then it should be fairly straightforward to merge. |
c7450a9
to
59e7194
Compare
@christopherdro updated the pull request. |
@mkonicek Fair enough. I'll update the the PR to only update the headers. Should have it done by this weekend and will ping you again. |
Hi @christopherdro, What is your opinion to keep the argument name *ex: *
for future workaround flags or custom actions. |
@zxcpoiu I believe that was my original thought but avoided since it seems that the general attitude of PR's is to implement whats required atm and not over engineer. I will however revisit this shortly. Can you provide any examples of what some future options might be? |
you're right, not over engineer is a good point. Currently what I can think of potential use cases are: maybe to tweak options of android OkHttpClient Consturrctor when create ws instance for example:
It's not that critical, and I don't want to hold this decent PR. |
@facebook-github-bot shipit |
Thanks for importing. If you are an FB employee go to Phabricator to review. |
@christopherdro updated the pull request. |
Summary:This is a follow up of 9b87e6c. - Allows custom headers on connection request - Adds a default `origin` header to Android, just like iOS **Introduces no breaking changes.** I was working on something similar and would like to propose a few changes that make the API more consistent across both iOS and Android platforms and brings this closer to [spec](https://tools.ietf.org/html/rfc6455). I believe aprock first implementation of adding custom `headers` was correct. It makes sense naming this argument `headers` since we have no other general options available, and the current `options` field is being used to pass in a header anyway. My use case for custom headers was attaching a token to the `Authorization` header on the connection request. I have been testing this by passing a JWT inside the `Authorization` header and verifying it on the server before establishing a connection. Closes #6016 Differential Revision: D3040735 fb-gh-sync-id: 183744d2415b895f9d9fd8ecf6023a546e18a546 shipit-source-id: 183744d2415b895f9d9fd8ecf6023a546e18a546
This is a follow up of 9b87e6c.
PR Overview:
origin
header to Android, just like iOSIntroduces no breaking changes.
PR Detail:
I was working on something similar and would like to propose a few changes that make the API more consistent across both iOS and Android platforms and brings this closer to spec.
I believe @aprock first implementation of adding custom
headers
was correct. It makes sense naming this argumentheaders
since we have no other general options available, and the currentoptions
field is being used to pass in a header anyway.My use case for custom headers was attaching a token to the
Authorization
header on the connection request. I have been testing this by passing a JWT inside theAuthorization
header and verifying it on the server before establishing a connection.I tried to take this this abstraction further and read the response headers from the server to see if a new token was available if the connection was denied from a expired token. Unfortunately, this was only possible with Android since the third party library used by iOS (SquareRocket) does not return the server response on connection failures.