ネットワーク環境:
Https Client <=============> Proxy Server <==============> Https Server
192.168.17.11 <----- extranet ------> 192.168.17.22
10.100.21.10 <----イントラネット-----> 10.100.21.11ps:デフォルトゲートウェイのないHttpクライアントですが、10.100.21.11にpingできます
説明:
OS:3つのホスト上のUbuntu 12.04
Httpsクライアント:Java(openjdk-6)を使用して実装します。ネットワークインターフェイスを1つ用意します。
プロキシサーバー:Apache2.2.2つのネットワークインターフェイスを用意します。
Httpsサーバー:Tomcat6。ネットワークインターフェイスが1つあります。
2つの方法を使用して、プロキシ経由でhttpsurlconnectionを実装します。
(簡単にするため、serverTrustedおよびhostnameVerifierの問題を確認するためのsslハンドル関数について書き留めません。必要に応じて更新します。)
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メソッドを使用する場合:
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はProxyServerにpingできます(10.100.12.10 ping 10.100.21.11)
したがって、プロキシ設定を削除します(プロキシを使用しない場合)。
またNoRouteToHostException: Network is unreachable
。
これは合理的だと思いました。エクストラネットへのルートがないためです。
setPropertyメソッドがhttpsUrlConnectionの内部関数がこのURLに到達できるかどうかをチェックする方法だと思います。
しかし、それは奇妙です。最初の方法は成功する可能性があります。
何かアイデアがありますか?または、1番目の方法と2番目の方法の違いは何ですか?
++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++
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");
[〜#〜] edit [〜#〜] @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();