View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with 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,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.conn;
28  
29  import java.io.IOException;
30  import java.io.InterruptedIOException;
31  import java.net.InetAddress;
32  import java.net.Socket;
33  import java.util.concurrent.TimeUnit;
34  
35  import javax.net.ssl.SSLSession;
36  import javax.net.ssl.SSLSocket;
37  
38  import org.apache.http.HttpConnectionMetrics;
39  import org.apache.http.HttpEntityEnclosingRequest;
40  import org.apache.http.HttpException;
41  import org.apache.http.HttpHost;
42  import org.apache.http.HttpRequest;
43  import org.apache.http.HttpResponse;
44  import org.apache.http.annotation.NotThreadSafe;
45  import org.apache.http.conn.ClientConnectionManager;
46  import org.apache.http.conn.ClientConnectionOperator;
47  import org.apache.http.conn.ManagedClientConnection;
48  import org.apache.http.conn.OperatedClientConnection;
49  import org.apache.http.conn.routing.HttpRoute;
50  import org.apache.http.conn.routing.RouteTracker;
51  import org.apache.http.params.HttpParams;
52  import org.apache.http.protocol.HttpContext;
53  import org.apache.http.util.Args;
54  import org.apache.http.util.Asserts;
55  
56  /**
57   * @since 4.2
58   *
59   * @deprecated (4.3) use {@link ManagedHttpClientConnectionFactory}.
60   */
61  @Deprecated
62  @NotThreadSafe
63  class ManagedClientConnectionImpl implements ManagedClientConnection {
64  
65      private final ClientConnectionManager manager;
66      private final ClientConnectionOperator operator;
67      private volatile HttpPoolEntry poolEntry;
68      private volatile boolean reusable;
69      private volatile long duration;
70  
71      ManagedClientConnectionImpl(
72              final ClientConnectionManager manager,
73              final ClientConnectionOperator operator,
74              final HttpPoolEntry entry) {
75          super();
76          Args.notNull(manager, "Connection manager");
77          Args.notNull(operator, "Connection operator");
78          Args.notNull(entry, "HTTP pool entry");
79          this.manager = manager;
80          this.operator = operator;
81          this.poolEntry = entry;
82          this.reusable = false;
83          this.duration = Long.MAX_VALUE;
84      }
85  
86      public String getId() {
87          return null;
88      }
89  
90      HttpPoolEntry getPoolEntry() {
91          return this.poolEntry;
92      }
93  
94      HttpPoolEntry detach() {
95          final HttpPoolEntry local = this.poolEntry;
96          this.poolEntry = null;
97          return local;
98      }
99  
100     public ClientConnectionManager getManager() {
101         return this.manager;
102     }
103 
104     private OperatedClientConnection getConnection() {
105         final HttpPoolEntry local = this.poolEntry;
106         if (local == null) {
107             return null;
108         }
109         return local.getConnection();
110     }
111 
112     private OperatedClientConnection ensureConnection() {
113         final HttpPoolEntry local = this.poolEntry;
114         if (local == null) {
115             throw new ConnectionShutdownException();
116         }
117         return local.getConnection();
118     }
119 
120     private HttpPoolEntry ensurePoolEntry() {
121         final HttpPoolEntry local = this.poolEntry;
122         if (local == null) {
123             throw new ConnectionShutdownException();
124         }
125         return local;
126     }
127 
128     public void close() throws IOException {
129         final HttpPoolEntry local = this.poolEntry;
130         if (local != null) {
131             final OperatedClientConnection conn = local.getConnection();
132             local.getTracker().reset();
133             conn.close();
134         }
135     }
136 
137     public void shutdown() throws IOException {
138         final HttpPoolEntry local = this.poolEntry;
139         if (local != null) {
140             final OperatedClientConnection conn = local.getConnection();
141             local.getTracker().reset();
142             conn.shutdown();
143         }
144     }
145 
146     public boolean isOpen() {
147         final OperatedClientConnection conn = getConnection();
148         if (conn != null) {
149             return conn.isOpen();
150         } else {
151             return false;
152         }
153     }
154 
155     public boolean isStale() {
156         final OperatedClientConnection conn = getConnection();
157         if (conn != null) {
158             return conn.isStale();
159         } else {
160             return true;
161         }
162     }
163 
164     public void setSocketTimeout(final int timeout) {
165         final OperatedClientConnection conn = ensureConnection();
166         conn.setSocketTimeout(timeout);
167     }
168 
169     public int getSocketTimeout() {
170         final OperatedClientConnection conn = ensureConnection();
171         return conn.getSocketTimeout();
172     }
173 
174     public HttpConnectionMetrics getMetrics() {
175         final OperatedClientConnection conn = ensureConnection();
176         return conn.getMetrics();
177     }
178 
179     public void flush() throws IOException {
180         final OperatedClientConnection conn = ensureConnection();
181         conn.flush();
182     }
183 
184     public boolean isResponseAvailable(final int timeout) throws IOException {
185         final OperatedClientConnection conn = ensureConnection();
186         return conn.isResponseAvailable(timeout);
187     }
188 
189     public void receiveResponseEntity(
190             final HttpResponse response) throws HttpException, IOException {
191         final OperatedClientConnection conn = ensureConnection();
192         conn.receiveResponseEntity(response);
193     }
194 
195     public HttpResponse receiveResponseHeader() throws HttpException, IOException {
196         final OperatedClientConnection conn = ensureConnection();
197         return conn.receiveResponseHeader();
198     }
199 
200     public void sendRequestEntity(
201             final HttpEntityEnclosingRequest request) throws HttpException, IOException {
202         final OperatedClientConnection conn = ensureConnection();
203         conn.sendRequestEntity(request);
204     }
205 
206     public void sendRequestHeader(
207             final HttpRequest request) throws HttpException, IOException {
208         final OperatedClientConnection conn = ensureConnection();
209         conn.sendRequestHeader(request);
210     }
211 
212     public InetAddress getLocalAddress() {
213         final OperatedClientConnection conn = ensureConnection();
214         return conn.getLocalAddress();
215     }
216 
217     public int getLocalPort() {
218         final OperatedClientConnection conn = ensureConnection();
219         return conn.getLocalPort();
220     }
221 
222     public InetAddress getRemoteAddress() {
223         final OperatedClientConnection conn = ensureConnection();
224         return conn.getRemoteAddress();
225     }
226 
227     public int getRemotePort() {
228         final OperatedClientConnection conn = ensureConnection();
229         return conn.getRemotePort();
230     }
231 
232     public boolean isSecure() {
233         final OperatedClientConnection conn = ensureConnection();
234         return conn.isSecure();
235     }
236 
237     public void bind(final Socket socket) throws IOException {
238         throw new UnsupportedOperationException();
239     }
240 
241     public Socket getSocket() {
242         final OperatedClientConnection conn = ensureConnection();
243         return conn.getSocket();
244     }
245 
246     public SSLSession getSSLSession() {
247         final OperatedClientConnection conn = ensureConnection();
248         SSLSession result = null;
249         final Socket sock = conn.getSocket();
250         if (sock instanceof SSLSocket) {
251             result = ((SSLSocket)sock).getSession();
252         }
253         return result;
254     }
255 
256     public Object getAttribute(final String id) {
257         final OperatedClientConnection conn = ensureConnection();
258         if (conn instanceof HttpContext) {
259             return ((HttpContext) conn).getAttribute(id);
260         } else {
261             return null;
262         }
263     }
264 
265     public Object removeAttribute(final String id) {
266         final OperatedClientConnection conn = ensureConnection();
267         if (conn instanceof HttpContext) {
268             return ((HttpContext) conn).removeAttribute(id);
269         } else {
270             return null;
271         }
272     }
273 
274     public void setAttribute(final String id, final Object obj) {
275         final OperatedClientConnection conn = ensureConnection();
276         if (conn instanceof HttpContext) {
277             ((HttpContext) conn).setAttribute(id, obj);
278         }
279     }
280 
281     public HttpRoute getRoute() {
282         final HttpPoolEntry local = ensurePoolEntry();
283         return local.getEffectiveRoute();
284     }
285 
286     public void open(
287             final HttpRoute route,
288             final HttpContext context,
289             final HttpParams params) throws IOException {
290         Args.notNull(route, "Route");
291         Args.notNull(params, "HTTP parameters");
292         final OperatedClientConnection conn;
293         synchronized (this) {
294             if (this.poolEntry == null) {
295                 throw new ConnectionShutdownException();
296             }
297             final RouteTracker tracker = this.poolEntry.getTracker();
298             Asserts.notNull(tracker, "Route tracker");
299             Asserts.check(!tracker.isConnected(), "Connection already open");
300             conn = this.poolEntry.getConnection();
301         }
302 
303         final HttpHost proxy  = route.getProxyHost();
304         this.operator.openConnection(
305                 conn,
306                 (proxy != null) ? proxy : route.getTargetHost(),
307                 route.getLocalAddress(),
308                 context, params);
309 
310         synchronized (this) {
311             if (this.poolEntry == null) {
312                 throw new InterruptedIOException();
313             }
314             final RouteTracker tracker = this.poolEntry.getTracker();
315             if (proxy == null) {
316                 tracker.connectTarget(conn.isSecure());
317             } else {
318                 tracker.connectProxy(proxy, conn.isSecure());
319             }
320         }
321     }
322 
323     public void tunnelTarget(
324             final boolean secure, final HttpParams params) throws IOException {
325         Args.notNull(params, "HTTP parameters");
326         final HttpHost target;
327         final OperatedClientConnection conn;
328         synchronized (this) {
329             if (this.poolEntry == null) {
330                 throw new ConnectionShutdownException();
331             }
332             final RouteTracker tracker = this.poolEntry.getTracker();
333             Asserts.notNull(tracker, "Route tracker");
334             Asserts.check(tracker.isConnected(), "Connection not open");
335             Asserts.check(!tracker.isTunnelled(), "Connection is already tunnelled");
336             target = tracker.getTargetHost();
337             conn = this.poolEntry.getConnection();
338         }
339 
340         conn.update(null, target, secure, params);
341 
342         synchronized (this) {
343             if (this.poolEntry == null) {
344                 throw new InterruptedIOException();
345             }
346             final RouteTracker tracker = this.poolEntry.getTracker();
347             tracker.tunnelTarget(secure);
348         }
349     }
350 
351     public void tunnelProxy(
352             final HttpHost next, final boolean secure, final HttpParams params) throws IOException {
353         Args.notNull(next, "Next proxy");
354         Args.notNull(params, "HTTP parameters");
355         final OperatedClientConnection conn;
356         synchronized (this) {
357             if (this.poolEntry == null) {
358                 throw new ConnectionShutdownException();
359             }
360             final RouteTracker tracker = this.poolEntry.getTracker();
361             Asserts.notNull(tracker, "Route tracker");
362             Asserts.check(tracker.isConnected(), "Connection not open");
363             conn = this.poolEntry.getConnection();
364         }
365 
366         conn.update(null, next, secure, params);
367 
368         synchronized (this) {
369             if (this.poolEntry == null) {
370                 throw new InterruptedIOException();
371             }
372             final RouteTracker tracker = this.poolEntry.getTracker();
373             tracker.tunnelProxy(next, secure);
374         }
375     }
376 
377     public void layerProtocol(
378             final HttpContext context, final HttpParams params) throws IOException {
379         Args.notNull(params, "HTTP parameters");
380         final HttpHost target;
381         final OperatedClientConnection conn;
382         synchronized (this) {
383             if (this.poolEntry == null) {
384                 throw new ConnectionShutdownException();
385             }
386             final RouteTracker tracker = this.poolEntry.getTracker();
387             Asserts.notNull(tracker, "Route tracker");
388             Asserts.check(tracker.isConnected(), "Connection not open");
389             Asserts.check(tracker.isTunnelled(), "Protocol layering without a tunnel not supported");
390             Asserts.check(!tracker.isLayered(), "Multiple protocol layering not supported");
391             target = tracker.getTargetHost();
392             conn = this.poolEntry.getConnection();
393         }
394         this.operator.updateSecureConnection(conn, target, context, params);
395 
396         synchronized (this) {
397             if (this.poolEntry == null) {
398                 throw new InterruptedIOException();
399             }
400             final RouteTracker tracker = this.poolEntry.getTracker();
401             tracker.layerProtocol(conn.isSecure());
402         }
403     }
404 
405     public Object getState() {
406         final HttpPoolEntry local = ensurePoolEntry();
407         return local.getState();
408     }
409 
410     public void setState(final Object state) {
411         final HttpPoolEntry local = ensurePoolEntry();
412         local.setState(state);
413     }
414 
415     public void markReusable() {
416         this.reusable = true;
417     }
418 
419     public void unmarkReusable() {
420         this.reusable = false;
421     }
422 
423     public boolean isMarkedReusable() {
424         return this.reusable;
425     }
426 
427     public void setIdleDuration(final long duration, final TimeUnit unit) {
428         if(duration > 0) {
429             this.duration = unit.toMillis(duration);
430         } else {
431             this.duration = -1;
432         }
433     }
434 
435     public void releaseConnection() {
436         synchronized (this) {
437             if (this.poolEntry == null) {
438                 return;
439             }
440             this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS);
441             this.poolEntry = null;
442         }
443     }
444 
445     public void abortConnection() {
446         synchronized (this) {
447             if (this.poolEntry == null) {
448                 return;
449             }
450             this.reusable = false;
451             final OperatedClientConnection conn = this.poolEntry.getConnection();
452             try {
453                 conn.shutdown();
454             } catch (final IOException ignore) {
455             }
456             this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS);
457             this.poolEntry = null;
458         }
459     }
460 
461 }