Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use HttpsURLConnection through proxy by setProperty?

Network environment:

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 Client without default gateway, but it can ping to 10.100.21.11

Description:

OS: Ubuntu 12.04 on 3 hosts
Https Client: Implement with java(openjdk-6).Have one network-interface.
Proxy Server: Apache2.2.Have two network-interfaces.
Https Server: Tomcat6.Have one network-interface.

I use two method to implement httpsurlconnection through proxy:
(For facilitate I do not write down about ssl handle function for checking serverTrusted and hostnameVerifier issue.If need I will update.)

1.Proxy class

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

This method workable and I observed packets flow also met my expectation.
HttpClient ---> ProxyServer ---> HttpServer

But when I use set Property method:

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

I got a NoRouteToHostException: Network is unreachable.
It make me confused.I did not see any packets between HttpClient and ProxyServer.
But HttpClient can ping to ProxyServer(10.100.12.10 ping 10.100.21.11)

So I remove proxy setting(as without using proxy):
Also got NoRouteToHostException: Network is unreachable.
I thought this is reasonable.Because there is no route to extranet.

I guess it seems like to setProperty method that the inner function of httpsUrlConnection will to check this url can be reachable or not.

But it is weird. 1st method can be success.

Have any idea? Or what are different between 1st and 2nd method?

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

Update

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

It can work and packets flow are correct what I expect for.
But set https.proxyPort=443 is not workable for me

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

It will thorow a exception as bellow:

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

So I thought Apache Proxy have also to be modified to the right configuration.

like image 837
CJeremy Avatar asked Apr 10 '13 13:04

CJeremy


People also ask

How to send http request through proxy in Java?

URL weburl = new URL(URL_STRING); Proxy webProxy = new Proxy(Proxy. Type. HTTP, new InetSocketAddress("127.0. 0.1", 3128)); HttpURLConnection webProxyConnection = (HttpURLConnection) weburl.

How do I make HttpURLConnection use a proxy?

HttpURLConnection webProxyConnection = (HttpURLConnection) weburl. openConnection(webProxy); Now, we'll connect to URL_STRING but then route that connection through a proxy server hosted at 127.0. 0.1:8080.

How do I configure proxy settings for Java?

Configure Proxies through the Java Control PanelIn the Java Control Panel, under the General tab, click on Network Settings. Select the Use Browser Settings checkbox. Click OK to save your changes. Close all browser windows.

What is proxy service in Java?

Proxy server is an intermediary server between client and the internet. Proxy servers offers the following basic functionalities: Firewall and network data filtering. Network connection sharing. Data caching.


3 Answers

Your URL connection is https whereas you are only setting the http proxy.

Try setting the https proxy.

//System.setProperty("https.proxySet", "true"); 
 System.setProperty("https.proxyHost",10.100.21.11);
 System.setProperty("https.proxyPort","443");

EDIT @EJP is correct. There is no https.proxySet .. I copied your original question and included in the answer.

like image 173
Kal Avatar answered Oct 02 '22 14:10

Kal


You will need to create a Proxy object for it. Create one as below:

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

Now use this proxy to create the HttpURLConnection object.

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

If you have to set the credentials for the proxy, set the Proxy-Authorization request property:

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

And finally, you connect:

connection.connect();
like image 31
divinedragon Avatar answered Oct 02 '22 12:10

divinedragon


thank you @divinedragon!

Same code on kotlin:

 fun testProxy(login: String, pass: String, proxyData: ProxyData): String {
    val url = URL("http://api.ipify.org")
    val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress(proxyData.ip, proxyData.port))
    val connection = url.openConnection(proxy) as HttpURLConnection

    val loginPass = "$login:$pass"
    val encodedLoginPass = Base64.getEncoder().encodeToString(loginPass.toByteArray())
    val authString = "Basic $encodedLoginPass"
    connection.setRequestProperty("Proxy-Authorization", authString);
    with(connection) {
        requestMethod = "GET"  // optional default is GET
        connectTimeout = 2000
        readTimeout = 2000
        return inputStream.bufferedReader().readText()
    }
}
like image 42
MeGaPk Avatar answered Oct 02 '22 12:10

MeGaPk