use of org.javacord.api.util.auth.Authenticator in project Javacord by BtoBastian.
the class ProxyAuthenticator method systemDefaultAuthentication.
/**
* Generates a {@code Basic} auth header with credentials from the system default authenticator.
*
* @param route The route to which a request is done that needs to be authenticated.
* @param request The originating request that led to the authentication attempt.
* @param response The response that demands authentication.
* @return The {@code Basic} auth header.
*/
private Map<String, List<String>> systemDefaultAuthentication(Route route, Request request, Response response) {
InetSocketAddress proxyAddress = (InetSocketAddress) route.getProxy().address();
String host = proxyAddress.getHostString();
InetAddress addr = proxyAddress.getAddress();
int port = proxyAddress.getPort();
URL url = route.getUrl();
String protocol = url.getProtocol();
return response.getChallenges("basic").filter(challenge -> challenge.getRealm().isPresent()).filter(challenge -> {
String charset = challenge.getAuthParams().get("charset");
return charset == null || charset.equalsIgnoreCase("UTF-8");
}).map(challenge -> {
String realm = challenge.getRealm().orElseThrow(AssertionError::new);
PasswordAuthentication passwordAuthentication = java.net.Authenticator.requestPasswordAuthentication(host, addr, port, protocol, realm, challenge.getScheme(), url, java.net.Authenticator.RequestorType.PROXY);
if (passwordAuthentication != null) {
Charset charset = challenge.getAuthParams().containsKey("charset") ? StandardCharsets.UTF_8 : StandardCharsets.ISO_8859_1;
return Credentials.basic(passwordAuthentication.getUserName(), String.valueOf(passwordAuthentication.getPassword()), charset);
}
return null;
}).filter(Objects::nonNull).filter(credentials -> request.getHeaders("Proxy-Authorization").stream().noneMatch(credentials::equals)).findAny().map(credentials -> Collections.singletonMap("Proxy-Authorization", Arrays.asList(null, credentials))).orElse(null);
}
use of org.javacord.api.util.auth.Authenticator 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