From 181ea7122278118b0ba8cc5b5aba0ed80f7b2e53 Mon Sep 17 00:00:00 2001 From: games647 Date: Sun, 28 Jan 2018 13:25:10 +0100 Subject: [PATCH] Readd SSLFactory for rate-limit load balance because direct proxies doesn't work at all --- .../core/mojang/BalancedSSLFactory.java | 71 +++++++++++++++++++ .../core/mojang/MojangApiConnector.java | 31 ++++++-- 2 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 core/src/main/java/com/github/games647/fastlogin/core/mojang/BalancedSSLFactory.java diff --git a/core/src/main/java/com/github/games647/fastlogin/core/mojang/BalancedSSLFactory.java b/core/src/main/java/com/github/games647/fastlogin/core/mojang/BalancedSSLFactory.java new file mode 100644 index 00000000..f76d6ce0 --- /dev/null +++ b/core/src/main/java/com/github/games647/fastlogin/core/mojang/BalancedSSLFactory.java @@ -0,0 +1,71 @@ +package com.github.games647.fastlogin.core.mojang; + +import com.google.common.collect.Iterables; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.util.Iterator; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSocketFactory; + +public class BalancedSSLFactory extends SSLSocketFactory { + + //in order to be thread-safe + private final Iterator iterator; + private final SSLSocketFactory oldFactory; + + public BalancedSSLFactory(SSLSocketFactory oldFactory, Iterable localAddresses) { + this.oldFactory = oldFactory; + this.iterator = Iterables.cycle(localAddresses).iterator(); + } + + public BalancedSSLFactory(Iterable iterator) { + this(HttpsURLConnection.getDefaultSSLSocketFactory(), iterator); + } + + @Override + public String[] getDefaultCipherSuites() { + return oldFactory.getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() { + return oldFactory.getSupportedCipherSuites(); + } + + @Override + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException { + return oldFactory.createSocket(host, port, getNextLocalAddress(), 0); + } + + @Override + public Socket createSocket(String host, int port) throws IOException { + return oldFactory.createSocket(host, port, getNextLocalAddress(), 0); + } + + @Override + public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) + throws IOException { + //default + return oldFactory.createSocket(host, port, localAddress, localPort); + } + + @Override + public Socket createSocket(InetAddress host, int port) throws IOException { + return oldFactory.createSocket(host, port, getNextLocalAddress(), 0); + } + + @Override + public Socket createSocket(InetAddress host, int port, InetAddress local, int localPort) throws IOException { + //Default + return oldFactory.createSocket(host, port, local, localPort); + } + + private InetAddress getNextLocalAddress() { + synchronized (iterator) { + return iterator.next(); + } + } +} diff --git a/core/src/main/java/com/github/games647/fastlogin/core/mojang/MojangApiConnector.java b/core/src/main/java/com/github/games647/fastlogin/core/mojang/MojangApiConnector.java index 48aae82f..3eab8c9a 100644 --- a/core/src/main/java/com/github/games647/fastlogin/core/mojang/MojangApiConnector.java +++ b/core/src/main/java/com/github/games647/fastlogin/core/mojang/MojangApiConnector.java @@ -11,23 +11,28 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.Proxy.Type; import java.net.URL; +import java.net.UnknownHostException; import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.UUID; import java.util.regex.Pattern; import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSocketFactory; import org.slf4j.Logger; @@ -46,6 +51,7 @@ public class MojangApiConnector { private final Pattern validNameMatcher = Pattern.compile("^\\w{2,16}$"); private final Iterator proxies; + private final SSLSocketFactory sslFactory; private final Map requests = CommonUtil.buildCache(10, -1); private final int rateLimit; @@ -59,16 +65,13 @@ public class MojangApiConnector { , Iterable proxies) { this.logger = logger; this.rateLimit = Math.max(rateLimit, 600); + this.sslFactory = buildAddresses(logger, localAddresses); List proxyBuilder = new ArrayList<>(); for (HostAndPort proxy : proxies) { proxyBuilder.add(new Proxy(Type.HTTP, new InetSocketAddress(proxy.getHostText(), proxy.getPort()))); } - for (String address : localAddresses) { - proxyBuilder.add(new Proxy(Type.DIRECT, new InetSocketAddress(address.replace('-', '.'), 0))); - } - this.proxies = Iterables.cycle(proxyBuilder).iterator(); } @@ -143,6 +146,8 @@ public class MojangApiConnector { connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("User-Agent", USER_AGENT); + connection.setSSLSocketFactory(sslFactory); + //this connection doesn't need to be closed. So can make use of keep alive in java return connection; } @@ -150,4 +155,22 @@ public class MojangApiConnector { protected HttpsURLConnection getConnection(String url) throws IOException { return getConnection(url, Proxy.NO_PROXY); } + + private SSLSocketFactory buildAddresses(Logger logger, Iterable localAddresses) { + Set addresses = new HashSet<>(); + for (String localAddress : localAddresses) { + try { + InetAddress address = InetAddress.getByName(localAddress.replace('-', '.')); + addresses.add(address); + } catch (UnknownHostException ex) { + logger.error("IP-Address is unknown to us", ex); + } + } + + if (addresses.isEmpty()) { + return HttpsURLConnection.getDefaultSSLSocketFactory(); + } + + return new BalancedSSLFactory(HttpsURLConnection.getDefaultSSLSocketFactory(), addresses); + } }