• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/AbstractPoolEntry.java $
3  * $Revision: 658775 $
4  * $Date: 2008-05-21 10:30:45 -0700 (Wed, 21 May 2008) $
5  *
6  * ====================================================================
7  *
8  *  Licensed to the Apache Software Foundation (ASF) under one or more
9  *  contributor license agreements.  See the NOTICE file distributed with
10  *  this work for additional information regarding copyright ownership.
11  *  The ASF licenses this file to You under the Apache License, Version 2.0
12  *  (the "License"); you may not use this file except in compliance with
13  *  the License.  You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  *  Unless required by applicable law or agreed to in writing, software
18  *  distributed under the License is distributed on an "AS IS" BASIS,
19  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  *  See the License for the specific language governing permissions and
21  *  limitations under the License.
22  * ====================================================================
23  *
24  * This software consists of voluntary contributions made by many
25  * individuals on behalf of the Apache Software Foundation.  For more
26  * information on the Apache Software Foundation, please see
27  * <http://www.apache.org/>.
28  *
29  */
30 
31 package org.apache.http.impl.conn;
32 
33 
34 import java.io.IOException;
35 
36 import org.apache.http.HttpHost;
37 import org.apache.http.params.HttpParams;
38 import org.apache.http.protocol.HttpContext;
39 import org.apache.http.conn.routing.HttpRoute;
40 import org.apache.http.conn.routing.RouteTracker;
41 import org.apache.http.conn.ClientConnectionOperator;
42 import org.apache.http.conn.OperatedClientConnection;
43 
44 
45 
46 /**
47  * A pool entry for use by connection manager implementations.
48  * Pool entries work in conjunction with an
49  * {@link AbstractClientConnAdapter adapter}.
50  * The adapter is handed out to applications that obtain a connection.
51  * The pool entry stores the underlying connection and tracks the
52  * {@link HttpRoute route} established.
53  * The adapter delegates methods for establishing the route to
54  * it's pool entry.
55  * <br/>
56  * If the managed connections is released or revoked, the adapter
57  * gets disconnected, but the pool entry still contains the
58  * underlying connection and the established route.
59  *
60  * @author <a href="mailto:rolandw at apache.org">Roland Weber</a>
61  * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
62  *
63  *
64  * <!-- empty lines to avoid svn diff problems -->
65  * @version   $Revision: 658775 $
66  *
67  * @since 4.0
68  *
69  * @deprecated Please use {@link java.net.URL#openConnection} instead.
70  *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
71  *     for further details.
72  */
73 @Deprecated
74 public abstract class AbstractPoolEntry {
75 
76     /** The connection operator. */
77     protected final ClientConnectionOperator connOperator;
78 
79     /** The underlying connection being pooled or used. */
80     protected final OperatedClientConnection connection;
81 
82     /** The route for which this entry gets allocated. */
83     //@@@ currently accessed from connection manager(s) as attribute
84     //@@@ avoid that, derived classes should decide whether update is allowed
85     //@@@ SCCM: yes, TSCCM: no
86     protected volatile HttpRoute route;
87 
88     /** Connection state object */
89     protected volatile Object state;
90 
91     /** The tracked route, or <code>null</code> before tracking starts. */
92     protected volatile RouteTracker tracker;
93 
94 
95     /**
96      * Creates a new pool entry.
97      *
98      * @param connOperator     the Connection Operator for this entry
99      * @param route   the planned route for the connection,
100      *                or <code>null</code>
101      */
AbstractPoolEntry(ClientConnectionOperator connOperator, HttpRoute route)102     protected AbstractPoolEntry(ClientConnectionOperator connOperator,
103                                 HttpRoute route) {
104         super();
105         if (connOperator == null) {
106             throw new IllegalArgumentException("Connection operator may not be null");
107         }
108         this.connOperator = connOperator;
109         this.connection = connOperator.createConnection();
110         this.route = route;
111         this.tracker = null;
112     }
113 
114     /**
115      * Returns the state object associated with this pool entry.
116      *
117      * @return The state object
118      */
getState()119     public Object getState() {
120         return state;
121     }
122 
123     /**
124      * Assigns a state object to this pool entry.
125      *
126      * @param state The state object
127      */
setState(final Object state)128     public void setState(final Object state) {
129         this.state = state;
130     }
131 
132     /**
133      * Opens the underlying connection.
134      *
135      * @param route         the route along which to open the connection
136      * @param context       the context for opening the connection
137      * @param params        the parameters for opening the connection
138      *
139      * @throws IOException  in case of a problem
140      */
open(HttpRoute route, HttpContext context, HttpParams params)141     public void open(HttpRoute route,
142                      HttpContext context, HttpParams params)
143         throws IOException {
144 
145         if (route == null) {
146             throw new IllegalArgumentException
147                 ("Route must not be null.");
148         }
149         //@@@ is context allowed to be null? depends on operator?
150         if (params == null) {
151             throw new IllegalArgumentException
152                 ("Parameters must not be null.");
153         }
154         if ((this.tracker != null) && this.tracker.isConnected()) {
155             throw new IllegalStateException("Connection already open.");
156         }
157 
158         // - collect the arguments
159         // - call the operator
160         // - update the tracking data
161         // In this order, we can be sure that only a successful
162         // opening of the connection will be tracked.
163 
164         //@@@ verify route against planned route?
165 
166         this.tracker = new RouteTracker(route);
167         final HttpHost proxy  = route.getProxyHost();
168 
169         connOperator.openConnection
170             (this.connection,
171              (proxy != null) ? proxy : route.getTargetHost(),
172              route.getLocalAddress(),
173              context, params);
174 
175         RouteTracker localTracker = tracker; // capture volatile
176 
177         // If this tracker was reset while connecting,
178         // fail early.
179         if (localTracker == null) {
180             throw new IOException("Request aborted");
181         }
182 
183         if (proxy == null) {
184             localTracker.connectTarget(this.connection.isSecure());
185         } else {
186             localTracker.connectProxy(proxy, this.connection.isSecure());
187         }
188 
189     } // open
190 
191 
192     /**
193      * Tracks tunnelling of the connection to the target.
194      * The tunnel has to be established outside by sending a CONNECT
195      * request to the (last) proxy.
196      *
197      * @param secure    <code>true</code> if the tunnel should be
198      *                  considered secure, <code>false</code> otherwise
199      * @param params    the parameters for tunnelling the connection
200      *
201      * @throws IOException  in case of a problem
202      */
tunnelTarget(boolean secure, HttpParams params)203     public void tunnelTarget(boolean secure, HttpParams params)
204         throws IOException {
205 
206         if (params == null) {
207             throw new IllegalArgumentException
208                 ("Parameters must not be null.");
209         }
210 
211         //@@@ check for proxy in planned route?
212         if ((this.tracker == null) || !this.tracker.isConnected()) {
213             throw new IllegalStateException("Connection not open.");
214         }
215         if (this.tracker.isTunnelled()) {
216             throw new IllegalStateException
217                 ("Connection is already tunnelled.");
218         }
219 
220         // LOG.debug?
221 
222         this.connection.update(null, tracker.getTargetHost(),
223                                secure, params);
224         this.tracker.tunnelTarget(secure);
225 
226     } // tunnelTarget
227 
228 
229     /**
230      * Tracks tunnelling of the connection to a chained proxy.
231      * The tunnel has to be established outside by sending a CONNECT
232      * request to the previous proxy.
233      *
234      * @param next      the proxy to which the tunnel was established.
235      *  See {@link org.apache.http.conn.ManagedClientConnection#tunnelProxy
236      *                                  ManagedClientConnection.tunnelProxy}
237      *                  for details.
238      * @param secure    <code>true</code> if the tunnel should be
239      *                  considered secure, <code>false</code> otherwise
240      * @param params    the parameters for tunnelling the connection
241      *
242      * @throws IOException  in case of a problem
243      */
tunnelProxy(HttpHost next, boolean secure, HttpParams params)244     public void tunnelProxy(HttpHost next, boolean secure, HttpParams params)
245         throws IOException {
246 
247         if (next == null) {
248             throw new IllegalArgumentException
249                 ("Next proxy must not be null.");
250         }
251         if (params == null) {
252             throw new IllegalArgumentException
253                 ("Parameters must not be null.");
254         }
255 
256         //@@@ check for proxy in planned route?
257         if ((this.tracker == null) || !this.tracker.isConnected()) {
258             throw new IllegalStateException("Connection not open.");
259         }
260 
261         // LOG.debug?
262 
263         this.connection.update(null, next, secure, params);
264         this.tracker.tunnelProxy(next, secure);
265 
266     } // tunnelProxy
267 
268 
269     /**
270      * Layers a protocol on top of an established tunnel.
271      *
272      * @param context   the context for layering
273      * @param params    the parameters for layering
274      *
275      * @throws IOException  in case of a problem
276      */
layerProtocol(HttpContext context, HttpParams params)277     public void layerProtocol(HttpContext context, HttpParams params)
278         throws IOException {
279 
280         //@@@ is context allowed to be null? depends on operator?
281         if (params == null) {
282             throw new IllegalArgumentException
283                 ("Parameters must not be null.");
284         }
285 
286         if ((this.tracker == null) || !this.tracker.isConnected()) {
287             throw new IllegalStateException("Connection not open.");
288         }
289         if (!this.tracker.isTunnelled()) {
290             //@@@ allow this?
291             throw new IllegalStateException
292                 ("Protocol layering without a tunnel not supported.");
293         }
294         if (this.tracker.isLayered()) {
295             throw new IllegalStateException
296                 ("Multiple protocol layering not supported.");
297         }
298 
299         // - collect the arguments
300         // - call the operator
301         // - update the tracking data
302         // In this order, we can be sure that only a successful
303         // layering on top of the connection will be tracked.
304 
305         final HttpHost target = tracker.getTargetHost();
306 
307         connOperator.updateSecureConnection(this.connection, target,
308                                              context, params);
309 
310         this.tracker.layerProtocol(this.connection.isSecure());
311 
312     } // layerProtocol
313 
314 
315     /**
316      * Shuts down the entry.
317      *
318      * If {@link #open(HttpRoute, HttpContext, HttpParams)} is in progress,
319      * this will cause that open to possibly throw an {@link IOException}.
320      */
shutdownEntry()321     protected void shutdownEntry() {
322         tracker = null;
323     }
324 
325 
326 } // class AbstractPoolEntry
327 
328