From 4fe52a15b9fe8624fcaea9741bc8e94e38126f33 Mon Sep 17 00:00:00 2001 From: Roland Weber Date: Thu, 4 Jan 2007 06:33:16 +0000 Subject: [PATCH] new connection interfaces, step 3 - HTTPCLIENT-475 git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@492424 13f79535-47bb-0310-9956-ffa450edef68 --- .../http/conn/UnmanagedClientConnection.java | 31 +++++++++++++++++ .../conn/impl/DefaultClientConnection.java | 34 +++++++++++++++++++ .../impl/DefaultSocketConnectionOperator.java | 14 ++++---- 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/java/org/apache/http/conn/UnmanagedClientConnection.java b/src/java/org/apache/http/conn/UnmanagedClientConnection.java index be0a34ec6..38ed4051e 100644 --- a/src/java/org/apache/http/conn/UnmanagedClientConnection.java +++ b/src/java/org/apache/http/conn/UnmanagedClientConnection.java @@ -88,6 +88,37 @@ public interface UnmanagedClientConnection // do not require connections to store parameters. + /** + * Prepares opening this connection. + * Opening can be prepared only while the connection is closed. + * This is an optional step, you can call {@link #open open} + * without preparing. + *
+ * By calling this method, you provide the connection with + * the unconnected socket that will be connected in order + * to call {@link #open open}. This allows the connection to + * close that socket if + * {@link org.apache.http.HttpConnection#shutdown shutdown} + * is called before it is open. Closing the unconnected socket + * will interrupt a thread that is blocked on the connect. + * Otherwise, that thread will either time out on the connect, + * or it returns successfully and then opens this connection + * which was just shut down. + *
+ * Note: + * The result of {@link #getSocket getSocket} is defined + * only for open connections. You MUST NOT rely on that + * method to return the unconnected socket after preparing. + * + * @param sock the unconnected socket which is about to + * be connected in order to call {@link #open open}. + * null can be passed to undo a + * previous call. + */ + void prepare(Socket sock) + ; + + /** * Opens this connection. * A connection can be openend only while it is closed. diff --git a/src/java/org/apache/http/conn/impl/DefaultClientConnection.java b/src/java/org/apache/http/conn/impl/DefaultClientConnection.java index dc9be95a6..002193777 100644 --- a/src/java/org/apache/http/conn/impl/DefaultClientConnection.java +++ b/src/java/org/apache/http/conn/impl/DefaultClientConnection.java @@ -55,6 +55,9 @@ import org.apache.http.conn.UnmanagedClientConnection; public class DefaultClientConnection extends SocketHttpClientConnection implements UnmanagedClientConnection { + /** The unconnected socket while being prepared. */ + private volatile Socket preparedSocket; + /** The target host of this connection. */ private HttpHost targetHost; @@ -84,6 +87,35 @@ public class DefaultClientConnection extends SocketHttpClientConnection } + // non-javadoc, see interface UnmanagedClientConnection + public void prepare(Socket sock) { + + assertNotOpen(); + preparedSocket = sock; + + } // prepare + + + /** + * Force-closes this connection. + * If it is not yet {@link #open open} but {@link #prepare prepared}, + * the associated socket is closed. That will interrupt a thread that + * is blocked on connecting the socket. + * + * @throws IOException in case of a problem + */ + public void shutdown() + throws IOException { + + Socket sock = preparedSocket; // copy volatile attribute + if (sock != null) + sock.close(); + + super.shutdown(); + + } // shutdown + + // non-javadoc, see interface UnmanagedClientConnection public void open(Socket sock, HttpHost target, boolean secure, HttpParams params) @@ -107,6 +139,8 @@ public class DefaultClientConnection extends SocketHttpClientConnection targetHost = target; connSecure = secure; + preparedSocket = null; + } // open diff --git a/src/java/org/apache/http/conn/impl/DefaultSocketConnectionOperator.java b/src/java/org/apache/http/conn/impl/DefaultSocketConnectionOperator.java index c93e51ab3..4dda2b5b8 100644 --- a/src/java/org/apache/http/conn/impl/DefaultSocketConnectionOperator.java +++ b/src/java/org/apache/http/conn/impl/DefaultSocketConnectionOperator.java @@ -104,18 +104,20 @@ public class DefaultSocketConnectionOperator "' in target host."); } final SocketFactory sf = schm.getSocketFactory(); - //@@@ create socket, register in connection, connect? (HTTPCLIENT-475) - //@@@ Requires registration method, since conn.open(...) fails if - //@@@ the socket is not open. Dependent objects need the streams! - final Socket sock = sf.connectSocket - (null, target.getHostName(), target.getPort(), local, 0, params); + + Socket sock = sf.createSocket(); + conn.prepare(sock); + + sock = sf.connectSocket + (sock, target.getHostName(), target.getPort(), local, 0, params); prepareSocket(sock, context, params); //@@@ ask the factory whether the new socket is secure? boolean secure = (sf instanceof SecureSocketFactory); conn.open(sock, target, secure, params); - //@@@ error handling: close the created socket in case of exception? + //@@@ error handling: unprepare the connection? + //@@@ error handling: close the created socket? } // openConnection