You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2010/04/02 10:59:23 UTC

svn commit: r930190 - /httpcomponents/httpclient/branches/4.0.x/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java

Author: olegk
Date: Fri Apr  2 08:59:22 2010
New Revision: 930190

URL: http://svn.apache.org/viewvc?rev=930190&view=rev
Log:
HTTPCLIENT-898: Improved multihome support
Contributed by Steinar H. Gunderson <sesse at google.com>

Modified:
    httpcomponents/httpclient/branches/4.0.x/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java

Modified: httpcomponents/httpclient/branches/4.0.x/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/4.0.x/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java?rev=930190&r1=930189&r2=930190&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/4.0.x/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java (original)
+++ httpcomponents/httpclient/branches/4.0.x/httpclient/src/main/java/org/apache/http/impl/conn/DefaultClientConnectionOperator.java Fri Apr  2 08:59:22 2010
@@ -39,10 +39,12 @@ import org.apache.http.params.HttpParams
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.protocol.HttpContext;
 
+import org.apache.http.conn.ConnectTimeoutException;
 import org.apache.http.conn.HttpHostConnectException;
 import org.apache.http.conn.OperatedClientConnection;
 import org.apache.http.conn.ClientConnectionOperator;
 import org.apache.http.conn.scheme.LayeredSocketFactory;
+import org.apache.http.conn.scheme.PlainSocketFactory;
 import org.apache.http.conn.scheme.Scheme;
 import org.apache.http.conn.scheme.SchemeRegistry;
 import org.apache.http.conn.scheme.SocketFactory;
@@ -102,8 +104,6 @@ public class DefaultClientConnectionOper
             throw new IllegalArgumentException
                 ("Target host must not be null.");
         }
-        // local address may be null
-        //@@@ is context allowed to be null?
         if (params == null) {
             throw new IllegalArgumentException
                 ("Parameters must not be null.");
@@ -113,21 +113,57 @@ public class DefaultClientConnectionOper
                 ("Connection must not be open.");
         }
 
-        final Scheme schm = schemeRegistry.getScheme(target.getSchemeName());
-        final SocketFactory sf = schm.getSocketFactory();
-
-        Socket sock = sf.createSocket();
-        conn.opening(sock, target);
-
-        try {
-            sock = sf.connectSocket(sock, target.getHostName(),
-                    schm.resolvePort(target.getPort()),
-                    local, 0, params);
-        } catch (ConnectException ex) {
-            throw new HttpHostConnectException(target, ex);
+        SocketFactory sf = null;
+        LayeredSocketFactory layeredsf = null;
+        
+        Scheme schm = schemeRegistry.getScheme(target.getSchemeName());
+        sf = schm.getSocketFactory();
+        if (sf instanceof LayeredSocketFactory) {
+            layeredsf = (LayeredSocketFactory) sf;
+            sf = PlainSocketFactory.getSocketFactory();
+        }
+
+        InetAddress[] addresses = InetAddress.getAllByName(target.getHostName());
+        for (int i = 0; i < addresses.length; i++) {
+            InetAddress address = addresses[i];
+            boolean last = i == addresses.length;
+            Socket sock = sf.createSocket();
+            conn.opening(sock, target);
+            try {
+                Socket connsock = sf.connectSocket(
+                        sock, 
+                        address.getHostAddress(),
+                        schm.resolvePort(target.getPort()),
+                        local, 0, params);
+                if (sock != connsock) {
+                    sock = connsock;
+                    conn.opening(sock, target);
+                }
+                if (layeredsf != null) {
+                    connsock = layeredsf.createSocket(
+                            sock, 
+                            address.getHostAddress(),
+                            schm.resolvePort(target.getPort()),
+                            true);
+                    if (sock != connsock) {
+                        sock = connsock;
+                        conn.opening(sock, target);
+                    }
+                    sf = layeredsf;
+                }
+                prepareSocket(sock, context, params);
+                conn.openCompleted(sf.isSecure(sock), params);
+                break;
+            } catch (ConnectException ex) {
+                if (last) {
+                    throw new HttpHostConnectException(target, ex);
+                }
+            } catch (ConnectTimeoutException ex) {
+                if (last) {
+                    throw ex;
+                }
+            }
         }
-        prepareSocket(sock, context, params);
-        conn.openCompleted(sf.isSecure(sock), params);
     }
 
     public void updateSecureConnection(OperatedClientConnection conn,