Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connecting with different Proxies to specific addresses

I am developing a Java webservice application (with JAX-WS) that has to use two different proxies to establish separated connections to internet and an intranet. As solution I tried to write my own java.net.ProxySelector that returns a java.net.Proxy instance (of type HTTP) for internet or intranet.

In a little test application I try to download webpage via URL.openConnection(), and before I replaced the default ProxySelector with my own. But it results in an exception:

java.net.SocketException: Unknown proxy type : HTTP at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:370) at java.net.Socket.connect(Socket.java:519) at java.net.Socket.connect(Socket.java:469) at sun.net.NetworkClient.doConnect(NetworkClient.java:163) at sun.net.www.http.HttpClient.openServer(HttpClient.java:394) at sun.net.www.http.HttpClient.openServer(HttpClient.java:529) at sun.net.www.http.HttpClient.(HttpClient.java:233) at sun.net.www.http.HttpClient.New(HttpClient.java:306) at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:844) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:792) at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:703) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1026) at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:373) at norman.test.ProxyTest.conntectToRmViaProxy(ProxyTest.java:42) at norman.test.ProxyTest.main(ProxyTest.java:65)

  1. Question: "Why tries the application to establish a connection via SOCKS, if my ProxySelector only returns a HTTP Proxy?"

2 Question: "Is there a alternative, to define different proxies for each connection?"

This is my ProxySelector:

public class OwnProxySelector extends ProxySelector {
private Proxy intranetProxy;
private Proxy extranetProxy;
private Proxy directConnection = Proxy.NO_PROXY;
private URI intranetAddress;
private URI extranetAddress;

/* (non-Javadoc)
 * @see java.net.ProxySelector#connectFailed(java.net.URI, java.net.SocketAddress, java.io.IOException)
 */
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
    // Nothing to do
}

/* (non-Javadoc)
 * @see java.net.ProxySelector#select(java.net.URI)
 */
public List select(URI uri) {
    ArrayList<Proxy> result = new ArrayList<Proxy>();

    if(intranetAddress.getHost().equals(uri.getHost()) && intranetAddress.getPort()==uri.getPort()){
        result.add(intranetProxy);
        System.out.println("Adding intranet Proxy!");
    }
    else if(extranetAddress.getHost().equals(uri.getHost()) && extranetAddress.getPort()==uri.getPort()){
        result.add(extranetProxy);
        System.out.println("Adding extranet Proxy!");
    }
    else{
        result.add(directConnection);
        System.out.println("Adding direct connection!");
    }

    return result;
}

public void setIntranetProxy(String proxyAddress, int proxyPort){
    if(proxyAddress==null || proxyAddress.isEmpty()){
        intranetProxy = Proxy.NO_PROXY;
    }
    else{
        SocketAddress address = new InetSocketAddress(proxyAddress, proxyPort);
        intranetProxy = new Proxy(Proxy.Type.HTTP, address);
    }
}

public void setExtranetProxy(String proxyAddress, int proxyPort){
    if(proxyAddress==null || proxyAddress.isEmpty()){
        extranetProxy = Proxy.NO_PROXY;
    }
    else{
        SocketAddress address = new InetSocketAddress(proxyAddress, proxyPort);
        extranetProxy = new Proxy(Proxy.Type.HTTP, address);
    }
}

public void clearIntranetProxy(){
    intranetProxy = Proxy.NO_PROXY;
}

public void clearExtranetProxy(){
    extranetProxy = Proxy.NO_PROXY;
}

public void setIntranetAddress(String address) throws URISyntaxException{
    intranetAddress = new URI(address);
}

public void setExtranetAddress(String address) throws URISyntaxException{
    extranetAddress = new URI(address);
}
}

This is the test class:

