mirror of
https://github.com/status-im/react-native.git
synced 2025-01-14 19:44:13 +00:00
Use ConcurrentHashMap for handling concurrent Android websockets, and…
Summary: … prevent unknown websocket IDs from crashing on Android (show warning on development builds instead) This PR addresses #3346; an unknown websocket ID should produce a warning during development, but not cause crashes in production RN apps. This PR was created by satya164's request, and was inspired by tanthanh289's suggestion on #3346's thread. On Android, create a websocket using a service like Pusher (`pusher-js` npm package) or manually, and then induce removal of its websocket ID. Result should be a red warning screen during development, and no crash in the app's release variant. [ANDROID] [BUGFIX] [WebSocket] - Prevent unknown websocket IDs from crashing on Android Closes https://github.com/facebook/react-native/pull/17884 Differential Revision: D6954038 Pulled By: hramos fbshipit-source-id: b346d80d7568996b8819c0de54552abb534cbfae
This commit is contained in:
parent
01a58d182a
commit
1a790f8703
@ -27,6 +27,7 @@ import com.facebook.react.modules.network.ForwardingCookieHandler;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -48,8 +49,8 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
|||||||
void onMessage(ByteString byteString, WritableMap params);
|
void onMessage(ByteString byteString, WritableMap params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<Integer, WebSocket> mWebSocketConnections = new HashMap<>();
|
private final Map<Integer, WebSocket> mWebSocketConnections = new ConcurrentHashMap<>();
|
||||||
private final Map<Integer, ContentHandler> mContentHandlers = new HashMap<>();
|
private final Map<Integer, ContentHandler> mContentHandlers = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private ReactContext mReactContext;
|
private ReactContext mReactContext;
|
||||||
private ForwardingCookieHandler mCookieHandler;
|
private ForwardingCookieHandler mCookieHandler;
|
||||||
@ -224,8 +225,19 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
|||||||
public void send(String message, int id) {
|
public void send(String message, int id) {
|
||||||
WebSocket client = mWebSocketConnections.get(id);
|
WebSocket client = mWebSocketConnections.get(id);
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
// This is a programmer error
|
// This is a programmer error -- display development warning
|
||||||
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
|
WritableMap params = Arguments.createMap();
|
||||||
|
params.putInt("id", id);
|
||||||
|
params.putString("message", "client is null");
|
||||||
|
sendEvent("websocketFailed", params);
|
||||||
|
params = Arguments.createMap();
|
||||||
|
params.putInt("id", id);
|
||||||
|
params.putInt("code", 0);
|
||||||
|
params.putString("reason", "client is null");
|
||||||
|
sendEvent("websocketClosed", params);
|
||||||
|
mWebSocketConnections.remove(id);
|
||||||
|
mContentHandlers.remove(id);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
client.send(message);
|
client.send(message);
|
||||||
@ -238,8 +250,19 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
|||||||
public void sendBinary(String base64String, int id) {
|
public void sendBinary(String base64String, int id) {
|
||||||
WebSocket client = mWebSocketConnections.get(id);
|
WebSocket client = mWebSocketConnections.get(id);
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
// This is a programmer error
|
// This is a programmer error -- display development warning
|
||||||
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
|
WritableMap params = Arguments.createMap();
|
||||||
|
params.putInt("id", id);
|
||||||
|
params.putString("message", "client is null");
|
||||||
|
sendEvent("websocketFailed", params);
|
||||||
|
params = Arguments.createMap();
|
||||||
|
params.putInt("id", id);
|
||||||
|
params.putInt("code", 0);
|
||||||
|
params.putString("reason", "client is null");
|
||||||
|
sendEvent("websocketClosed", params);
|
||||||
|
mWebSocketConnections.remove(id);
|
||||||
|
mContentHandlers.remove(id);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
client.send(ByteString.decodeBase64(base64String));
|
client.send(ByteString.decodeBase64(base64String));
|
||||||
@ -251,8 +274,19 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
|||||||
public void sendBinary(ByteString byteString, int id) {
|
public void sendBinary(ByteString byteString, int id) {
|
||||||
WebSocket client = mWebSocketConnections.get(id);
|
WebSocket client = mWebSocketConnections.get(id);
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
// This is a programmer error
|
// This is a programmer error -- display development warning
|
||||||
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
|
WritableMap params = Arguments.createMap();
|
||||||
|
params.putInt("id", id);
|
||||||
|
params.putString("message", "client is null");
|
||||||
|
sendEvent("websocketFailed", params);
|
||||||
|
params = Arguments.createMap();
|
||||||
|
params.putInt("id", id);
|
||||||
|
params.putInt("code", 0);
|
||||||
|
params.putString("reason", "client is null");
|
||||||
|
sendEvent("websocketClosed", params);
|
||||||
|
mWebSocketConnections.remove(id);
|
||||||
|
mContentHandlers.remove(id);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
client.send(byteString);
|
client.send(byteString);
|
||||||
@ -265,8 +299,19 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
|||||||
public void ping(int id) {
|
public void ping(int id) {
|
||||||
WebSocket client = mWebSocketConnections.get(id);
|
WebSocket client = mWebSocketConnections.get(id);
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
// This is a programmer error
|
// This is a programmer error -- display development warning
|
||||||
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
|
WritableMap params = Arguments.createMap();
|
||||||
|
params.putInt("id", id);
|
||||||
|
params.putString("message", "client is null");
|
||||||
|
sendEvent("websocketFailed", params);
|
||||||
|
params = Arguments.createMap();
|
||||||
|
params.putInt("id", id);
|
||||||
|
params.putInt("code", 0);
|
||||||
|
params.putString("reason", "client is null");
|
||||||
|
sendEvent("websocketClosed", params);
|
||||||
|
mWebSocketConnections.remove(id);
|
||||||
|
mContentHandlers.remove(id);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
client.send(ByteString.EMPTY);
|
client.send(ByteString.EMPTY);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user