Skip to content

Commit

Permalink
Merge pull request #808 from ably/feature/fix-websocket-issue
Browse files Browse the repository at this point in the history
Fix Java-WebSocket problem on Android below 24
  • Loading branch information
KacperKluka authored Jun 22, 2022
2 parents 282d2a4 + f35c5b6 commit cb21576
Showing 1 changed file with 40 additions and 2 deletions.
42 changes: 40 additions & 2 deletions lib/src/main/java/io/ably/lib/transport/WebSocketTransport.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
import java.util.Timer;
import java.util.TimerTask;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.exceptions.WebsocketNotConnectedException;
Expand Down Expand Up @@ -147,8 +150,28 @@ class WsClient extends WebSocketClient {
@Override
public void onOpen(ServerHandshake handshakedata) {
Log.d(TAG, "onOpen()");
connectListener.onTransportAvailable(WebSocketTransport.this);
flagActivity();
if (shouldExplicitlyVerifyHostname && !isHostnameVerified(params.host)) {
close();
} else {
connectListener.onTransportAvailable(WebSocketTransport.this);
flagActivity();
}
}

/**
* Added because we had to override the onSetSSLParameters() that usually performs this verification.
* When the minSdkVersion will be updated to 24 we should remove this method and its usages.
* https://github.com/TooTallNate/Java-WebSocket/wiki/No-such-method-error-setEndpointIdentificationAlgorithm#workaround
*/
private boolean isHostnameVerified(String hostname) {
final SSLSession session = getSSLSession();
if (HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session)) {
Log.v(TAG, "Successfully verified hostname");
return true;
} else {
Log.e(TAG, "Hostname verification failed, expected " + hostname + ", found " + session.getPeerHost());
return false;
}
}

@Override
Expand Down Expand Up @@ -234,6 +257,20 @@ public void onError(final Exception e) {
connectListener.onTransportUnavailable(WebSocketTransport.this, new ErrorInfo(e.getMessage(), 503, 80000));
}

@Override
protected void onSetSSLParameters(SSLParameters sslParameters) {
try {
super.onSetSSLParameters(sslParameters);
shouldExplicitlyVerifyHostname = false;
} catch (NoSuchMethodError exception) {
// This error will be thrown on Android below level 24.
// When the minSdkVersion will be updated to 24 we should remove this overridden method.
// https://github.com/TooTallNate/Java-WebSocket/wiki/No-such-method-error-setEndpointIdentificationAlgorithm#workaround
Log.w(TAG, "Error when trying to set SSL parameters, most likely due to an old Java API version", exception);
shouldExplicitlyVerifyHostname = true;
}
}

private synchronized void dispose() {
/* dispose timer */
try {
Expand Down Expand Up @@ -307,6 +344,7 @@ private synchronized void schedule(TimerTask task, long delay) {
private Timer timer = new Timer();
private TimerTask activityTimerTask = null;
private long lastActivityTime;
private boolean shouldExplicitlyVerifyHostname = true;
}

public String toString() {
Expand Down

0 comments on commit cb21576

Please sign in to comment.