use of org.javacord.core.util.auth.NvWebSocketRouteImpl in project Javacord by BtoBastian.
the class DiscordWebSocketAdapter method connect.
/**
* Connects the websocket.
*/
private void connect() {
try {
WebSocketFactory factory = new WebSocketFactory();
String webSocketUri = getGateway(api) + "?encoding=json&v=" + Javacord.DISCORD_GATEWAY_VERSION;
Proxy proxy = api.getProxy().orElseGet(() -> {
List<Proxy> proxies = api.getProxySelector().orElseGet(ProxySelector::getDefault).select(URI.create(webSocketUri.replace("wss://", "https://").replace("ws://", "http://")));
return proxies.stream().filter(p -> p.type() == Proxy.Type.DIRECT).findAny().orElseGet(() -> proxies.stream().filter(p -> p.type() == Proxy.Type.HTTP).findAny().orElseGet(() -> proxies.get(0)));
});
switch(proxy.type()) {
case DIRECT:
// nothing to do
break;
case HTTP:
SocketAddress proxyAddress = proxy.address();
if (!(proxyAddress instanceof InetSocketAddress)) {
throw new WebSocketException(null, "HTTP proxies without an InetSocketAddress are not supported currently");
}
InetSocketAddress proxyInetAddress = ((InetSocketAddress) proxyAddress);
String proxyHost = proxyInetAddress.getHostString();
int proxyPort = proxyInetAddress.getPort();
ProxySettings proxySettings = factory.getProxySettings();
proxySettings.setHost(proxyHost).setPort(proxyPort);
Optional<Authenticator> proxyAuthenticator = api.getProxyAuthenticator();
URL webSocketUrl = URI.create(webSocketUri.replace("wss://", "https://").replace("ws://", "http://")).toURL();
if (proxyAuthenticator.isPresent()) {
Map<String, List<String>> requestHeaders = proxyAuthenticator.get().authenticate(new NvWebSocketRouteImpl(webSocketUrl, proxy, proxyInetAddress), new Request() {
}, new NvWebSocketResponseImpl());
if (requestHeaders != null) {
requestHeaders.forEach((headerName, headerValues) -> {
if (headerValues == null) {
proxySettings.getHeaders().remove(headerName);
return;
}
if (headerValues.isEmpty()) {
return;
}
String firstHeaderValue = headerValues.get(0);
if (firstHeaderValue == null) {
proxySettings.getHeaders().remove(headerName);
} else {
proxySettings.addHeader(headerName, firstHeaderValue);
}
headerValues.stream().skip(1).forEach(headerValue -> proxySettings.addHeader(headerName, headerValue));
});
}
} else {
PasswordAuthentication credentials = java.net.Authenticator.requestPasswordAuthentication(proxyHost, proxyInetAddress.getAddress(), proxyPort, webSocketUrl.getProtocol(), null, "Basic", webSocketUrl, java.net.Authenticator.RequestorType.PROXY);
if (credentials != null) {
proxySettings.setId(credentials.getUserName()).setPassword(String.valueOf(credentials.getPassword()));
}
}
break;
default:
throw new WebSocketException(null, "Proxies of type '" + proxy.type() + "' are not supported currently");
}
if (api.isTrustAllCertificates()) {
factory.setSSLSocketFactory(new TrustAllTrustManager().createSslSocketFactory());
}
WebSocket websocket = factory.createSocket(webSocketUri);
this.websocket.set(websocket);
websocket.addHeader("Accept-Encoding", "gzip");
websocket.addListener(this);
websocket.addListener(new WebSocketLogger());
if (sessionId == null) {
api.getGatewayIdentifyRatelimiter().requestQuota();
}
websocket.connect();
} catch (Throwable t) {
logger.warn("An error occurred while connecting to websocket", t);
if (reconnect) {
reconnectingOrResumingLock.lock();
try {
reconnectAttempt.incrementAndGet();
} finally {
reconnectingOrResumingLock.unlock();
}
logger.info("Trying to reconnect/resume in {} seconds!", api.getReconnectDelay(reconnectAttempt.get()));
// Reconnect after a (short?) delay depending on the amount of reconnect attempts
api.getThreadPool().getScheduler().schedule(() -> {
gatewayWriteLock.lock();
try {
gateway = null;
} finally {
gatewayWriteLock.unlock();
}
this.connect();
}, api.getReconnectDelay(reconnectAttempt.get()), TimeUnit.SECONDS);
}
}
}
Aggregations