View Javadoc

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  
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.SSLSocket;
36  import javax.net.ssl.SSLSession;
37  
38  import org.apache.http.HttpException;
39  import org.apache.http.HttpRequest;
40  import org.apache.http.HttpEntityEnclosingRequest;
41  import org.apache.http.HttpResponse;
42  import org.apache.http.HttpConnectionMetrics;
43  import org.apache.http.annotation.NotThreadSafe;
44  import org.apache.http.conn.OperatedClientConnection;
45  import org.apache.http.conn.ManagedClientConnection;
46  import org.apache.http.conn.ClientConnectionManager;
47  import org.apache.http.protocol.HttpContext;
48  
49  /**
50   * Abstract adapter from {@link OperatedClientConnection operated} to
51   * {@link ManagedClientConnection managed} client connections.
52   * Read and write methods are delegated to the wrapped connection.
53   * Operations affecting the connection state have to be implemented
54   * by derived classes. Operations for querying the connection state
55   * are delegated to the wrapped connection if there is one, or
56   * return a default value if there is none.
57   * <p>
58   * This adapter tracks the checkpoints for reusable communication states,
59   * as indicated by {@link #markReusable markReusable} and queried by
60   * {@link #isMarkedReusable isMarkedReusable}.
61   * All send and receive operations will automatically clear the mark.
62   * <p>
63   * Connection release calls are delegated to the connection manager,
64   * if there is one. {@link #abortConnection abortConnection} will
65   * clear the reusability mark first. The connection manager is
66   * expected to tolerate multiple calls to the release method.
67   *
68   * @since 4.0
69   *
70   * @deprecated (4.2)  do not use
71   */
72  @Deprecated
73  @NotThreadSafe
74  public abstract class AbstractClientConnAdapter implements ManagedClientConnection, HttpContext {
75  
76      /**
77       * The connection manager.
78       */
79      private final ClientConnectionManager connManager;
80  
81      /** The wrapped connection. */
82      private volatile OperatedClientConnection wrappedConnection;
83  
84      /** The reusability marker. */
85      private volatile boolean markedReusable;
86  
87      /** True if the connection has been shut down or released. */
88      private volatile boolean released;
89  
90      /** The duration this is valid for while idle (in ms). */
91      private volatile long duration;
92  
93      /**
94       * Creates a new connection adapter.
95       * The adapter is initially <i>not</i>
96       * {@link #isMarkedReusable marked} as reusable.
97       *
98       * @param mgr       the connection manager, or <code>null</code>
99       * @param conn      the connection to wrap, or <code>null</code>
100      */
101     protected AbstractClientConnAdapter(ClientConnectionManager mgr,
102                                         OperatedClientConnection conn) {
103         super();
104         connManager = mgr;
105         wrappedConnection = conn;
106         markedReusable = false;
107         released = false;
108         duration = Long.MAX_VALUE;
109     }
110 
111     /**
112      * Detaches this adapter from the wrapped connection.
113      * This adapter becomes useless.
114      */
115     protected synchronized void detach() {
116         wrappedConnection = null;
117         duration = Long.MAX_VALUE;
118     }
119 
120     protected OperatedClientConnection getWrappedConnection() {
121         return wrappedConnection;
122     }
123 
124     protected ClientConnectionManager getManager() {
125         return connManager;
126     }
127 
128     /**
129      * @deprecated (4.1)  use {@link #assertValid(OperatedClientConnection)}
130      */
131     protected final void assertNotAborted() throws InterruptedIOException {
132         if (isReleased()) {
133             throw new InterruptedIOException("Connection has been shut down");
134         }
135     }
136 
137     /**
138      * @since 4.1
139      * @return value of released flag
140      */
141     protected boolean isReleased() {
142         return released;
143     }
144 
145     /**
146      * Asserts that there is a valid wrapped connection to delegate to.
147      *
148      * @throws ConnectionShutdownException if there is no wrapped connection
149      *                                  or connection has been aborted
150      */
151     protected final void assertValid(
152             final OperatedClientConnection wrappedConn) throws ConnectionShutdownException {
153         if (isReleased() || wrappedConn == null) {
154             throw new ConnectionShutdownException();
155         }
156     }
157 
158     public boolean isOpen() {
159         OperatedClientConnection conn = getWrappedConnection();
160         if (conn == null)
161             return false;
162 
163         return conn.isOpen();
164     }
165 
166     public boolean isStale() {
167         if (isReleased())
168             return true;
169         OperatedClientConnection conn = getWrappedConnection();
170         if (conn == null)
171             return true;
172 
173         return conn.isStale();
174     }
175 
176     public void setSocketTimeout(int timeout) {
177         OperatedClientConnection conn = getWrappedConnection();
178         assertValid(conn);
179         conn.setSocketTimeout(timeout);
180     }
181 
182     public int getSocketTimeout() {
183         OperatedClientConnection conn = getWrappedConnection();
184         assertValid(conn);
185         return conn.getSocketTimeout();
186     }
187 
188     public HttpConnectionMetrics getMetrics() {
189         OperatedClientConnection conn = getWrappedConnection();
190         assertValid(conn);
191         return conn.getMetrics();
192     }
193 
194     public void flush() throws IOException {
195         OperatedClientConnection conn = getWrappedConnection();
196         assertValid(conn);
197         conn.flush();
198     }
199 
200     public boolean isResponseAvailable(int timeout) throws IOException {
201         OperatedClientConnection conn = getWrappedConnection();
202         assertValid(conn);
203         return conn.isResponseAvailable(timeout);
204     }
205 
206     public void receiveResponseEntity(HttpResponse response)
207         throws HttpException, IOException {
208         OperatedClientConnection conn = getWrappedConnection();
209         assertValid(conn);
210         unmarkReusable();
211         conn.receiveResponseEntity(response);
212     }
213 
214     public HttpResponse receiveResponseHeader()
215         throws HttpException, IOException {
216         OperatedClientConnection conn = getWrappedConnection();
217         assertValid(conn);
218         unmarkReusable();
219         return conn.receiveResponseHeader();
220     }
221 
222     public void sendRequestEntity(HttpEntityEnclosingRequest request)
223         throws HttpException, IOException {
224         OperatedClientConnection conn = getWrappedConnection();
225         assertValid(conn);
226         unmarkReusable();
227         conn.sendRequestEntity(request);
228     }
229 
230     public void sendRequestHeader(HttpRequest request)
231         throws HttpException, IOException {
232         OperatedClientConnection conn = getWrappedConnection();
233         assertValid(conn);
234         unmarkReusable();
235         conn.sendRequestHeader(request);
236     }
237 
238     public InetAddress getLocalAddress() {
239         OperatedClientConnection conn = getWrappedConnection();
240         assertValid(conn);
241         return conn.getLocalAddress();
242     }
243 
244     public int getLocalPort() {
245         OperatedClientConnection conn = getWrappedConnection();
246         assertValid(conn);
247         return conn.getLocalPort();
248     }
249 
250     public InetAddress getRemoteAddress() {
251         OperatedClientConnection conn = getWrappedConnection();
252         assertValid(conn);
253         return conn.getRemoteAddress();
254     }
255 
256     public int getRemotePort() {
257         OperatedClientConnection conn = getWrappedConnection();
258         assertValid(conn);
259         return conn.getRemotePort();
260     }
261 
262     public boolean isSecure() {
263         OperatedClientConnection conn = getWrappedConnection();
264         assertValid(conn);
265         return conn.isSecure();
266     }
267 
268     public SSLSession getSSLSession() {
269         OperatedClientConnection conn = getWrappedConnection();
270         assertValid(conn);
271         if (!isOpen())
272             return null;
273 
274         SSLSession result = null;
275         Socket    sock    = conn.getSocket();
276         if (sock instanceof SSLSocket) {
277             result = ((SSLSocket)sock).getSession();
278         }
279         return result;
280     }
281 
282     public void markReusable() {
283         markedReusable = true;
284     }
285 
286     public void unmarkReusable() {
287         markedReusable = false;
288     }
289 
290     public boolean isMarkedReusable() {
291         return markedReusable;
292     }
293 
294     public void setIdleDuration(long duration, TimeUnit unit) {
295         if(duration > 0) {
296             this.duration = unit.toMillis(duration);
297         } else {
298             this.duration = -1;
299         }
300     }
301 
302     public synchronized void releaseConnection() {
303         if (released) {
304             return;
305         }
306         released = true;
307         connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS);
308     }
309 
310     public synchronized void abortConnection() {
311         if (released) {
312             return;
313         }
314         released = true;
315         unmarkReusable();
316         try {
317             shutdown();
318         } catch (IOException ignore) {
319         }
320         connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS);
321     }
322 
323     public Object getAttribute(final String id) {
324         OperatedClientConnection conn = getWrappedConnection();
325         assertValid(conn);
326         if (conn instanceof HttpContext) {
327             return ((HttpContext) conn).getAttribute(id);
328         } else {
329             return null;
330         }
331     }
332 
333     public Object removeAttribute(final String id) {
334         OperatedClientConnection conn = getWrappedConnection();
335         assertValid(conn);
336         if (conn instanceof HttpContext) {
337             return ((HttpContext) conn).removeAttribute(id);
338         } else {
339             return null;
340         }
341     }
342 
343     public void setAttribute(final String id, final Object obj) {
344         OperatedClientConnection conn = getWrappedConnection();
345         assertValid(conn);
346         if (conn instanceof HttpContext) {
347             ((HttpContext) conn).setAttribute(id, obj);
348         }
349     }
350 
351 }