如何通过setProperty通过代理使用HttpsURLConnection?1.代理类2.设置属性更新

网络环境:

Https Client<==========>Proxy Server<==============>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

描述:

OS: Ubuntu 12.04 on 3 hosts
Https Client: Implement with 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.设置属性

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

我得到了一个.
这让我感到困惑。我没有看到HttpClient和ProxyServer之间的任何数据包。
但是HttpClient可以ping到ProxyServer(10.100.12.10 ping 10.100.21.11)NoRouteToHostException: Network is unreachable

所以我删除了代理设置(因为不使用代理):
也得到了.
我认为这是合理的。因为没有通往外联网的途径。NoRouteToHostException: Network is unreachable

我想这似乎是设置Property方法,httpsUrlConnection的内部功能将检查这个网址是否可以访问。

但这很奇怪。第一种方法可以成功。

有什么想法吗?或者第一和第二种方法之间有什么区别?

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

更新

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也必须修改为正确的配置。


答案 1

您的 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 ..我复制了您的原始问题并包含在答案中。


答案 2

您需要为其创建一个对象。创建一个,如下所示:Proxy

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

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

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

如果必须设置代理的凭据,请设置 request 属性: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();

推荐