PageRenderTime 28ms CodeModel.GetById 16ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/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
Possible License(s): GPL-3.0
  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
 27package org.apache.http.impl.conn;
 28
 29import java.io.IOException;
 30
 31import org.apache.http.HttpHost;
 32import org.apache.http.params.HttpParams;
 33import org.apache.http.protocol.HttpContext;
 34import org.apache.http.conn.routing.HttpRoute;
 35import org.apache.http.conn.routing.RouteTracker;
 36import org.apache.http.conn.ClientConnectionOperator;
 37import org.apache.http.conn.OperatedClientConnection;
 38
 39/**
 40 * A pool entry for use by connection manager implementations.
 41 * Pool entries work in conjunction with an
 42 * {@link AbstractClientConnAdapter adapter}.
 43 * The adapter is handed out to applications that obtain a connection.
 44 * The pool entry stores the underlying connection and tracks the
 45 * {@link HttpRoute route} established.
 46 * The adapter delegates methods for establishing the route to
 47 * its pool entry.
 48 * <p>
 49 * If the managed connections is released or revoked, the adapter
 50 * gets disconnected, but the pool entry still contains the
 51 * underlying connection and the established route.
 52 *
 53 * @since 4.0
 54 */
 55public abstract class AbstractPoolEntry {
 56
 57    /** The connection operator. */
 58    protected final ClientConnectionOperator connOperator;
 59
 60    /** The underlying connection being pooled or used. */
 61    protected final OperatedClientConnection connection;
 62
 63    /** The route for which this entry gets allocated. */
 64    //@@@ currently accessed from connection manager(s) as attribute
 65    //@@@ avoid that, derived classes should decide whether update is allowed
 66    //@@@ SCCM: yes, TSCCM: no
 67    protected volatile HttpRoute route;
 68
 69    /** Connection state object */
 70    protected volatile Object state;
 71
 72    /** The tracked route, or <code>null</code> before tracking starts. */
 73    protected volatile RouteTracker tracker;
 74
 75
 76    /**
 77     * Creates a new pool entry.
 78     *
 79     * @param connOperator     the Connection Operator for this entry
 80     * @param route   the planned route for the connection,
 81     *                or <code>null</code>
 82     */
 83    protected AbstractPoolEntry(ClientConnectionOperator connOperator,
 84                                HttpRoute route) {
 85        super();
 86        if (connOperator == null) {
 87            throw new IllegalArgumentException("Connection operator may not be null");
 88        }
 89        this.connOperator = connOperator;
 90        this.connection = connOperator.createConnection();
 91        this.route = route;
 92        this.tracker = null;
 93    }
 94
 95    /**
 96     * Returns the state object associated with this pool entry.
 97     *
 98     * @return The state object
 99     */
100    public Object getState() {
101        return state;
102    }
103
104    /**
105     * Assigns a state object to this pool entry.
106     *
107     * @param state The state object
108     */
109    public void setState(final Object state) {
110        this.state = state;
111    }
112
113    /**
114     * Opens the underlying connection.
115     *
116     * @param route         the route along which to open the connection
117     * @param context       the context for opening the connection
118     * @param params        the parameters for opening the connection
119     *
120     * @throws IOException  in case of a problem
121     */
122    public void open(HttpRoute route,
123                     HttpContext context, HttpParams params)
124        throws IOException {
125
126        if (route == null) {
127            throw new IllegalArgumentException
128                ("Route must not be null.");
129        }
130        if (params == null) {
131            throw new IllegalArgumentException
132                ("Parameters must not be null.");
133        }
134        if ((this.tracker != null) && this.tracker.isConnected()) {
135            throw new IllegalStateException("Connection already open.");
136        }
137
138        // - collect the arguments
139        // - call the operator
140        // - update the tracking data
141        // In this order, we can be sure that only a successful
142        // opening of the connection will be tracked.
143
144        this.tracker = new RouteTracker(route);
145        final HttpHost proxy  = route.getProxyHost();
146
147        connOperator.openConnection
148            (this.connection,
149             (proxy != null) ? proxy : route.getTargetHost(),
150             route.getLocalAddress(),
151             context, params);
152
153        RouteTracker localTracker = tracker; // capture volatile
154
155        // If this tracker was reset while connecting,
156        // fail early.
157        if (localTracker == null) {
158            throw new IOException("Request aborted");
159        }
160
161        if (proxy == null) {
162            localTracker.connectTarget(this.connection.isSecure());
163        } else {
164            localTracker.connectProxy(proxy, this.connection.isSecure());
165        }
166
167    }
168
169    /**
170     * Tracks tunnelling of the connection to the target.
171     * The tunnel has to be established outside by sending a CONNECT
172     * request to the (last) proxy.
173     *
174     * @param secure    <code>true</code> if the tunnel should be
175     *                  considered secure, <code>false</code> otherwise
176     * @param params    the parameters for tunnelling the connection
177     *
178     * @throws IOException  in case of a problem
179     */
180    public void tunnelTarget(boolean secure, HttpParams params)
181        throws IOException {
182
183        if (params == null) {
184            throw new IllegalArgumentException
185                ("Parameters must not be null.");
186        }
187
188        if ((this.tracker == null) || !this.tracker.isConnected()) {
189            throw new IllegalStateException("Connection not open.");
190        }
191        if (this.tracker.isTunnelled()) {
192            throw new IllegalStateException
193                ("Connection is already tunnelled.");
194        }
195
196        this.connection.update(null, tracker.getTargetHost(),
197                               secure, params);
198        this.tracker.tunnelTarget(secure);
199    }
200
201    /**
202     * Tracks tunnelling of the connection to a chained proxy.
203     * The tunnel has to be established outside by sending a CONNECT
204     * request to the previous proxy.
205     *
206     * @param next      the proxy to which the tunnel was established.
207     *  See {@link org.apache.http.conn.ManagedClientConnection#tunnelProxy
208     *                                  ManagedClientConnection.tunnelProxy}
209     *                  for details.
210     * @param secure    <code>true</code> if the tunnel should be
211     *                  considered secure, <code>false</code> otherwise
212     * @param params    the parameters for tunnelling the connection
213     *
214     * @throws IOException  in case of a problem
215     */
216    public void tunnelProxy(HttpHost next, boolean secure, HttpParams params)
217        throws IOException {
218
219        if (next == null) {
220            throw new IllegalArgumentException
221                ("Next proxy must not be null.");
222        }
223        if (params == null) {
224            throw new IllegalArgumentException
225                ("Parameters must not be null.");
226        }
227
228        //@@@ check for proxy in planned route?
229        if ((this.tracker == null) || !this.tracker.isConnected()) {
230            throw new IllegalStateException("Connection not open.");
231        }
232
233        this.connection.update(null, next, secure, params);
234        this.tracker.tunnelProxy(next, secure);
235    }
236
237    /**
238     * Layers a protocol on top of an established tunnel.
239     *
240     * @param context   the context for layering
241     * @param params    the parameters for layering
242     *
243     * @throws IOException  in case of a problem
244     */
245    public void layerProtocol(HttpContext context, HttpParams params)
246        throws IOException {
247
248        //@@@ is context allowed to be null? depends on operator?
249        if (params == null) {
250            throw new IllegalArgumentException
251                ("Parameters must not be null.");
252        }
253
254        if ((this.tracker == null) || !this.tracker.isConnected()) {
255            throw new IllegalStateException("Connection not open.");
256        }
257        if (!this.tracker.isTunnelled()) {
258            //@@@ allow this?
259            throw new IllegalStateException
260                ("Protocol layering without a tunnel not supported.");
261        }
262        if (this.tracker.isLayered()) {
263            throw new IllegalStateException
264                ("Multiple protocol layering not supported.");
265        }
266
267        // - collect the arguments
268        // - call the operator
269        // - update the tracking data
270        // In this order, we can be sure that only a successful
271        // layering on top of the connection will be tracked.
272
273        final HttpHost target = tracker.getTargetHost();
274
275        connOperator.updateSecureConnection(this.connection, target,
276                                             context, params);
277
278        this.tracker.layerProtocol(this.connection.isSecure());
279
280    }
281
282    /**
283     * Shuts down the entry.
284     *
285     * If {@link #open(HttpRoute, HttpContext, HttpParams)} is in progress,
286     * this will cause that open to possibly throw an {@link IOException}.
287     */
288    protected void shutdownEntry() {
289        tracker = null;
290        state = null;
291    }
292
293}
294