/lib/src/org/apache/http/impl/conn/AbstractPoolEntry.java

http://github.com/onedanshow/Screen-Courter · Java · 294 lines · 123 code · 41 blank · 130 comment · 35 complexity · 16ad0b24ec8d03b0dc0b9d8095ef2470 MD5 · raw file

  1. /*
  2. * ====================================================================
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership.
  7. * The ASF licenses this file to You under the Apache License, Version 2.0
  8. * (the "License"); you may not use this file except in compliance with
  9. * the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * ====================================================================
  19. *
  20. * This software consists of voluntary contributions made by many
  21. * individuals on behalf of the Apache Software Foundation. For more
  22. * information on the Apache Software Foundation, please see
  23. * <http://www.apache.org/>.
  24. *
  25. */
  26. package org.apache.http.impl.conn;
  27. import java.io.IOException;
  28. import org.apache.http.HttpHost;
  29. import org.apache.http.params.HttpParams;
  30. import org.apache.http.protocol.HttpContext;
  31. import org.apache.http.conn.routing.HttpRoute;
  32. import org.apache.http.conn.routing.RouteTracker;
  33. import org.apache.http.conn.ClientConnectionOperator;
  34. import org.apache.http.conn.OperatedClientConnection;
  35. /**
  36. * A pool entry for use by connection manager implementations.
  37. * Pool entries work in conjunction with an
  38. * {@link AbstractClientConnAdapter adapter}.
  39. * The adapter is handed out to applications that obtain a connection.
  40. * The pool entry stores the underlying connection and tracks the
  41. * {@link HttpRoute route} established.
  42. * The adapter delegates methods for establishing the route to
  43. * its pool entry.
  44. * <p>
  45. * If the managed connections is released or revoked, the adapter
  46. * gets disconnected, but the pool entry still contains the
  47. * underlying connection and the established route.
  48. *
  49. * @since 4.0
  50. */
  51. public abstract class AbstractPoolEntry {
  52. /** The connection operator. */
  53. protected final ClientConnectionOperator connOperator;
  54. /** The underlying connection being pooled or used. */
  55. protected final OperatedClientConnection connection;
  56. /** The route for which this entry gets allocated. */
  57. //@@@ currently accessed from connection manager(s) as attribute
  58. //@@@ avoid that, derived classes should decide whether update is allowed
  59. //@@@ SCCM: yes, TSCCM: no
  60. protected volatile HttpRoute route;
  61. /** Connection state object */
  62. protected volatile Object state;
  63. /** The tracked route, or <code>null</code> before tracking starts. */
  64. protected volatile RouteTracker tracker;
  65. /**
  66. * Creates a new pool entry.
  67. *
  68. * @param connOperator the Connection Operator for this entry
  69. * @param route the planned route for the connection,
  70. * or <code>null</code>
  71. */
  72. protected AbstractPoolEntry(ClientConnectionOperator connOperator,
  73. HttpRoute route) {
  74. super();
  75. if (connOperator == null) {
  76. throw new IllegalArgumentException("Connection operator may not be null");
  77. }
  78. this.connOperator = connOperator;
  79. this.connection = connOperator.createConnection();
  80. this.route = route;
  81. this.tracker = null;
  82. }
  83. /**
  84. * Returns the state object associated with this pool entry.
  85. *
  86. * @return The state object
  87. */
  88. public Object getState() {
  89. return state;
  90. }
  91. /**
  92. * Assigns a state object to this pool entry.
  93. *
  94. * @param state The state object
  95. */
  96. public void setState(final Object state) {
  97. this.state = state;
  98. }
  99. /**
  100. * Opens the underlying connection.
  101. *
  102. * @param route the route along which to open the connection
  103. * @param context the context for opening the connection
  104. * @param params the parameters for opening the connection
  105. *
  106. * @throws IOException in case of a problem
  107. */
  108. public void open(HttpRoute route,
  109. HttpContext context, HttpParams params)
  110. throws IOException {
  111. if (route == null) {
  112. throw new IllegalArgumentException
  113. ("Route must not be null.");
  114. }
  115. if (params == null) {
  116. throw new IllegalArgumentException
  117. ("Parameters must not be null.");
  118. }
  119. if ((this.tracker != null) && this.tracker.isConnected()) {
  120. throw new IllegalStateException("Connection already open.");
  121. }
  122. // - collect the arguments
  123. // - call the operator
  124. // - update the tracking data
  125. // In this order, we can be sure that only a successful
  126. // opening of the connection will be tracked.
  127. this.tracker = new RouteTracker(route);
  128. final HttpHost proxy = route.getProxyHost();
  129. connOperator.openConnection
  130. (this.connection,
  131. (proxy != null) ? proxy : route.getTargetHost(),
  132. route.getLocalAddress(),
  133. context, params);
  134. RouteTracker localTracker = tracker; // capture volatile
  135. // If this tracker was reset while connecting,
  136. // fail early.
  137. if (localTracker == null) {
  138. throw new IOException("Request aborted");
  139. }
  140. if (proxy == null) {
  141. localTracker.connectTarget(this.connection.isSecure());
  142. } else {
  143. localTracker.connectProxy(proxy, this.connection.isSecure());
  144. }
  145. }
  146. /**
  147. * Tracks tunnelling of the connection to the target.
  148. * The tunnel has to be established outside by sending a CONNECT
  149. * request to the (last) proxy.
  150. *
  151. * @param secure <code>true</code> if the tunnel should be
  152. * considered secure, <code>false</code> otherwise
  153. * @param params the parameters for tunnelling the connection
  154. *
  155. * @throws IOException in case of a problem
  156. */
  157. public void tunnelTarget(boolean secure, HttpParams params)
  158. throws IOException {
  159. if (params == null) {
  160. throw new IllegalArgumentException
  161. ("Parameters must not be null.");
  162. }
  163. if ((this.tracker == null) || !this.tracker.isConnected()) {
  164. throw new IllegalStateException("Connection not open.");
  165. }
  166. if (this.tracker.isTunnelled()) {
  167. throw new IllegalStateException
  168. ("Connection is already tunnelled.");
  169. }
  170. this.connection.update(null, tracker.getTargetHost(),
  171. secure, params);
  172. this.tracker.tunnelTarget(secure);
  173. }
  174. /**
  175. * Tracks tunnelling of the connection to a chained proxy.
  176. * The tunnel has to be established outside by sending a CONNECT
  177. * request to the previous proxy.
  178. *
  179. * @param next the proxy to which the tunnel was established.
  180. * See {@link org.apache.http.conn.ManagedClientConnection#tunnelProxy
  181. * ManagedClientConnection.tunnelProxy}
  182. * for details.
  183. * @param secure <code>true</code> if the tunnel should be
  184. * considered secure, <code>false</code> otherwise
  185. * @param params the parameters for tunnelling the connection
  186. *
  187. * @throws IOException in case of a problem
  188. */
  189. public void tunnelProxy(HttpHost next, boolean secure, HttpParams params)
  190. throws IOException {
  191. if (next == null) {
  192. throw new IllegalArgumentException
  193. ("Next proxy must not be null.");
  194. }
  195. if (params == null) {
  196. throw new IllegalArgumentException
  197. ("Parameters must not be null.");
  198. }
  199. //@@@ check for proxy in planned route?
  200. if ((this.tracker == null) || !this.tracker.isConnected()) {
  201. throw new IllegalStateException("Connection not open.");
  202. }
  203. this.connection.update(null, next, secure, params);
  204. this.tracker.tunnelProxy(next, secure);
  205. }
  206. /**
  207. * Layers a protocol on top of an established tunnel.
  208. *
  209. * @param context the context for layering
  210. * @param params the parameters for layering
  211. *
  212. * @throws IOException in case of a problem
  213. */
  214. public void layerProtocol(HttpContext context, HttpParams params)
  215. throws IOException {
  216. //@@@ is context allowed to be null? depends on operator?
  217. if (params == null) {
  218. throw new IllegalArgumentException
  219. ("Parameters must not be null.");
  220. }
  221. if ((this.tracker == null) || !this.tracker.isConnected()) {
  222. throw new IllegalStateException("Connection not open.");
  223. }
  224. if (!this.tracker.isTunnelled()) {
  225. //@@@ allow this?
  226. throw new IllegalStateException
  227. ("Protocol layering without a tunnel not supported.");
  228. }
  229. if (this.tracker.isLayered()) {
  230. throw new IllegalStateException
  231. ("Multiple protocol layering not supported.");
  232. }
  233. // - collect the arguments
  234. // - call the operator
  235. // - update the tracking data
  236. // In this order, we can be sure that only a successful
  237. // layering on top of the connection will be tracked.
  238. final HttpHost target = tracker.getTargetHost();
  239. connOperator.updateSecureConnection(this.connection, target,
  240. context, params);
  241. this.tracker.layerProtocol(this.connection.isSecure());
  242. }
  243. /**
  244. * Shuts down the entry.
  245. *
  246. * If {@link #open(HttpRoute, HttpContext, HttpParams)} is in progress,
  247. * this will cause that open to possibly throw an {@link IOException}.
  248. */
  249. protected void shutdownEntry() {
  250. tracker = null;
  251. state = null;
  252. }
  253. }