public class ProxyTest {
OwnProxySelector ownSelector = new OwnProxySelector();

public ProxyTest(){
    ownSelector.setIntranetProxy("intranet.proxy", 8123);
    try {
        ownSelector.setIntranetAddress("http://intranet:80");
    } catch (URISyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    ownSelector.setExtranetProxy("", 0);
    try {
        ownSelector.setExtranetAddress("http://www.example.com:80");
    } catch (URISyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    ProxySelector.setDefault(ownSelector);
}

public void conntectToRmViaProxy(boolean internal, String connectAddress){
    try {
        URL url = new URL(connectAddress);

        HttpURLConnection conn = (HttpURLConnection)url.openConnection();

        conn.setRequestMethod("GET");
          if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
            System.out.println(conn.getResponseMessage());
          }
          else{
              BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
              int tmp = reader.read();
              while(tmp != -1){
                  System.out.print((char)tmp);
                  tmp = reader.read();
              }
          }

    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public static void main(String[] args){
    ProxyTest proxyText = new ProxyTest();
    proxyText.conntectToRmViaProxy(true, "http://intranet:80");
}
}
like image 887
Crazy Doc Avatar asked Feb 01 '10 09:02

Crazy Doc


People also ask

Can you use multiple proxies?

Using multiple proxies to serve different Web services can strengthen your company's internal network security even further. To use multiple proxies, though, you must enable the correct settings in your Web browser.

How do I bypass a proxy for a specific address?

To bypass a range of IP addresses or a specific domain name, specify the addresses in the proxy exception list: In Internet Explorer, on the Tools menu, select Internet Options. On the Connections tab, select LAN Settings. Select Advanced, and type the appropriate information in the Exceptions area.

Can a user setup multiple proxies on the network?

You can configure multiple proxy servers with multiple network interfaces using a load balancer in a multihomed environment.

How do I use a different proxy?

Select the Start button, then select Settings > Network & Internet > VPN. Select the VPN connection, then select Advanced options. Under VPN proxy settings, select the type of proxy setup you want to use, then enter the proxy server information for that VPN connection.


1 Answers

Ok, I have found the problem.

The HttpURLConnection did the OwnProxySelector.select() twice if the requested URL does not contain a port.

At first, HttpURLConnection invoked the select() with an URI, with the Scheme of "http" but no port. The select() checks whether the host address and port are euqal to intranetAddress or extranetAddress. This didn't match, because the port was not given. So the select return a Proxy for a direct connection.

At the second HttpURLConnection invoked the select() with an URI, with the Scheme of "socket" and port 80. So, because the select() checks host address and port, but not the scheme, it returned a HTTP proxy.

Now here is my corrected version of OwnProxySelector. It checks the scheme and sets the default port for HTTP or HTTPS if the port is not given by the URI. Also it asks the Java standard ProxySelector, if no HTTP or HTTPS scheme is given.

public class OwnProxySelector extends ProxySelector {
private ProxySelector defaultProxySelector;
private Proxy intranetProxy;
private Proxy extranetProxy;
private Proxy directConnection = Proxy.NO_PROXY;
private URI intranetAddress;
private URI extranetAddress;


public OwnProxySelector(ProxySelector defaultProxySelector){
    this.defaultProxySelector = defaultProxySelector;
}

/* (non-Javadoc)
 * @see java.net.ProxySelector#connectFailed(java.net.URI, java.net.SocketAddress, java.io.IOException)
 */
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
    // Nothing to do
}

/* (non-Javadoc)
 * @see java.net.ProxySelector#select(java.net.URI)
 */
public List select(URI uri) {
    ArrayList<Proxy> result = new ArrayList<Proxy>();
    
    if(uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")){
        int uriPort = uri.getPort();
        
        // set default http and https ports if port is not given in URI
        if(uriPort<1){
            if(uri.getScheme().equalsIgnoreCase("http")){
                uriPort = 80;
            }
            else if(uri.getScheme().equalsIgnoreCase("https")){
                uriPort = 443;
            }
        }
        
        if(intranetAddress.getHost().equals(uri.getHost()) && intranetAddress.getPort()==uriPort){
            result.add(intranetProxy);
            System.out.println("Adding intranet Proxy!");
        }
        else if(extranetAddress.getHost().equals(uri.getHost()) && extranetAddress.getPort()==uriPort){
            result.add(extranetProxy);
            System.out.println("Adding extranet Proxy!");
        }
    }
    
    if(result.isEmpty()){
        List<Proxy> defaultResult = defaultProxySelector.select(uri);
        if(defaultResult!=null && !defaultResult.isEmpty()){
            result.addAll(defaultResult);
            System.out.println("Adding Proxis from default selector.");
        }
        else{
            result.add(directConnection);
            System.out.println("Adding direct connection, because requested URI does not match any Proxy");
        }
    }
    
    return result;
}

public void setIntranetProxy(String proxyAddress, int proxyPort){
    if(proxyAddress==null || proxyAddress.isEmpty()){
        intranetProxy = Proxy.NO_PROXY;
    }
    else{
        SocketAddress address = new InetSocketAddress(proxyAddress, proxyPort);
        intranetProxy = new Proxy(Proxy.Type.HTTP, address);
    }
}

public void setExtranetProxy(String proxyAddress, int proxyPort){
    if(proxyAddress==null || proxyAddress.isEmpty()){
        extranetProxy = Proxy.NO_PROXY;
    }
    else{
        SocketAddress address = new InetSocketAddress(proxyAddress, proxyPort);
        extranetProxy = new Proxy(Proxy.Type.HTTP, address);
    }
}

public void clearIntranetProxy(){
    intranetProxy = Proxy.NO_PROXY;
}

public void clearExtranetProxy(){
    extranetProxy = Proxy.NO_PROXY;
}

public void setIntranetAddress(String address) throws URISyntaxException{
    intranetAddress = new URI(address);
}

public void setExtranetAddress(String address) throws URISyntaxException{
    extranetAddress = new URI(address);
}

}

But it is curious to me, that the HttpURLConnection did a second invoke of select(), when it got a direct connection Proxy from the first invoke.

like image 93
Crazy Doc Avatar answered Sep 30 '22 09:09

Crazy Doc