After reading this excellent guide on proxies in Java, I decided to try using the ProxySelector mechanism. The results were awesome!!
Using ProxySelector gives us the flexibility to :
- decide whether a proxy should be used or not for a URI being connected to. You can choose not to use a proxy altogether.
- specify what proxies (yes multiple!) to use - including varying protocols in each proxy
- manage failures when connecting to proxy servers
- Extended a new class from Java's java.net.ProxySelector
- The select method of this class (which is an override of the abstract method from the ProxySelector class), would be called each time Java tries to make a network connection - querying for the proxy to be used for that connection. The URI being connected to is passed to the method. I checked the attributes of this URI and if matched the hostname that my code used to connect to (which did not work via a proxy), I returned a java.net.Proxy.NO_PROXY to signify that no proxy should be used for this URI.
- For all other URIs, I did not want to fidget with the user's settings, so I delegated the proxy decision making to the default ProxySelector that ships with Java
/**
* Created by : Madhur Tanwani
* Created on : May 28, 2010
*/
package edu.madhurtanwani.net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
/**
*
* @author Madhur Tanwani (madhurt@yahoo-inc.com)
*/
class CustomProxySelector extends ProxySelector {
private final ProxySelector def;
CustomProxySelector(ProxySelector aDefault) {
this.def = aDefault;
}
@Override
public List<Proxy> select(URI uri) {
System.out.println("select for URL : " + uri);
if ("http".equalsIgnoreCase(uri.getScheme()) || "socket".equalsIgnoreCase(uri.getScheme())) {
if (uri.getHost().startsWith("mail")) {
List<Proxy> proxyList = new ArrayList<Proxy>();
proxyList.add(Proxy.NO_PROXY);
System.out.println("NO PROXY TO BE USED");
return proxyList;
}
}
//Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("socks.corp.yahoo.com", 1080));
List<Proxy> select = def.select(uri);
System.out.println("Default proxy list : " + select);
return select;
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
/**
*
* @author Madhur Tanwani (madhurt@yahoo-inc.com)
*/
public class Socks_Public {
private static final String URL_BEHIND_SOCKS = "http://yahoo.com";
private static final String URL_NO_SOCKS = "http://mail.yahoo.com";
public static void main(String[] args) throws Exception {
ProxySelector.setDefault(new CustomProxySelector(ProxySelector.getDefault()));
System.out.println("\n\n++++++++++++++++++++USING HTTP CLIENT++++++++++++++++++++");
HttpClient client = new HttpClient();
System.out.println("\nURL : " + URL_NO_SOCKS);
GetMethod get = new GetMethod(URL_NO_SOCKS);
int response = client.executeMethod(get);
System.out.println("Response code : " + response + " , Response : " + get.getResponseBodyAsString().substring(0, 50));
System.out.println("\nURL : " + URL_BEHIND_SOCKS);
get = new GetMethod(URL_BEHIND_SOCKS);
response = client.executeMethod(get);
System.out.println("Response code : " + response + " , Response : " + get.getResponseBodyAsString().substring(0, 50));
System.out.println("\n\n++++++++++++++++++++USING JAVA URL CONNECTION++++++++++++++++++++");
System.out.println("\nURL : " + URL_NO_SOCKS);
URI uri = new URI(URL_NO_SOCKS);
InputStream is = uri.toURL().openStream();
BufferedReader rdr = new BufferedReader(new InputStreamReader(is));
for (int i = 0; i < 2; i++) {
System.out.println(rdr.readLine());
}
is.close();
System.out.println("\nURL : " + URL_BEHIND_SOCKS);
uri = new URI(URL_BEHIND_SOCKS);
is = uri.toURL().openStream();
rdr = new BufferedReader(new InputStreamReader(is));
for (int i = 0; i < 2; i++) {
System.out.println(rdr.readLine());
}
is.close();
}
}
And here is the output of the code run :
++++++++++++++++++++USING HTTP CLIENT++++++++++++++++++++ URL : http://mail.yahoo.com select for URL : socket://mail.yahoo.com:80 NO PROXY TO BE USED select for URL : socket://login.yahoo.com:443 Default proxy list : [SOCKS @ socks.corp.yahoo.com:1080] Response code : 200 , Response : <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 URL : http://yahoo.com select for URL : socket://yahoo.com:80 Default proxy list : [SOCKS @ socks.corp.yahoo.com:1080] select for URL : socket://www.yahoo.com:80 Default proxy list : [SOCKS @ socks.corp.yahoo.com:1080] Response code : 200 , Response : <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" ++++++++++++++++++++USING JAVA URL CONNECTION++++++++++++++++++++ URL : http://mail.yahoo.com select for URL : http://mail.yahoo.com/ NO PROXY TO BE USED <!-- l03.member.in2.yahoo.com uncompressed/chunked Fri May 28 20:32:24 IST 2010 --> null URL : http://yahoo.com select for URL : http://yahoo.com/ Default proxy list : [SOCKS @ socks.corp.yahoo.com:1080] select for URL : http://www.yahoo.com/ Default proxy list : [SOCKS @ socks.corp.yahoo.com:1080] <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">




