You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ro...@apache.org on 2007/09/08 16:20:54 UTC
svn commit: r573844 - in /jakarta/httpcomponents/httpclient/trunk: ./
module-client/src/main/java/org/apache/http/conn/
module-client/src/main/java/org/apache/http/impl/client/
module-client/src/main/java/org/apache/http/impl/conn/
module-client/src/te...
Author: rolandw
Date: Sat Sep 8 07:20:53 2007
New Revision: 573844
URL: http://svn.apache.org/viewvc?rev=573844&view=rev
Log:
HTTPCLIENT-649: ManagedClientConnection now supports proxy chains
Modified:
jakarta/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ManagedClientConnection.java
jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java
jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java
jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java
jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/ClientConnAdapterMockup.java
Modified: jakarta/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt?rev=573844&r1=573843&r2=573844&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original)
+++ jakarta/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Sat Sep 8 07:20:53 2007
@@ -1,5 +1,8 @@
Changes since release 4.0 Alpha 1
+* [HTTPCLIENT-649] support for proxy chains in HttpConn
+ Contributed by Roland Weber <rolandw at apache.org>
+
* [HTTPCLIENT-636] refactor ThreadSafeClientConnManager in separate package
Contributed by Roland Weber <rolandw at apache.org>
Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ManagedClientConnection.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ManagedClientConnection.java?rev=573844&r1=573843&r2=573844&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ManagedClientConnection.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/ManagedClientConnection.java Sat Sep 8 07:20:53 2007
@@ -35,6 +35,7 @@
import org.apache.http.HttpClientConnection;
import org.apache.http.HttpInetConnection;
+import org.apache.http.HttpHost;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
@@ -80,8 +81,8 @@
/**
* Opens this connection according to the given route.
*
- * @param route the route along which to open. It will be opened
- * to the proxy if present, or directly to the target.
+ * @param route the route along which to open. It will be opened to
+ * the first proxy if present, or directly to the target.
* @param context the context for opening this connection
* @param params the parameters for opening this connection
*
@@ -93,7 +94,7 @@
/**
- * Indicates that a tunnel has been established.
+ * Indicates that a tunnel to the target has been established.
* The route is the one previously passed to {@link #open open}.
* Subsequently, {@link #layerProtocol layerProtocol} can be called
* to layer the TLS/SSL protocol on top of the tunnelled connection.
@@ -109,7 +110,32 @@
*
* @throws IOException in case of a problem
*/
- void tunnelCreated(boolean secure, HttpParams params)
+ void tunnelTarget(boolean secure, HttpParams params)
+ throws IOException
+ ;
+
+
+ /**
+ * Indicates that a tunnel to an intermediate proxy has been established.
+ * This is used exclusively for so-called <i>proxy chains</i>, where
+ * a request has to pass through multiple proxies before reaching the
+ * target. In that case, all proxies but the last need to be tunnelled
+ * when establishing the connection. Tunnelling of the last proxy to the
+ * target is optional and would be indicated via {@link #tunnelTarget}.
+ *
+ * @param next the proxy to which the tunnel was established.
+ * This is <i>not</i> the proxy <i>through</i> which
+ * the tunnel was established, but the new end point
+ * of the tunnel. The tunnel does <i>not</i> yet
+ * reach to the target, use {@link #tunnelTarget}
+ * to indicate an end-to-end tunnel.
+ * @param secure <code>true</code> if the connection should be
+ * considered secure, <code>false</code> otherwise
+ * @param params the parameters for tunnelling this connection
+ *
+ * @throws IOException in case of a problem
+ */
+ void tunnelProxy(HttpHost next, boolean secure, HttpParams params)
throws IOException
;
Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java?rev=573844&r1=573843&r2=573844&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java Sat Sep 8 07:20:53 2007
@@ -439,7 +439,8 @@
*
* @throws HttpException in case of a problem
*/
- protected ManagedClientConnection allocateConnection(HttpRoute route, long timeout)
+ protected ManagedClientConnection allocateConnection(HttpRoute route,
+ long timeout)
throws HttpException, ConnectionPoolTimeoutException {
return connManager.getConnection(route, timeout);
@@ -481,15 +482,24 @@
managedConn.open(route, context, this.params);
break;
- case HttpRouteDirector.TUNNEL_TARGET:
- boolean secure = createTunnel(route, context);
- LOG.debug("Tunnel created");
- managedConn.tunnelCreated(secure, this.params);
- break;
+ case HttpRouteDirector.TUNNEL_TARGET: {
+ boolean secure = createTunnelToTarget(route, context);
+ LOG.debug("Tunnel to target created.");
+ managedConn.tunnelTarget(secure, this.params);
+ } break;
+
+ case HttpRouteDirector.TUNNEL_PROXY: {
+ // The most simple example for this case is a proxy chain
+ // of two proxies, where P1 must be tunnelled to P2.
+ // route: Source -> P1 -> P2 -> Target (3 hops)
+ // fact: Source -> P1 -> Target (2 hops)
+ final int hop = fact.getHopCount()-1; // the hop to establish
+ boolean secure = createTunnelToProxy(route, hop, context);
+ LOG.debug("Tunnel to proxy created.");
+ managedConn.tunnelProxy(route.getHopTarget(hop),
+ secure, this.params);
+ } break;
- case HttpRouteDirector.TUNNEL_PROXY:
- throw new UnsupportedOperationException
- ("Proxy chains are not supported.");
case HttpRouteDirector.LAYER_PROTOCOL:
managedConn.layerProtocol(context, this.params);
@@ -516,8 +526,8 @@
/**
- * Creates a tunnel.
- * The connection must be established to the proxy.
+ * Creates a tunnel to the target server.
+ * The connection must be established to the (last) proxy.
* A CONNECT request for tunnelling through the proxy will
* be created and sent, the response received and checked.
* This method does <i>not</i> update the connection with
@@ -534,7 +544,8 @@
* @throws HttpException in case of a problem
* @throws IOException in case of an IO problem
*/
- protected boolean createTunnel(HttpRoute route, HttpContext context)
+ protected boolean createTunnelToTarget(HttpRoute route,
+ HttpContext context)
throws HttpException, IOException {
HttpHost proxy = route.getProxyHost();
@@ -645,7 +656,45 @@
// Even if that is secure, the hop to the target may be insecure.
// Leave it to derived classes, consider insecure by default here.
return false;
+
+ } // createTunnelToTarget
+
+
+
+ /**
+ * Creates a tunnel to an intermediate proxy.
+ * This method is <i>not</i> implemented in this class.
+ * It just throws an exception here.
+ *
+ * @param route the route to establish
+ * @param hop the hop in the route to establish now.
+ * <code>route.getHopTarget(hop)</code>
+ * will return the proxy to tunnel to.
+ * @param context the context for request execution
+ *
+ * @return <code>true</code> if the partially tunnelled connection
+ * is secure, <code>false</code> otherwise.
+ *
+ * @throws HttpException in case of a problem
+ * @throws IOException in case of an IO problem
+ */
+ protected boolean createTunnelToProxy(HttpRoute route, int hop,
+ HttpContext context)
+ throws HttpException, IOException {
+
+ // Have a look at createTunnelToTarget and replicate the parts
+ // you need in a custom derived class. If your proxies don't require
+ // authentication, it is not too hard. But for the stock version of
+ // HttpClient, we cannot make such simplifying assumptions and would
+ // have to include proxy authentication code. The HttpComponents team
+ // is currently not in a position to support rarely used code of this
+ // complexity. Feel free to submit patches that refactor the code in
+ // createTunnelToTarget to facilitate re-use for proxy tunnelling.
+
+ throw new UnsupportedOperationException
+ ("Proxy chains are not supported.");
}
+
/**
Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java?rev=573844&r1=573843&r2=573844&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java Sat Sep 8 07:20:53 2007
@@ -161,9 +161,9 @@
/**
- * Tracks tunnelling of the connection.
+ * Tracks tunnelling of the connection to the target.
* The tunnel has to be established outside by sending a CONNECT
- * request to the proxy.
+ * request to the (last) proxy.
*
* @param secure <code>true</code> if the tunnel should be
* considered secure, <code>false</code> otherwise
@@ -171,7 +171,7 @@
*
* @throws IOException in case of a problem
*/
- public void tunnelCreated(boolean secure, HttpParams params)
+ public void tunnelTarget(boolean secure, HttpParams params)
throws IOException {
if (params == null) {
@@ -194,7 +194,47 @@
secure, params);
this.tracker.tunnelTarget(secure);
- } // tunnelCreated
+ } // tunnelTarget
+
+
+ /**
+ * Tracks tunnelling of the connection to a chained proxy.
+ * The tunnel has to be established outside by sending a CONNECT
+ * request to the previous proxy.
+ *
+ * @param next the proxy to which the tunnel was established.
+ * See {@link org.apache.http.conn.ManagedClientConnection#tunnelProxy
+ * ManagedClientConnection.tunnelProxy}
+ * for details.
+ * @param secure <code>true</code> if the tunnel should be
+ * considered secure, <code>false</code> otherwise
+ * @param params the parameters for tunnelling the connection
+ *
+ * @throws IOException in case of a problem
+ */
+ public void tunnelProxy(HttpHost next, boolean secure, HttpParams params)
+ throws IOException {
+
+ if (next == null) {
+ throw new IllegalArgumentException
+ ("Next proxy must not be null.");
+ }
+ if (params == null) {
+ throw new IllegalArgumentException
+ ("Parameters must not be null.");
+ }
+
+ //@@@ check for proxy in planned route?
+ if ((this.tracker == null) || !this.tracker.isConnected()) {
+ throw new IllegalStateException("Connection not open.");
+ }
+
+ // LOG.debug?
+
+ this.connection.update(null, next, secure, params);
+ this.tracker.tunnelProxy(next, secure);
+
+ } // tunnelProxy
/**
Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java?rev=573844&r1=573843&r2=573844&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java Sat Sep 8 07:20:53 2007
@@ -33,6 +33,7 @@
import java.io.IOException;
+import org.apache.http.HttpHost;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.apache.http.conn.HttpRoute;
@@ -122,11 +123,20 @@
// non-javadoc, see interface ManagedHttpConnection
- public void tunnelCreated(boolean secure, HttpParams params)
+ public void tunnelTarget(boolean secure, HttpParams params)
throws IOException {
assertAttached();
- poolEntry.tunnelCreated(secure, params);
+ poolEntry.tunnelTarget(secure, params);
+ }
+
+
+ // non-javadoc, see interface ManagedHttpConnection
+ public void tunnelProxy(HttpHost next, boolean secure, HttpParams params)
+ throws IOException {
+
+ assertAttached();
+ poolEntry.tunnelProxy(next, secure, params);
}
Modified: jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/ClientConnAdapterMockup.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/ClientConnAdapterMockup.java?rev=573844&r1=573843&r2=573844&view=diff
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/ClientConnAdapterMockup.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/module-client/src/test/java/org/apache/http/impl/conn/ClientConnAdapterMockup.java Sat Sep 8 07:20:53 2007
@@ -30,6 +30,7 @@
package org.apache.http.impl.conn;
+import org.apache.http.HttpHost;
import org.apache.http.conn.HttpRoute;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
@@ -64,7 +65,11 @@
throw new UnsupportedOperationException("just a mockup");
}
- public void tunnelCreated(boolean secure, HttpParams params) {
+ public void tunnelTarget(boolean secure, HttpParams params) {
+ throw new UnsupportedOperationException("just a mockup");
+ }
+
+ public void tunnelProxy(HttpHost next, boolean secure, HttpParams params) {
throw new UnsupportedOperationException("just a mockup");
}