不对回环地址应用代理 (#4338)
This commit is contained in:
@@ -19,22 +19,28 @@ package org.jackhuang.hmcl.setting;
|
||||
|
||||
import javafx.beans.InvalidationListener;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public final class ProxyManager {
|
||||
|
||||
private static final ProxySelector NO_PROXY = new SimpleProxySelector(Proxy.NO_PROXY);
|
||||
private static final ProxySelector SYSTEM_DEFAULT = Objects.requireNonNullElse(ProxySelector.getDefault(), NO_PROXY);
|
||||
private static final SimpleProxySelector NO_PROXY = new SimpleProxySelector(Proxy.NO_PROXY);
|
||||
private static final ProxySelector SYSTEM_DEFAULT;
|
||||
|
||||
static {
|
||||
ProxySelector systemProxySelector = ProxySelector.getDefault();
|
||||
SYSTEM_DEFAULT = systemProxySelector != null
|
||||
? new ProxySelectorWrapper(systemProxySelector)
|
||||
: NO_PROXY;
|
||||
}
|
||||
|
||||
private static volatile @NotNull ProxySelector defaultProxySelector = SYSTEM_DEFAULT;
|
||||
private static volatile @Nullable SimpleAuthenticator defaultAuthenticator = null;
|
||||
@@ -51,7 +57,7 @@ public final class ProxyManager {
|
||||
LOG.warning("Illegal proxy port: " + port);
|
||||
return NO_PROXY;
|
||||
} else {
|
||||
return new SimpleProxySelector(new Proxy(proxyType, new InetSocketAddress(host, port)));
|
||||
return new ProxySelectorWrapper(new SimpleProxySelector(new Proxy(proxyType, new InetSocketAddress(host, port))));
|
||||
}
|
||||
} else {
|
||||
return ProxyManager.SYSTEM_DEFAULT;
|
||||
@@ -106,15 +112,41 @@ public final class ProxyManager {
|
||||
config().proxyPassProperty().addListener(updateAuthenticator);
|
||||
}
|
||||
|
||||
private static final class SimpleProxySelector extends ProxySelector {
|
||||
private static abstract class AbstractProxySelector extends ProxySelector {
|
||||
@Override
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
|
||||
if (uri == null || sa == null || ioe == null) {
|
||||
throw new IllegalArgumentException("Arguments can't be null.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SimpleProxySelector extends AbstractProxySelector {
|
||||
private final List<Proxy> proxies;
|
||||
|
||||
SimpleProxySelector(Proxy proxy) {
|
||||
this(Collections.singletonList(proxy));
|
||||
this.proxies = List.of(proxy);
|
||||
}
|
||||
|
||||
SimpleProxySelector(List<Proxy> proxies) {
|
||||
this.proxies = proxies;
|
||||
@Override
|
||||
public List<Proxy> select(URI uri) {
|
||||
if (uri == null)
|
||||
throw new IllegalArgumentException("URI can't be null.");
|
||||
return proxies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SimpleProxySelector" + proxies;
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps another ProxySelector to avoid using proxy for loopback addresses.
|
||||
private static final class ProxySelectorWrapper extends AbstractProxySelector {
|
||||
private final ProxySelector source;
|
||||
|
||||
ProxySelectorWrapper(ProxySelector source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,19 +154,10 @@ public final class ProxyManager {
|
||||
if (uri == null)
|
||||
throw new IllegalArgumentException("URI can't be null.");
|
||||
|
||||
return proxies;
|
||||
}
|
||||
if (NetworkUtils.isLoopbackAddress(uri))
|
||||
return NO_PROXY.proxies;
|
||||
|
||||
@Override
|
||||
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
|
||||
if (uri == null || sa == null || ioe == null) {
|
||||
throw new IllegalArgumentException("Arguments can't be null.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SimpleProxySelector" + proxies;
|
||||
return source.select(uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package org.jackhuang.hmcl.util.io;
|
||||
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
@@ -45,6 +46,19 @@ public final class NetworkUtils {
|
||||
private NetworkUtils() {
|
||||
}
|
||||
|
||||
public static boolean isLoopbackAddress(URI uri) {
|
||||
String host = uri.getHost();
|
||||
if (StringUtils.isBlank(host))
|
||||
return false;
|
||||
|
||||
try {
|
||||
InetAddress addr = InetAddress.getByName(host);
|
||||
return addr.isLoopbackAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isHttpUri(URI uri) {
|
||||
return "http".equals(uri.getScheme()) || "https".equals(uri.getScheme());
|
||||
}
|
||||
|
||||
@@ -19,17 +19,31 @@ package org.jackhuang.hmcl.util.io;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.jackhuang.hmcl.util.io.NetworkUtils.encodeLocation;
|
||||
import static org.jackhuang.hmcl.util.io.NetworkUtils.getCharsetFromContentType;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.jackhuang.hmcl.util.io.NetworkUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* @author Glavo
|
||||
*/
|
||||
public class NetworkUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testIsLoopbackAddress() {
|
||||
assertTrue(isLoopbackAddress(URI.create("https://127.0.0.1/test")));
|
||||
assertTrue(isLoopbackAddress(URI.create("https://127.0.0.1:8080/test")));
|
||||
assertTrue(isLoopbackAddress(URI.create("https://localhost/test")));
|
||||
assertTrue(isLoopbackAddress(URI.create("https://localhost:8080/test")));
|
||||
assertTrue(isLoopbackAddress(URI.create("https://[::1]/test")));
|
||||
assertTrue(isLoopbackAddress(URI.create("https://[::1]:8080/test")));
|
||||
|
||||
assertFalse(isLoopbackAddress(URI.create("https://www.example.com/test")));
|
||||
assertFalse(isLoopbackAddress(URI.create("https://www.example.com:8080/test")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeLocation() {
|
||||
assertEquals("https://github.com", encodeLocation("https://github.com"));
|
||||
|
||||
Reference in New Issue
Block a user