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

网络环境:

Https客户端代理服务器 Https服务器
192.168.17.11 192.168.17.22
10.100.21.10 10.100.21.11

ps:没有默认网关的Http客户端,但它可以ping到10.100.21.11

描述:

操作系统:3台主机上的Ubuntu 12.04
Https Client:用java实现(openjdk-6)。有一个网络接口。
代理服务器:Apache2.2。有两个网络接口。
Https服务器:Tomcat6.Have一个网络接口。

我使用两种方法通过代理实现httpsurlconnection
(为方便起见 ,我没有写下关于ssl句柄函数来检查serverTrustedhostnameVerifier问题。如果需要我会更新。)

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("test"); 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("test"); 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"); 

如下所示,它会引发exception:

 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();