diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a74ec5..8de8ac3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Getdown Releases +## 2.0.1 - +* Introduction of ProxyVole dependency library as default proxy detection, old usage of JRegistryKey + kept, require setting property `use_proxy` to value `legacy` + + ## 2.0.0 - May 01, 2024 * GroupId and package root have moved from `com.threerings.getdown` to `io.github.bekoenig.getdown` diff --git a/core/src/main/java/io/github/bekoenig/getdown/data/SysProps.java b/core/src/main/java/io/github/bekoenig/getdown/data/SysProps.java index 5478fde..3d0d45f 100644 --- a/core/src/main/java/io/github/bekoenig/getdown/data/SysProps.java +++ b/core/src/main/java/io/github/bekoenig/getdown/data/SysProps.java @@ -142,6 +142,14 @@ public static boolean useProxy() { return !"false".equals(System.getProperty("use_proxy")); } + /** + * If true, Getdown will detect proxy through Proxy Vole. Default is true. + * Usage: {@code -Duse_proxy=false}. + */ + public static boolean useProxyVole() { + return !"false".equals(System.getProperty("use_proxy")) && !"legacy".equals(System.getProperty("use_proxy")); + } + /** * If true, Getdown will always try to connect without proxy settings even it a proxy is set * in {@code proxy.txt}. If direct access is possible it will not clear {@code proxy.txt}, it @@ -248,4 +256,6 @@ public static String replaceDomain(String appbase) { } return appbase; } + + } diff --git a/core/src/test/java/io/github/bekoenig/getdown/data/SysPropsTest.java b/core/src/test/java/io/github/bekoenig/getdown/data/SysPropsTest.java index 2b135f4..e1d16d9 100644 --- a/core/src/test/java/io/github/bekoenig/getdown/data/SysPropsTest.java +++ b/core/src/test/java/io/github/bekoenig/getdown/data/SysPropsTest.java @@ -106,6 +106,19 @@ void test_useProxy_undefined() { assertThat(useProxy).isTrue(); } + + @Test + @ClearSystemProperty(key = "use_proxy") + void test_useProxyVole_undefined() { + // GIVEN + + // WHEN + boolean useProxyVole = SysProps.useProxyVole(); + + // THEN + assertThat(useProxyVole).isTrue(); + } + @Test @SetSystemProperty(key = "use_proxy", value = "") void test_useProxy_defined() { @@ -118,6 +131,18 @@ void test_useProxy_defined() { assertThat(useProxy).isTrue(); } + @Test + @SetSystemProperty(key = "use_proxy", value = "") + void test_useProxyVole_defined() { + // GIVEN + + // WHEN + boolean useProxyVole = SysProps.useProxyVole(); + + // THEN + assertThat(useProxyVole).isTrue(); + } + @Test @SetSystemProperty(key = "use_proxy", value = "true") void test_useProxy_true() { @@ -142,4 +167,54 @@ void test_useProxy_false() { assertThat(useProxy).isFalse(); } + + @Test + @SetSystemProperty(key = "use_proxy", value = "true") + void test_useProxy_proxyvole() { + // GIVEN + + // WHEN + boolean useProxy = SysProps.useProxy(); + + // THEN + assertThat(useProxy).isTrue(); + } + + + @Test + @SetSystemProperty(key = "use_proxy", value = "legacy") + void test_useProxyVole_proxyvole() { + // GIVEN + + // WHEN + boolean useProxyVole = SysProps.useProxyVole(); + + // THEN + assertThat(useProxyVole).isFalse(); + } + + @Test + @SetSystemProperty(key = "use_proxy", value = "true") + void test_useProxyVole_true() { + // GIVEN + + // WHEN + boolean useProxyVole = SysProps.useProxyVole(); + + // THEN + assertThat(useProxyVole).isTrue(); + } + + @Test + @SetSystemProperty(key = "use_proxy", value = "legacy") + void test_useProxyVole_false() { + // GIVEN + + // WHEN + boolean useProxyVole = SysProps.useProxyVole(); + + // THEN + assertThat(useProxyVole).isFalse(); + } + } diff --git a/launcher/pom.xml b/launcher/pom.xml index 76ff15b..1fdab86 100644 --- a/launcher/pom.xml +++ b/launcher/pom.xml @@ -69,6 +69,11 @@ 22.0.0 test + + org.bidib.com.github.markusbernhardt + proxy-vole + 1.1.6 + diff --git a/launcher/src/main/java/io/github/bekoenig/getdown/launcher/ProxyUtil.java b/launcher/src/main/java/io/github/bekoenig/getdown/launcher/ProxyUtil.java index 81a046a..a1fd86c 100644 --- a/launcher/src/main/java/io/github/bekoenig/getdown/launcher/ProxyUtil.java +++ b/launcher/src/main/java/io/github/bekoenig/getdown/launcher/ProxyUtil.java @@ -9,6 +9,7 @@ import ca.beq.util.win32.registry.RegistryValue; import ca.beq.util.win32.registry.RootKey; import io.github.bekoenig.getdown.data.Application; +import io.github.bekoenig.getdown.data.SysProps; import io.github.bekoenig.getdown.net.Connector; import io.github.bekoenig.getdown.spi.ProxyAuth; import io.github.bekoenig.getdown.util.Config; @@ -16,12 +17,14 @@ import io.github.bekoenig.getdown.util.StringUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.github.markusbernhardt.proxy.ProxySearch; import javax.script.*; import java.io.*; import java.net.*; import java.nio.file.Files; import java.util.Iterator; +import java.util.List; import java.util.ServiceLoader; public final class ProxyUtil { @@ -40,8 +43,15 @@ public static boolean autoDetectProxy(Application app) { port = System.getProperty("http.proxyPort"); } - // check the Windows registry - if (StringUtil.isBlank(host) && LaunchUtil.isWindows()) { + //check using Proxy Vole else check the Windows registry + if (StringUtil.isBlank(host) && SysProps.useProxyVole()) { + Proxy neededProxy = getProxyForInternetAccess(app.getConfigResource().getRemote()); + + if (neededProxy != null) { + host = ((InetSocketAddress) neededProxy.address()).getHostString(); + port = String.valueOf(((InetSocketAddress) neededProxy.address()).getPort()); + } + } else if (LaunchUtil.isWindows()) { try { String rhost = null, rport = null; boolean enabled = false; @@ -85,9 +95,9 @@ public static boolean autoDetectProxy(Application app) { } catch (Throwable t) { LOGGER.atInfo() - .setMessage("Failed to find proxy settings in Windows registry") - .addKeyValue("error", t) - .log(); + .setMessage("Failed to find proxy settings in Windows registry") + .addKeyValue("error", t) + .log(); } } @@ -284,4 +294,49 @@ private static String[] splitHostPort(String hostPort) { private static final String PROXY_REGISTRY = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; + + public static Proxy getProxyForInternetAccess(URL rurl) { + // Use the static factory method getDefaultProxySearch to create a proxy search instance + // configured with the default proxy search strategies for the current environment. + ProxySearch proxySearch = ProxySearch.getDefaultProxySearch(); + + // Invoke the proxy search. This will create a ProxySelector with the detected proxy settings. + ProxySelector proxySelector = proxySearch.getProxySelector(); + + // Install this ProxySelector as default ProxySelector for all connections. + ProxySelector.setDefault(proxySelector); + + // Get list of proxies from default ProxySelector available for given URL + List proxies = null; + if (ProxySelector.getDefault() != null) { + try { + proxies = ProxySelector.getDefault().select(rurl.toURI()); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } + + Proxy proxy = Proxy.NO_PROXY; + // Find first proxy for HTTP/S. Any DIRECT proxy in the list returned is only second choice + if (proxies != null) { + loop: for (Proxy p : proxies) { + switch (p.type()) { + case HTTP: + proxy = p; + break loop; + case DIRECT: + proxy = Proxy.NO_PROXY; + break; + } + } + } + if (proxy != Proxy.NO_PROXY) + return proxy; + else + return null; + } + + } + +