HTTP call with Socks 4 proxy

2019-09-07 02:07发布

问题:

I need to call a server using a socks 4 proxy. I am on java version 1.6.

If we use something like this then it treats the SOCKS proxy as version 5.

 URL url = new URL("https://www.google.com");  
 URLConnection connection = null;  
 SocketAddress proxySocketAddress1 =  new InetSocketAddress("XXXXXXXXXX", 8081);  
 Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxySocketAddress1);  
 connection = url.openConnection(proxy);  
 connection.setConnectTimeout(150000);  
 connection.connect();  

I can setup socks proxy at the system level by doing

// Set SOCKS proxy
System.getProperties().put( "socksProxyHost","xxxxx");
System.getProperties().put( "socksProxyPort","1234");
System.getProperties().put("socksProxyVersion","4");

When I do this I am able to reach the server

connection = url.openConnection(); 

But my other connections like connections to db, encryption server also goes thru the proxy and fails.

I also tried excluding servers from system proxy but no success.

System.getProperties().put("socksnonProxyHosts","*.net");
System.getProperties().put("http.nonProxyHosts","*.net"); 

Is there any other way I can choose to use SOCKS4 in java 1.6.

回答1:

It is a bug in the SocksSocketImpl implementation:

JDK-6964547 : Impossible to set useV4 in SocksSocketImpl



回答2:

This is what I tried and seems like it's working. Basically I need SOCKS4 proxy to connect to a socket.

SocketAddress socketAddress =  new InetSocketAddress("proxyhost",proxyport);
Proxy socketProxy =  new Proxy(Proxy.Type.SOCKS, socketAddress);

Socket  socket = new Socket(socketProxy); 
Class clazzSocks  = socket.getClass();
Method setSockVersion  = null;
Field sockImplField = null; 
SocketImpl socksimpl = null; 
 try {
    sockImplField = clazzSocks.getDeclaredField("impl");
    sockImplField.setAccessible(true);
    socksimpl  = (SocketImpl) sockImplField.get(socket);
    Class clazzSocksImpl  =  socksimpl.getClass();
    setSockVersion  = clazzSocksImpl.getDeclaredMethod("setV4");
    setSockVersion.setAccessible(true);
    if(null != setSockVersion){
        setSockVersion.invoke(socksimpl);
    }
    sockImplField.set(socket, socksimpl);
    } 
        catch (Exception e) {
      // TODO Auto-generated catch block
            e.printStackTrace();
    } 

String hostName="xxxxx";
int port=1080;
InetAddress address;        
SocketAddress socketAddress;            
address = InetAddress.getByName(hostName);
socketAddress = new InetSocketAddress(address, port);

// Connect to socket
socket.connect(socketAddress, 100000);

//setting the socket read() connection time out 
socket.setSoTimeout(100000);    

Please share your comments, feedback for this approach.



标签: java proxy socks