gpt4 book ai didi

java - ProxySelector 从 https ://to socket://更改 URL 的方案

转载 作者:可可西里 更新时间:2023-11-01 16:25:58 25 4
gpt4 key购买 nike

我需要访问 Facebook,但所有传出通信在我们的服务器上都被阻止,所以我必须使用代理。

我初始化代理:

ProxySelector.setDefault(new ConfigurableProxySelector(mapping));

代理类型为 HTTP,代理主机和端口正常工作(通过简单的 wget 测试确认)。

我正在尝试这样做:

HttpClient httpClient = new HttpClient();
HttpMethod method = new GetMethod("https://graph.facebook.com:443");

int status = httpClient.executeMethod(method);

现在,在我的类 ConfigurableProxySelector 中,我有选择方法,我在上面设置了断点:

public List<Proxy> select(URI uri) {
...
}

因此,我使用 HttpClient 发出一个请求,该请求应该被代理并且代码在 ConfigurableProxySelector 的 select() 方法中的断点处停止。

但奇怪的是 uri.scheme = "socket"和 .toString() 给出的是 "socket://graph.facebook.com:443"而不是 "https://graph.facebook.com:443".

因为 ProxySelector 有“https://”的映射而不是“socket://”的映射,它找不到它并以“连接被拒绝”结束。奇怪的是,select() 方法在执行以“Connection refused”结束之前被调用了 4 次。

如有任何帮助,我们将不胜感激。

最佳答案

Apache HTTP Client 3.1 本身不会支持从默认 ProxySelector 或用户实现返回的 HTTP 代理。

ProxySelector 的快速总结

ProxySelector 是一个服务类,它根据其方案为给定的 URL 选择并返回合适的代理。例如,对 http://somehost 的请求将尝试提供 HTTP 代理(如果已定义的话)。可以在运行时使用系统属性配置默认 ProxySelector,例如 http.proxyHosthttp.proxyPort

HTTPUrlConnection

HTTPUrlConnection 的实例将多次检查默认的 ProxySelector:第一次选择 httphttps,然后在构建原始 tcp 套接字时,使用套接字 方案。 SOCKS 代理可用于代理原始 tcp 套接字,但在公司环境中并不常见,因此原始 tcp 套接字通常不会接收任何代理。

HTTP 客户端 3.1

另一方面,HC 3.1 将永远不会检查 http/https 方案的默认 ProxySelector。但是,它将在稍后最终构建原始套接字时检查 socket 方案 - 这就是您看到的请求。这意味着系统属性 http.proxyHosthttp.proxyPort 无效。对于大多数只有 HTTP/HTTPS 代理的人来说,这显然不理想。

要解决此问题,您有两个选择:在每个 HC 3.1 连接上定义一个代理或实现您自己的 HC 3.1 HTTPConnectionManager。

HTTP连接管理器

HTTPConnectionManager 负责为 HC 3.1 客户端建立连接。

可以扩展默认的 HC 3.1 HTTPConnectionManager,以便它在以与 HTTPUrlConnection 相同的方式构建请求时从 ProxySelector(默认或自定义)寻找合适的代理:

public class MyHTTPConnectionManager extends SimpleHttpConnectionManager {
@Override
public HttpConnection getConnectionWithTimeout(
HostConfiguration hostConfiguration, long timeout) {
HttpConnection hc = super.getConnectionWithTimeout(hostConfiguration, timeout);

try {
URI uri = new URI( hostConfiguration.getHostURL());
List<Proxy> hostProxies = ProxySelector.getDefault().select(uri);
Proxy Proxy = hostProxies.get(0);

InetSocketAddress sa = (InetSocketAddress) Proxy.address();
hc.setProxyHost(sa.getHostName());
hc.setProxyPort(sa.getPort());

} catch (URISyntaxException e) {
return hc;
}
return hc;
}
}

然后,当您创建 HC 3.1 客户端时,使用您的新连接管理器:

HttpClient client = new HttpClient(new MyHTTPConnectionManager() );

关于java - ProxySelector 从 https ://to socket://更改 URL 的方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7413552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com