io.ably.lib.network.DefaultWebSocketClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of network-client-default Show documentation
Show all versions of network-client-default Show documentation
Default implementation for HTTP client
package io.ably.lib.network;
import org.java_websocket.WebSocket;
import org.java_websocket.exceptions.WebsocketNotConnectedException;
import org.java_websocket.framing.Framedata;
import org.java_websocket.handshake.ServerHandshake;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;
import java.net.URI;
import java.nio.ByteBuffer;
public class DefaultWebSocketClient extends org.java_websocket.client.WebSocketClient implements WebSocketClient {
private final WebSocketListener listener;
private final WebSocketEngineConfig config;
private boolean shouldExplicitlyVerifyHostname = true;
public DefaultWebSocketClient(URI serverUri, WebSocketListener listener, WebSocketEngineConfig config) {
super(serverUri);
this.listener = listener;
this.config = config;
}
@Override
public void onOpen(ServerHandshake serverHandshake) {
if (config.isTls() && shouldExplicitlyVerifyHostname && !isHostnameVerified(config.getHost())) {
close();
} else {
listener.onOpen();
}
}
@Override
public void onMessage(String s) {
listener.onMessage(s);
}
@Override
public void onMessage(ByteBuffer blob) {
listener.onMessage(blob);
}
/* This allows us to detect a websocket ping, so we don't need Ably pings. */
@Override
public void onWebsocketPing(WebSocket conn, Framedata f) {
/* Call superclass to ensure the pong is sent. */
super.onWebsocketPing(conn, f);
listener.onWebsocketPing();
}
@Override
public void onClose(int code, String reason, boolean remote) {
listener.onClose(code, reason);
}
@Override
public void onError(Exception e) {
listener.onError(e);
}
@Override
public void cancel(int code, String reason) {
closeConnection(code, reason);
}
@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
shouldExplicitlyVerifyHostname = true;
listener.onOldJavaVersionDetected(exception);
}
}
@Override
public void send(String text) {
try {
super.send(text);
} catch (WebsocketNotConnectedException e) {
throw new NotConnectedException(e);
}
}
/**
* 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)) {
return true;
} else {
listener.onError(new IllegalArgumentException("Hostname verification failed, expected " + hostname + ", found " + session.getPeerHost()));
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy