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

CJe*_*emy 14 java proxy networking outputstream httpsurlconnection

网络环境:

Https客户端<=============>代理服务器<==============> Https Server
                                                  192.168.17.11 <----- extranet --- ---> 192.168.17.22
10.100.21.10 <---- intranet -----> 10.100.21.11

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

描述:

操作系统:3台主机上的Ubuntu 12.04
Https客户端:用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("<request>test</request>");
owriter.flush();
owriter.close();
...
Run Code Online (Sandbox Code Playgroud)

这种方法可行,我观察到数据包流量也符合我的期望.
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();
...
Run Code Online (Sandbox Code Playgroud)

我有一个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"); 
Run Code Online (Sandbox Code Playgroud)

它可以工作,数据包流是正确的我期望的.
但设置https.proxyPort = 443对我来说是行不通的

System.setProperty("https.proxyPort","443");
Run Code Online (Sandbox Code Playgroud)

如下所示,它会引发异常:

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

所以我认为Apache Proxy也需要修改为正确的配置.

Kal*_*Kal 17

您的URL连接是https,而您只是设置http代理.

尝试设置https代理.

//System.setProperty("https.proxySet", "true"); 
 System.setProperty("https.proxyHost",10.100.21.11);
 System.setProperty("https.proxyPort","443");
Run Code Online (Sandbox Code Playgroud)

编辑 @EJP是正确的.没有https.proxySet ..我复制了您的原始问题并包含在答案中.


div*_*gon 9

您需要Proxy为它创建一个对象.创建一个如下:

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, Integer.parseInt(proxyPort)));
Run Code Online (Sandbox Code Playgroud)

现在使用此代理来创建HttpURLConnection对象.

HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(proxy);
Run Code Online (Sandbox Code Playgroud)

如果必须设置代理的凭据,请设置Proxy-Authorizationrequest属性:

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

最后,你连接:

connection.connect();
Run Code Online (Sandbox Code Playgroud)