You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by "Steinar H. Gunderson (JIRA)" <ji...@apache.org> on 2010/03/09 17:59:27 UTC

[jira] Commented: (HTTPCLIENT-898) Improve multihome support

    [ https://issues.apache.org/jira/browse/HTTPCLIENT-898?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12843197#action_12843197 ] 

Steinar H. Gunderson commented on HTTPCLIENT-898:
-------------------------------------------------

FWIW, the following code fragment was newly checked into Android's repository. Note that you need to deal with LayeredSocketFactory specifically, or you will break SSL, since SSLSocketFactory uses the given (textual) hostname both to figure out where to connect and for SSL hostname verification (so if you just give it an IP, it breaks verification).

diff --git a/src/org/apache/http/conn/scheme/PlainSocketFactory.java b/src/org/apache/http/conn/scheme/PlainSocketFactory.java
index acc13f7..b15df44 100644
--- a/src/org/apache/http/conn/scheme/PlainSocketFactory.java
+++ b/src/org/apache/http/conn/scheme/PlainSocketFactory.java
@@ -35,7 +35,9 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Socket;
+import java.net.SocketTimeoutException;
 
+import org.apache.http.conn.ConnectTimeoutException;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
 
@@ -113,9 +115,11 @@ public final class PlainSocketFactory implements SocketFactory {
         } else {
             remoteAddress = new InetSocketAddress(host, port);            
         }
-        
-        sock.connect(remoteAddress, timeout);
-
+        try {
+            sock.connect(remoteAddress, timeout);
+        } catch (SocketTimeoutException ex) {
+            throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out");
+        }
         return sock;
 
     } // connectSocket
diff --git a/src/org/apache/http/impl/conn/DefaultClientConnectionOperator.java b/src/org/apache/http/impl/conn/DefaultClientConnectionOperator.java
index 41488e1..854b2b0 100644
--- a/src/org/apache/http/impl/conn/DefaultClientConnectionOperator.java
+++ b/src/org/apache/http/impl/conn/DefaultClientConnectionOperator.java
@@ -44,7 +44,9 @@ import org.apache.http.protocol.HttpContext;
 import org.apache.http.conn.HttpHostConnectException;
 import org.apache.http.conn.OperatedClientConnection;
 import org.apache.http.conn.ClientConnectionOperator;
+import org.apache.http.conn.ConnectTimeoutException;
 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;
@@ -67,6 +69,7 @@ import org.apache.http.conn.scheme.SocketFactory;
 public class DefaultClientConnectionOperator
     implements ClientConnectionOperator {
 
+    private static final PlainSocketFactory staticPlainSocketFactory = new PlainSocketFactory();
 
     /** The scheme registry for looking up socket factories. */
     protected SchemeRegistry schemeRegistry;
@@ -121,19 +124,55 @@ public class DefaultClientConnectionOperator
 
         final Scheme schm = schemeRegistry.getScheme(target.getSchemeName());
         final SocketFactory sf = schm.getSocketFactory();
+        final SocketFactory plain_sf;
+        final LayeredSocketFactory layered_sf;
+        if (sf instanceof LayeredSocketFactory) {
+            plain_sf = staticPlainSocketFactory;
+            layered_sf = (LayeredSocketFactory)sf;
+        } else {
+            plain_sf = sf;
+            layered_sf = null;
+        }
+        InetAddress[] addresses = InetAddress.getAllByName(target.getHostName());
 
-        Socket sock = sf.createSocket();
-        conn.opening(sock, target);
+        for (int i = 0; i < addresses.length; ++i) {
+            Socket sock = plain_sf.createSocket();
+            conn.opening(sock, target);
 
-        try {
-            sock = sf.connectSocket(sock, target.getHostName(),
+            try {
+                Socket connsock = plain_sf.connectSocket(sock,
+                    addresses[i].getHostAddress(),
                     schm.resolvePort(target.getPort()),
+                        true);
+                    if (layeredsock != sock) {
+                        conn.opening(layeredsock, target);
+                    }
+                    prepareSocket(layeredsock, context, params);
+                    conn.openCompleted(sf.isSecure(layeredsock), params);
+                } else {
+                    prepareSocket(sock, context, params);
+                    conn.openCompleted(sf.isSecure(sock), params);
+                }
+                break;
+            } catch (ConnectException ex) {
+                if (i == addresses.length - 1) {
+                    throw new HttpHostConnectException(target, ex);
+                }
+            } catch (ConnectTimeoutException ex) {
+                if (i == addresses.length - 1) {
+                    throw ex;
+                }
+            }
         }
-        prepareSocket(sock, context, params);
-        conn.openCompleted(sf.isSecure(sock), params);
     } // openConnection
 
 


> Improve multihome support
> -------------------------
>
>                 Key: HTTPCLIENT-898
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-898
>             Project: HttpComponents HttpClient
>          Issue Type: Improvement
>          Components: HttpConn
>    Affects Versions: 4.0 Final, 4.0.1, 4.1 Alpha1
>            Reporter: Oleg Kalnichevski
>             Fix For: 4.1 Alpha2
>
>
> MultihomePlainSocketFactory is basically broken and should be deprecated. Multihome logic needs to be moved to the DefaultClientConnectionOperator

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org