2013-04-10 35 views
12

網絡環境:
如何通過setProperty通過代理使用HttpsURLConnection?

HTTPS客戶端< =============>代理服務器< ==============> HTTPS服務器
                                                                                                    192.168.17.11 < -----外聯網------> 192.168.17.22
10.100.21.10 < ---- intranet -----> 10.10 0.21.11

PS:沒有的Http默認網關的客戶端,但它可以ping到10.100.21.11

說明:

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

我使用兩種方法,通過代理實現HttpsURLConnection的
(爲了方便我不寫下關於SSL處理功能檢查serverTrusted的HostnameVerifier issue.If需要我會更新。 )

1.Proxy類

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 --->訪問代理服務器--->的HttpServer

但是當我使用set屬性方法:

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到訪問代理服務器(10.100.12.10平10.100.21.11)

所以我刪除代理服務器設置(如不使用代理):
也得到了NoRouteToHostException: Network is unreachable
我認爲這是合理的。因爲沒有路由到Extranet。

我想它似乎想的setProperty方法HttpsURLConnection的內功能意願來檢查這個URL可以到達與否。

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

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

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

更新

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

它可以工作和數據包流是正確的我所期望的。
但設置https.proxyPort = 443是行不通的,我

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

它將爲波紋管thorow一個例外:

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

因此,我認爲Apache代理也紛紛進行修改,以正確的配置。

+0

有沒有這樣的財產HTTP .proxySet。 – EJP 2013-04-10 22:34:02

+0

是的。這個屬性真的不需要設置。謝謝〜 – CJeremy 2013-04-11 09:55:19

回答

13

您的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 ..我複製了您的原始問題幷包含在答案中。

+0

https.proxySet沒有這樣的屬性。 – EJP 2013-04-10 22:34:48

+0

我認爲這是正確的答案,同時發送請求「https」url。 setProperty的關鍵是https。proxyHost/proxyPort而不是http.proxyHost/porxyPort。 – CJeremy 2013-04-11 09:54:26

7

您需要爲它創建一個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(); 
+0

謝謝你的回覆。 首先,我用第一種方法創建一個代理對象,它對我來說是可行的。 其次,我需要的網址是「https」,所以我認爲使用HttpsURLConnection是正確的。 – CJeremy 2013-04-11 10:03:13