How can I bind an (outbound, of course) HttpUrlCon

2020-03-03 10:04发布

问题:

I have a kind of Http-Gateway app, which acts as an http client towards servers outside our local network.

There is going to be a network configuration upgrade, and I'm going to have problems because:
- there are multiple network cards on client machine
- firewall/nat rules use hardwired ip addresses

If I could programmatically force HttpUrlConnection object to use a specific ip address, I would be ok. But I'm afraid it can't be done.

Am I right? If not, which version of JRE supports it?

Other possible solutions, preferably ones which don't involve rewriting everything from scratch?
The simpler the better: I know, there is Apache HttpClient, or I could use Sockets...

Thanks

回答1:

I can see no good solution but have two poor possibilities:

  1. Proxy the connections locally:

    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
            "proxy", 5555));
    URLConnection urlConnection = url.openConnection(proxy);
    
  2. Register a custom URLStreamHandlerFactory with java.net.URL. Whenever openConnection() is called on the URL it would be handled by this registered custom factory, giving you control over details of the socket connection. Either use Apache's implementation or roll your own?

    Url.setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
    


回答2:

You can't. HttpURLConnection doesn't provide any interface to manipulate the socket.

You shouldn't do this either. Selection of interface is based on routing decision. If you have to manually select the NIC to get to the destination, all your internet connection would have the same issue. You should add static route in the OS to make sure the correct interface is used for the destination.



回答3:

There's a constructor on the Socket class ( http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html ) that will let you specify a localAddr. This makes it possible to do what you want in Java.

Unfortunately, HttpUrlConnection and its family of classes don't give you much opportunity to get at the underlying socket. I followed the possibility offered by setContentHandlerFactory but that only lets you manipulate the content long after the socket's been opened.

My suggestion, therefore, would be to twist your admin's arm into changing the routing table of your machine such that the only one possible (or optimal) route from that machine to your target hosts will go through the gateway you want to use. That way, when a socket connection is opened it will default to the card for that gateway.