如何为单个 HttpsURLConnection 设置 https.proxyHost 和 https.proxyPort?
How can I set https.proxyHost and https.proxyPort for individual HttpsURLConnections?
我正在尝试通过代理发出 HTTPS 请求。这是我到目前为止所得到的,基于 this question:
中的代码
try {
HttpsURLConnection connection = (HttpsURLConnection) new URL("https://proxylist.geonode.com/api/proxy-list?limit=1&page=1&sort_by=speed&sort_type=asc&protocols=https").openConnection();
connection.setRequestMethod("GET");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36");
connection.setConnectTimeout(30000);
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String rawJSON = reader.readLine();
if(rawJSON == null) throw new IOException("No data");
JSONObject data = new JSONObject(rawJSON).getJSONArray("data").getJSONObject(0);
String ipAddress = data.getString("ip"), port = data.getString("port");
System.setProperty("https.proxyHost", ipAddress);
System.setProperty("https.proxyPort", port);
SSLContext sslContext = SSLContext.getInstance("SSL");
// set up a TrustManager that trusts everything
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
} }, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier((arg0, arg1) -> true);
HttpsURLConnection testConnection = (HttpsURLConnection) new URL("https://example.com").openConnection();
testConnection.connect();
StringBuilder result = new StringBuilder();
String line;
try(BufferedReader reader2 = new BufferedReader(new InputStreamReader(testConnection.getInputStream()))) {
while ((line = reader2.readLine()) != null) result.append(line);
}
System.out.println(result);
} catch(Exception e) {
e.printStackTrace();
}
代码有效,但有问题。我的应用程序 (https://encyclosearch.org) 是多线程的,我需要通过代理发出一些请求,一些直接发出请求。由于系统属性是全局的,如果我使用 System.setProperty
设置 https.proxyHost
和 https.proxyPort
,一些不应该通过代理的请求将通过代理。
我可以这样使用java.net.Proxy
:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipAddress, Integer.parseInt(port)));
HttpsURLConnection testConnection = (HttpsURLConnection) new URL("http://example.com").openConnection(proxy);
但这只适用于 HTTP 代理,不适用于 HTTPS 代理,所以我无法发出 HTTPS 请求。没有Proxy.Type.HTTPS
.
如有任何帮助,我们将不胜感激。提前致谢。
如果您选择哪些连接通过代理,哪些连接不通过目标 url,那么您可以使用 属性 http.nonProxyHosts。如文档所述,此 属性 用于 http 和 https:
for the "non proxy hosts" list, the HTTPS protocol handler will use the same as the http handler (i.e. http.nonProxyHosts).
您通过添加由 | 分隔的 url 的模式来设置 属性 值例如:
System.setProperty("http.nonProxyHosts", ”localhost|host.example.com”)
您还可以使用 ProxySelector class 选择哪些连接通过代理。有关更多信息(有点旧):
https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
至于没有 Proxy.Type.HTTPS,这是因为代理通常不是最终目的地,因此安全连接将与最终目的地而不是代理本身有关。有通过代理的 SSL 隧道之类的东西,但我不太了解它。
在@Bashi 的帮助下,我弄明白了。对于直接连接,我使用了:
url.openConnection(Proxy.NO_PROXY);
这也适用于 Jsoup:
Document document = Jsoup.connect("https://example.com").proxy(Proxy.NO_PROXY).get();
来自https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html的解释:
Now, this guarantees you that this specific URL will be retrieved though a direct connection bypassing any other proxy settings, which can be convenient.
我正在尝试通过代理发出 HTTPS 请求。这是我到目前为止所得到的,基于 this question:
中的代码try {
HttpsURLConnection connection = (HttpsURLConnection) new URL("https://proxylist.geonode.com/api/proxy-list?limit=1&page=1&sort_by=speed&sort_type=asc&protocols=https").openConnection();
connection.setRequestMethod("GET");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36");
connection.setConnectTimeout(30000);
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String rawJSON = reader.readLine();
if(rawJSON == null) throw new IOException("No data");
JSONObject data = new JSONObject(rawJSON).getJSONArray("data").getJSONObject(0);
String ipAddress = data.getString("ip"), port = data.getString("port");
System.setProperty("https.proxyHost", ipAddress);
System.setProperty("https.proxyPort", port);
SSLContext sslContext = SSLContext.getInstance("SSL");
// set up a TrustManager that trusts everything
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
} }, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier((arg0, arg1) -> true);
HttpsURLConnection testConnection = (HttpsURLConnection) new URL("https://example.com").openConnection();
testConnection.connect();
StringBuilder result = new StringBuilder();
String line;
try(BufferedReader reader2 = new BufferedReader(new InputStreamReader(testConnection.getInputStream()))) {
while ((line = reader2.readLine()) != null) result.append(line);
}
System.out.println(result);
} catch(Exception e) {
e.printStackTrace();
}
代码有效,但有问题。我的应用程序 (https://encyclosearch.org) 是多线程的,我需要通过代理发出一些请求,一些直接发出请求。由于系统属性是全局的,如果我使用 System.setProperty
设置 https.proxyHost
和 https.proxyPort
,一些不应该通过代理的请求将通过代理。
我可以这样使用java.net.Proxy
:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipAddress, Integer.parseInt(port)));
HttpsURLConnection testConnection = (HttpsURLConnection) new URL("http://example.com").openConnection(proxy);
但这只适用于 HTTP 代理,不适用于 HTTPS 代理,所以我无法发出 HTTPS 请求。没有Proxy.Type.HTTPS
.
如有任何帮助,我们将不胜感激。提前致谢。
如果您选择哪些连接通过代理,哪些连接不通过目标 url,那么您可以使用 属性 http.nonProxyHosts。如文档所述,此 属性 用于 http 和 https:
for the "non proxy hosts" list, the HTTPS protocol handler will use the same as the http handler (i.e. http.nonProxyHosts).
您通过添加由 | 分隔的 url 的模式来设置 属性 值例如:
System.setProperty("http.nonProxyHosts", ”localhost|host.example.com”)
您还可以使用 ProxySelector class 选择哪些连接通过代理。有关更多信息(有点旧): https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
至于没有 Proxy.Type.HTTPS,这是因为代理通常不是最终目的地,因此安全连接将与最终目的地而不是代理本身有关。有通过代理的 SSL 隧道之类的东西,但我不太了解它。
在@Bashi 的帮助下,我弄明白了。对于直接连接,我使用了:
url.openConnection(Proxy.NO_PROXY);
这也适用于 Jsoup:
Document document = Jsoup.connect("https://example.com").proxy(Proxy.NO_PROXY).get();
来自https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html的解释:
Now, this guarantees you that this specific URL will be retrieved though a direct connection bypassing any other proxy settings, which can be convenient.