簡體   English   中英

如何通過 setProperty 通過代理使用 HttpsURLConnection?

[英]How to use HttpsURLConnection through proxy by setProperty?

網絡環境:

Https 客戶端<==============>代理服務器<==============>Https 服務器
192.168.17.11<-----外網------>192.168.17.22
10.100.21.10<----內網---->10.100.21.11

ps:沒有默認網關的Http Client,但是可以ping到10.100.21.11

描述:

操作系統:3 台主機上的 Ubuntu 12.04
Https Client:用java(openjdk-6)實現。有一個網絡接口。
代理服務器:Apache2.2。有兩個網絡接口。
Https Server:Tomcat6。有一個網絡接口。

我使用兩種方法通過代理實現httpsurlconnection
(為了方便我沒有寫關於檢查serverTrustedhostnameVerifier問題的ssl句柄函數。如果需要我會更新。)

1.代理類

InetSocketAddress proxyInet = new InetSocketAddress("10.100.21.11",80);
Proxy proxy = new Proxy(Proxy.Type.HTTP, proxyInet);
URL httpsUrl = new URL("https://192.168.17.22:8443/test");
HttpsURLConnection httpsCon = (HttpsURLConnection) httpsUrl.openConnection(proxy);

httpsCon.setDoOutput(true);
httpsCon.setDoInput(true);
httpsCon.setRequestMethod("POST");
OutputStream out = httpsCon.getOutputStream();
OutputStreamWriter owriter = new OutputStreamWriter(out);

owriter.write("<request>test</request>");
owriter.flush();
owriter.close();
...

這種方法可行,我觀察到的數據包流也符合我的預期。
HttpClient ---> ProxyServer ---> HttpServer

但是當我使用 set Property 方法時:

2.setProperty

System.setProperty("http.proxySet", "true");
System.setProperty("http.proxyHost",10.100.21.11);
System.setProperty("http.proxyPort","80");

URL httpsUrl = new URL("https://192.168.17.22:8443/test");
HttpsURLConnection httpsCon = (HttpsURLConnection)httpsUrl.openConnection();

httpsCon.setDoOutput(true);
httpsCon.setDoInput(true);
httpsCon.setRequestMethod("POST");
OutputStream out = httpsCon.getOutputStream();
OutputStreamWriter owriter = new OutputStreamWriter(out);

owriter.write("<request>test</request>");
owriter.flush();
owriter.close();
...

我收到了NoRouteToHostException: Network is unreachable
這讓我很困惑。我沒有看到 HttpClient 和 ProxyServer 之間的任何數據包。
但是HttpClient可以ping到ProxyServer(10.100.12.10 ping 10.100.21.11)

所以我刪除了代理設置(如不使用代理):
還得到了NoRouteToHostException: Network is unreachable
我認為這是合理的。因為沒有到外網的路由。

我猜這似乎是setProperty方法, httpsUrlConnection的內部函數將檢查此 url 是否可以訪問。

但這很奇怪。 第一種方法可以成功。

有什么想法嗎? 或者第一種和第二種方法有什么不同?

++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++

更新

System.setProperty("https.proxyHost",10.100.21.11);
System.setProperty("https.proxyPort","80"); 

它可以工作,並且數據包流是我所期望的。
但是設置 https.proxyPort=443 對我不起作用

System.setProperty("https.proxyPort","443");

它會拋出一個異常如下:

java.net.SocketException: Unexpected end of file from server 
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:770)
....

所以我認為 Apache Proxy 也必須修改為正確的配置。

您的 URL 連接是 https 而您只設置了 http 代理。

嘗試設置 https 代理。

//System.setProperty("https.proxySet", "true"); 
 System.setProperty("https.proxyHost",10.100.21.11);
 System.setProperty("https.proxyPort","443");

編輯@EJP 是正確的。 沒有 https.proxySet .. 我復制了您的原始問題並包含在答案中。

您需要為它創建一個Proxy對象。 創建一個如下:

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, Integer.parseInt(proxyPort)));

現在使用這個代理來創建HttpURLConnection對象。

HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(proxy);

如果必須為代理設置憑據,請設置Proxy-Authorization請求屬性:

String uname_pwd = proxyUsername + ":" + proxyPassword
String authString = "Basic " + new sun.misc.BASE64Encoder().encode(uname_pwd.getBytes())
connection.setRequestProperty("Proxy-Authorization", authString);

最后,您連接:

connection.connect();

謝謝@divinedragon!

kotlin 上的相同代碼:

 fun testProxy(login: String, pass: String, proxyData: ProxyData): String {
    val url = URL("http://api.ipify.org")
    val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress(proxyData.ip, proxyData.port))
    val connection = url.openConnection(proxy) as HttpURLConnection

    val loginPass = "$login:$pass"
    val encodedLoginPass = Base64.getEncoder().encodeToString(loginPass.toByteArray())
    val authString = "Basic $encodedLoginPass"
    connection.setRequestProperty("Proxy-Authorization", authString);
    with(connection) {
        requestMethod = "GET"  // optional default is GET
        connectTimeout = 2000
        readTimeout = 2000
        return inputStream.bufferedReader().readText()
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM