Android WebSocket: include cookies in request

Summary:
This PR updates #6851 from srikanthkh, fixing coding conventions and javadoc, and adding a test plan.

Added testing functions into the WebSocketExample page of the UIExplorer, including a tiny http server to set a cookie on demand. Instructions included in the UIExplorer app.
Closes https://github.com/facebook/react-native/pull/9114

Differential Revision: D4140534

Pulled By: lacker

fbshipit-source-id: e020ad0c6d1d3ea09c0c3564c1795b4e1bc4517d
This commit is contained in:
Antoine Rousseau
2016-11-07 10:37:11 -08:00
committed by Facebook Github Bot
parent a4bb4d25f5
commit be4afdde37
5 changed files with 147 additions and 27 deletions

View File

@@ -32,10 +32,12 @@ const {
Text,
TextInput,
TouchableOpacity,
ScrollView,
View,
} = ReactNative;
const DEFAULT_WS_URL = 'ws://localhost:5555/';
const DEFAULT_HTTP_URL = 'http://localhost:5556/';
const WS_EVENTS = [
'close',
'error',
@@ -95,6 +97,8 @@ function showValue(value) {
type State = {
url: string;
httpUrl: string;
fetchStatus: ?string;
socket: ?WebSocket;
socketState: ?number;
lastSocketEvent: ?string;
@@ -109,6 +113,8 @@ class WebSocketExample extends React.Component<any, any, State> {
state: State = {
url: DEFAULT_WS_URL,
httpUrl: DEFAULT_HTTP_URL,
fetchStatus: null,
socket: null,
socketState: null,
lastSocketEvent: null,
@@ -154,6 +160,19 @@ class WebSocketExample extends React.Component<any, any, State> {
this.setState({outgoingMessage: ''});
};
_sendHttp = () => {
this.setState({
fetchStatus: 'fetching',
});
fetch(this.state.httpUrl).then((response) => {
if (response.status >= 200 && response.status < 400) {
this.setState({
fetchStatus: 'OK',
});
}
});
};
_sendBinary = () => {
if (!this.state.socket ||
typeof ArrayBuffer === 'undefined' ||
@@ -176,16 +195,11 @@ class WebSocketExample extends React.Component<any, any, State> {
this.state.socket.readyState >= WebSocket.CLOSING;
const canSend = !!this.state.socket;
return (
<View style={styles.container}>
<ScrollView style={styles.container}>
<View style={styles.note}>
<Text>Pro tip:</Text>
<Text>To start the WS test server:</Text>
<Text style={styles.monospace}>
node Examples/UIExplorer/websocket_test_server.js
</Text>
<Text>
{' in the '}
<Text style={styles.monospace}>react-native</Text>
{' directory starts a test server.'}
./Examples/UIExplorer/js/websocket_test_server.js
</Text>
</View>
<Row
@@ -207,16 +221,18 @@ class WebSocketExample extends React.Component<any, any, State> {
onChangeText={(url) => this.setState({url})}
value={this.state.url}
/>
<Button
onPress={this._connect}
label="Connect"
disabled={!canConnect}
/>
<Button
onPress={this._disconnect}
label="Disconnect"
disabled={canConnect}
/>
<View style={styles.buttonRow}>
<Button
onPress={this._connect}
label="Connect"
disabled={!canConnect}
/>
<Button
onPress={this._disconnect}
label="Disconnect"
disabled={canConnect}
/>
</View>
<TextInput
style={styles.textInput}
autoCorrect={false}
@@ -236,7 +252,32 @@ class WebSocketExample extends React.Component<any, any, State> {
disabled={!canSend}
/>
</View>
</View>
<View style={styles.note}>
<Text>To start the HTTP test server:</Text>
<Text style={styles.monospace}>
./Examples/UIExplorer/http_test_server.js
</Text>
</View>
<TextInput
style={styles.textInput}
autoCorrect={false}
placeholder="HTTP URL..."
onChangeText={(httpUrl) => this.setState({httpUrl})}
value={this.state.httpUrl}
/>
<View style={styles.buttonRow}>
<Button
onPress={this._sendHttp}
label="Send HTTP request to set cookie"
disabled={this.state.fetchStatus === 'fetching'}
/>
</View>
<View style={styles.note}>
<Text>
{this.state.fetchStatus === 'OK' ? 'Done. Check your WS server console to see if the next WS requests include the cookie (should be "wstest=OK")' : '-'}
</Text>
</View>
</ScrollView>
);
}

View File

@@ -0,0 +1,43 @@
#!/usr/bin/env node
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @flow
*/
'use strict';
/* eslint-env node */
console.log(`\
Test server for WebSocketExample
This will set a cookie named "wstest" on the response of any incoming request.
`);
const connect = require('connect');
const http = require('http');
const app = connect();
app.use(function(req, res) {
console.log('received request');
const cookieOptions = {
//httpOnly: true, // the cookie is not accessible by the user (javascript,...)
secure: false, // allow HTTP
};
res.cookie('wstest', 'OK', cookieOptions);
res.end('Cookie has been set!\n');
});
http.createServer(app).listen(5556);

View File

@@ -1,3 +1,5 @@
#!/usr/bin/env node
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
@@ -29,7 +31,7 @@ const WebSocket = require('ws');
console.log(`\
Test server for WebSocketExample
This will send each incoming message right back to the other side.a
This will send each incoming message right back to the other side.
Restart with the '--binary' command line flag to have it respond with an
ArrayBuffer instead of a string.
`);
@@ -39,6 +41,7 @@ const server = new WebSocket.Server({port: 5555});
server.on('connection', (ws) => {
ws.on('message', (message) => {
console.log('Received message:', message);
console.log('Cookie:', ws.upgradeReq.headers.cookie);
if (respondWithBinary) {
message = new Buffer(message);
}