Return-Path: Mailing-List: contact commons-httpclient-dev-help@jakarta.apache.org; run by ezmlm Delivered-To: mailing list commons-httpclient-dev@jakarta.apache.org Received: (qmail 84828 invoked from network); 9 May 2003 00:32:39 -0000 Received: from unknown (HELO vocalsend.bevocal.com) (66.147.154.130) by daedalus.apache.org with SMTP; 9 May 2003 00:32:39 -0000 Received: from lwerner.org (speedtrap.bevocal.com [172.16.2.66]) by vocalsend.bevocal.com (8.11.0/8.11.0) with ESMTP id h48MogE15597 for ; Thu, 8 May 2003 15:50:43 -0700 Message-ID: <3EBAF72F.8080606@lwerner.org> Date: Thu, 08 May 2003 17:32:47 -0700 From: Laura Werner User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.3) Gecko/20030312 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Commons HttpClient Project Subject: [PATCH] Add HostConfiguration.set/getLocalAddress Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Here's a patch that adds setLocalAddress(InetAddress) and getLocalAddress methods to HostConfiguration. I added localAddress fields to both HostConfiguration and HttpConnection, and HttpConnection.open uses the local address if it's non-null. Feedback is welcome. In particular, I wasn't sure how much to expose the local address in HttpConnection. Right now, the only way to tell a connection to use a special local address is to construct the HttpConnection with a HostConfiguration that has the local address set; there's no additional HttpConnection constructor that takes a local address. Also, I had to add a getLocalAddress method to HttpConnection so that HostConfiguration.equals would work, but I decided to leave it with package access to minimize API disturbance. I'm not wedded to either of those decisions. Here's the patch. I haven't done a lot of testing on it yet, but it seems to work and I wanted to get feedback ASAP. Index: org/apache/commons/httpclient/HostConfiguration.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HostConfiguration.java,v retrieving revision 1.10 diff -u -r1.10 HostConfiguration.java --- org/apache/commons/httpclient/HostConfiguration.java 19 Apr 2003 22:29:31 -0000 1.10 +++ org/apache/commons/httpclient/HostConfiguration.java 9 May 2003 00:26:43 -0000 @@ -65,6 +65,8 @@ import org.apache.commons.httpclient.protocol.Protocol; +import java.net.InetAddress; + /** * * @author Michael Becke @@ -98,6 +100,9 @@ /** True if a proxy server has been set */ private boolean proxySet; + /** The local address to use when creating the socket, or null to use the default */ + private InetAddress localAddress; + /** * Constructor for HostConfiguration. */ @@ -112,7 +117,7 @@ this.proxyHost = null; this.proxyPort = -1; this.proxySet = false; - + this.localAddress = null; } /** @@ -134,6 +139,7 @@ this.proxyHost = hostConfiguration.getProxyHost(); this.proxyPort = hostConfiguration.getProxyPort(); this.proxySet = hostConfiguration.isProxySet(); + this.localAddress = hostConfiguration.getLocalAddress(); } } @@ -177,6 +183,15 @@ if (!this.protocol.equals(connection.getProtocol())) { return false; } + if (this.localAddress != null) { + if (!this.localAddress.equals(connection.getLocalAddress())) { + return false; + } + } else { + if (connection.getLocalAddress() != null) { + return false; + } + } return true; } else { return false; @@ -388,6 +403,25 @@ return proxyPort; } + /** + * Set the local address to be used when creating connections. + * If this is unset, the default address will be used. + * This is useful for specifying the interface to use on multi-homed or clustered systems. + */ + public synchronized void setLocalAddress(InetAddress localAddress) { + this.localAddress = localAddress; + } + + /** + * Return the local address to be used when creating connections. + * If this is unset, the default address should be used. + * + * @return InetAddress the local address to be used when creating Sockets + */ + public synchronized InetAddress getLocalAddress() { + return this.localAddress; + } + /** * @see java.lang.Object#equals(java.lang.Object) */ Index: org/apache/commons/httpclient/HttpConnection.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java,v retrieving revision 1.65 diff -u -r1.65 HttpConnection.java --- org/apache/commons/httpclient/HttpConnection.java 8 May 2003 17:33:51 -0000 1.65 +++ org/apache/commons/httpclient/HttpConnection.java 9 May 2003 00:26:43 -0000 @@ -70,6 +70,7 @@ import java.io.OutputStream; import java.io.PushbackInputStream; import java.lang.reflect.Method; +import java.net.InetAddress; import java.net.Socket; import java.net.SocketException; @@ -217,6 +218,7 @@ hostConfiguration.getVirtualHost(), hostConfiguration.getPort(), hostConfiguration.getProtocol()); + this.localAddress = hostConfiguration.getLocalAddress(); } /** @@ -446,6 +448,17 @@ } /** + * Return the local address to be used when creating connections. + * If this is unset, the default address should be used. + * + * @return InetAddress the local address to be used when creating Sockets + */ + InetAddress getLocalAddress() { + return this.localAddress; + } + + + /** * Return true if I am connected, * false otherwise. * @@ -636,11 +649,19 @@ : protocolInUse.getSocketFactory()); if (connectTimeout == 0) { - socket = socketFactory.createSocket(host, port); + if (localAddress != null) { + socket = socketFactory.createSocket(host, port, localAddress, 0); + } else { + socket = socketFactory.createSocket(host, port); + } } else { SocketTask task = new SocketTask() { public void doit() throws IOException { - setSocket(socketFactory.createSocket(host, port)); + if (localAddress != null) { + setSocket(socketFactory.createSocket(host, port, localAddress, 0)); + } else { + setSocket(socketFactory.createSocket(host, port)); + } } }; TimeoutController.execute(task, connectTimeout); @@ -1394,4 +1415,7 @@ /** the connection manager that created this connection or null */ private HttpConnectionManager httpConnectionManager; + + /** The local interface on which the connection was created, or null for the default */ + private InetAddress localAddress; }