View Javadoc

1   /*
2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/SimpleHttpConnectionManager.java,v 1.23 2004/10/16 22:40:08 mbecke Exp $
3    * $Revision: 414231 $
4    * $Date: 2006-06-14 15:01:48 +0200 (Wed, 14 Jun 2006) $
5    *
6    * ====================================================================
7    *
8    *  Copyright 2002-2004 The Apache Software Foundation
9    *
10   *  Licensed under the Apache License, Version 2.0 (the "License");
11   *  you may not use this file except in compliance with the License.
12   *  You may obtain a copy of the License at
13   *
14   *      http://www.apache.org/licenses/LICENSE-2.0
15   *
16   *  Unless required by applicable law or agreed to in writing, software
17   *  distributed under the License is distributed on an "AS IS" BASIS,
18   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   *  See the License for the specific language governing permissions and
20   *  limitations under the License.
21   * ====================================================================
22   *
23   * This software consists of voluntary contributions made by many
24   * individuals on behalf of the Apache Software Foundation.  For more
25   * information on the Apache Software Foundation, please see
26   * <http://www.apache.org/>.
27   *
28   */
29  
30  package org.apache.commons.httpclient;
31  
32  import java.io.IOException;
33  import java.io.InputStream;
34  
35  import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  
39  /***
40   * A connection manager that provides access to a single HttpConnection.  This
41   * manager makes no attempt to provide exclusive access to the contained
42   * HttpConnection.
43   *
44   * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
45   * @author Eric Johnson
46   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
47   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
48   * @author Laura Werner
49   * 
50   * @since 2.0
51   */
52  public class SimpleHttpConnectionManager implements HttpConnectionManager {
53  
54      private static final Log LOG = LogFactory.getLog(SimpleHttpConnectionManager.class);
55  
56      private static final String MISUSE_MESSAGE = 
57          "SimpleHttpConnectionManager being used incorrectly.  Be sure that"
58          + " HttpMethod.releaseConnection() is always called and that only one thread"
59          + " and/or method is using this connection manager at a time.";
60      
61      /***
62       * Since the same connection is about to be reused, make sure the
63       * previous request was completely processed, and if not
64       * consume it now.
65       * @param conn The connection
66       */
67      static void finishLastResponse(HttpConnection conn) {
68          InputStream lastResponse = conn.getLastResponseInputStream();
69          if (lastResponse != null) {
70              conn.setLastResponseInputStream(null);
71              try {
72                  lastResponse.close();
73              } catch (IOException ioe) {
74                  conn.close();
75              }
76          }
77      }
78      
79      /*** The http connection */
80      protected HttpConnection httpConnection;
81  
82      /***
83       * Collection of parameters associated with this connection manager.
84       */
85      private HttpConnectionManagerParams params = new HttpConnectionManagerParams(); 
86  
87      /***
88       * The time the connection was made idle.
89       */
90      private long idleStartTime = Long.MAX_VALUE;
91      
92      /***
93       * Used to test if {@link #httpConnection} is currently in use 
94       * (i.e. checked out).  This is only used as a sanity check to help
95       * debug cases where this connection manager is being used incorrectly.
96       * It will not be used to enforce thread safety.
97       */
98      private volatile boolean inUse = false;
99  
100     private boolean alwaysClose = false;
101 
102     /***
103      * The connection manager created with this constructor will try to keep the 
104      * connection open (alive) between consecutive requests if the alwaysClose 
105      * parameter is set to <tt>false</tt>. Otherwise the connection manager will 
106      * always close connections upon release.
107      * 
108      * @param alwaysClose if set <tt>true</tt>, the connection manager will always
109      *    close connections upon release.
110      */
111     public SimpleHttpConnectionManager(boolean alwaysClose) {
112         super();
113         this.alwaysClose = alwaysClose;
114     }
115     
116     /***
117      * The connection manager created with this constructor will always try to keep 
118      * the connection open (alive) between consecutive requests.
119      */
120     public SimpleHttpConnectionManager() {
121         super();
122     }
123     
124     /***
125      * @see HttpConnectionManager#getConnection(HostConfiguration)
126      */
127     public HttpConnection getConnection(HostConfiguration hostConfiguration) {
128         return getConnection(hostConfiguration, 0);
129     }
130 
131     /***
132      * Gets the staleCheckingEnabled value to be set on HttpConnections that are created.
133      * 
134      * @return <code>true</code> if stale checking will be enabled on HttpConections
135      * 
136      * @see HttpConnection#isStaleCheckingEnabled()
137      * 
138      * @deprecated Use {@link HttpConnectionManagerParams#isStaleCheckingEnabled()},
139      * {@link HttpConnectionManager#getParams()}.
140      */
141     public boolean isConnectionStaleCheckingEnabled() {
142         return this.params.isStaleCheckingEnabled();
143     }
144 
145     /***
146      * Sets the staleCheckingEnabled value to be set on HttpConnections that are created.
147      * 
148      * @param connectionStaleCheckingEnabled <code>true</code> if stale checking will be enabled 
149      * on HttpConections
150      * 
151      * @see HttpConnection#setStaleCheckingEnabled(boolean)
152      * 
153      * @deprecated Use {@link HttpConnectionManagerParams#setStaleCheckingEnabled(boolean)},
154      * {@link HttpConnectionManager#getParams()}.
155      */
156     public void setConnectionStaleCheckingEnabled(boolean connectionStaleCheckingEnabled) {
157         this.params.setStaleCheckingEnabled(connectionStaleCheckingEnabled);
158     }
159     
160     /***
161      * This method always returns the same connection object. If the connection is already
162      * open, it will be closed and the new host configuration will be applied.
163      * 
164      * @param hostConfiguration The host configuration specifying the connection
165      *        details.
166      * @param timeout this parameter has no effect. The connection is always returned
167      *        immediately.
168      * @since 3.0
169      */
170     public HttpConnection getConnectionWithTimeout(
171         HostConfiguration hostConfiguration, long timeout) {
172 
173         if (httpConnection == null) {
174             httpConnection = new HttpConnection(hostConfiguration);
175             httpConnection.setHttpConnectionManager(this);
176             httpConnection.getParams().setDefaults(this.params);
177         } else {
178 
179             // make sure the host and proxy are correct for this connection
180             // close it and set the values if they are not
181             if (!hostConfiguration.hostEquals(httpConnection)
182                 || !hostConfiguration.proxyEquals(httpConnection)) {
183                     
184                 if (httpConnection.isOpen()) {
185                     httpConnection.close();
186                 }
187 
188                 httpConnection.setHost(hostConfiguration.getHost());
189                 httpConnection.setPort(hostConfiguration.getPort());
190                 httpConnection.setProtocol(hostConfiguration.getProtocol());
191                 httpConnection.setLocalAddress(hostConfiguration.getLocalAddress());
192 
193                 httpConnection.setProxyHost(hostConfiguration.getProxyHost());
194                 httpConnection.setProxyPort(hostConfiguration.getProxyPort());
195             } else {
196                 finishLastResponse(httpConnection);
197             }
198         }
199 
200         // remove the connection from the timeout handler
201         idleStartTime = Long.MAX_VALUE;
202 
203         if (inUse) LOG.warn(MISUSE_MESSAGE);
204         inUse = true;
205         
206         return httpConnection;
207     }
208 
209 	/***
210 	 * @see HttpConnectionManager#getConnection(HostConfiguration, long)
211 	 * 
212 	 * @deprecated Use #getConnectionWithTimeout(HostConfiguration, long)
213 	 */
214 	public HttpConnection getConnection(
215 		HostConfiguration hostConfiguration, long timeout) {
216         return getConnectionWithTimeout(hostConfiguration, timeout);
217 	}
218 
219     /***
220      * @see HttpConnectionManager#releaseConnection(org.apache.commons.httpclient.HttpConnection)
221      */
222     public void releaseConnection(HttpConnection conn) {
223         if (conn != httpConnection) {
224             throw new IllegalStateException("Unexpected release of an unknown connection.");
225         }
226         if (this.alwaysClose) {
227             httpConnection.close();
228         } else {
229             // make sure the connection is reuseable
230             finishLastResponse(httpConnection);
231         }
232         
233         inUse = false;
234 
235         // track the time the connection was made idle
236         idleStartTime = System.currentTimeMillis();
237     }
238 
239     /***
240      * Returns {@link HttpConnectionManagerParams parameters} associated 
241      * with this connection manager.
242      * 
243      * @since 2.1
244      * 
245      * @see HttpConnectionManagerParams
246      */
247     public HttpConnectionManagerParams getParams() {
248         return this.params;
249     }
250 
251     /***
252      * Assigns {@link HttpConnectionManagerParams parameters} for this 
253      * connection manager.
254      * 
255      * @since 2.1
256      * 
257      * @see HttpConnectionManagerParams
258      */
259     public void setParams(final HttpConnectionManagerParams params) {
260         if (params == null) {
261             throw new IllegalArgumentException("Parameters may not be null");
262         }
263         this.params = params;
264     }
265     
266     /***
267      * @since 3.0
268      */
269     public void closeIdleConnections(long idleTimeout) {
270         long maxIdleTime = System.currentTimeMillis() - idleTimeout;
271         if (idleStartTime <= maxIdleTime) {
272             httpConnection.close();
273         }
274     }
275     
276     /***
277      * since 3.1
278      */
279     public void shutdown() {
280         httpConnection.close();
281     }
282     
283 }