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.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -48,8 +49,8 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
|||
void onMessage(ByteString byteString, WritableMap params);
|
||||
}
|
||||
|
||||
private final Map<Integer, WebSocket> mWebSocketConnections = new HashMap<>();
|
||||
private final Map<Integer, ContentHandler> mContentHandlers = new HashMap<>();
|
||||
private final Map<Integer, WebSocket> mWebSocketConnections = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, ContentHandler> mContentHandlers = new ConcurrentHashMap<>();
|
||||
|
||||
private ReactContext mReactContext;
|
||||
private ForwardingCookieHandler mCookieHandler;
|
||||
|
@ -224,8 +225,19 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
|||
public void send(String message, int id) {
|
||||
WebSocket client = mWebSocketConnections.get(id);
|
||||
if (client == null) {
|
||||
// This is a programmer error
|
||||
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
|
||||
// This is a programmer error -- display development warning
|
||||
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 {
|
||||
client.send(message);
|
||||
|
@ -238,8 +250,19 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
|||
public void sendBinary(String base64String, int id) {
|
||||
WebSocket client = mWebSocketConnections.get(id);
|
||||
if (client == null) {
|
||||
// This is a programmer error
|
||||
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
|
||||
// This is a programmer error -- display development warning
|
||||
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 {
|
||||
client.send(ByteString.decodeBase64(base64String));
|
||||
|
@ -251,8 +274,19 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
|||
public void sendBinary(ByteString byteString, int id) {
|
||||
WebSocket client = mWebSocketConnections.get(id);
|
||||
if (client == null) {
|
||||
// This is a programmer error
|
||||
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
|
||||
// This is a programmer error -- display development warning
|
||||
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 {
|
||||
client.send(byteString);
|
||||
|
@ -265,8 +299,19 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
|||
public void ping(int id) {
|
||||
WebSocket client = mWebSocketConnections.get(id);
|
||||
if (client == null) {
|
||||
// This is a programmer error
|
||||
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
|
||||
// This is a programmer error -- display development warning
|
||||
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 {
|
||||
client.send(ByteString.EMPTY);
|
||||
|
|
Loading…
Reference in New Issue