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