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: 329914 $
4    * $Date: 2005-10-31 16:24:47 -0500 (Mon, 31 Oct 2005) $
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                  //FIXME: badness - close to force reconnect.
75                  conn.close();
76              }
77          }
78      }
79      
80      /*** The http connection */
81      protected HttpConnection httpConnection;
82  
83      /***
84       * Collection of parameters associated with this connection manager.
85       */
86      private HttpConnectionManagerParams params = new HttpConnectionManagerParams(); 
87  
88      /***
89       * The time the connection was made idle.
90       */
91      private long idleStartTime = Long.MAX_VALUE;
92      
93      /***
94       * Used to test if {@link #httpConnection} is currently in use 
95       * (i.e. checked out).  This is only used as a sanity check to help
96       * debug cases where this connection manager is being used incorrectly.
97       * It will not be used to enforce thread safety.
98       */
99      private volatile boolean inUse = false;
100     
101     public SimpleHttpConnectionManager() {
102     }
103     
104     /***
105      * @see HttpConnectionManager#getConnection(HostConfiguration)
106      */
107     public HttpConnection getConnection(HostConfiguration hostConfiguration) {
108         return getConnection(hostConfiguration, 0);
109     }
110 
111     /***
112      * Gets the staleCheckingEnabled value to be set on HttpConnections that are created.
113      * 
114      * @return <code>true</code> if stale checking will be enabled on HttpConections
115      * 
116      * @see HttpConnection#isStaleCheckingEnabled()
117      * 
118      * @deprecated Use {@link HttpConnectionManagerParams#isStaleCheckingEnabled()},
119      * {@link HttpConnectionManager#getParams()}.
120      */
121     public boolean isConnectionStaleCheckingEnabled() {
122         return this.params.isStaleCheckingEnabled();
123     }
124 
125     /***
126      * Sets the staleCheckingEnabled value to be set on HttpConnections that are created.
127      * 
128      * @param connectionStaleCheckingEnabled <code>true</code> if stale checking will be enabled 
129      * on HttpConections
130      * 
131      * @see HttpConnection#setStaleCheckingEnabled(boolean)
132      * 
133      * @deprecated Use {@link HttpConnectionManagerParams#setStaleCheckingEnabled(boolean)},
134      * {@link HttpConnectionManager#getParams()}.
135      */
136     public void setConnectionStaleCheckingEnabled(boolean connectionStaleCheckingEnabled) {
137         this.params.setStaleCheckingEnabled(connectionStaleCheckingEnabled);
138     }
139     
140     /***
141      * @see HttpConnectionManager#getConnectionWithTimeout(HostConfiguration, long)
142      * 
143      * @since 3.0
144      */
145     public HttpConnection getConnectionWithTimeout(
146         HostConfiguration hostConfiguration, long timeout) {
147 
148         if (httpConnection == null) {
149             httpConnection = new HttpConnection(hostConfiguration);
150             httpConnection.setHttpConnectionManager(this);
151             httpConnection.getParams().setDefaults(this.params);
152         } else {
153 
154             // make sure the host and proxy are correct for this connection
155             // close it and set the values if they are not
156             if (!hostConfiguration.hostEquals(httpConnection)
157                 || !hostConfiguration.proxyEquals(httpConnection)) {
158                     
159                 if (httpConnection.isOpen()) {
160                     httpConnection.close();
161                 }
162 
163                 httpConnection.setHost(hostConfiguration.getHost());
164                 httpConnection.setPort(hostConfiguration.getPort());
165                 httpConnection.setProtocol(hostConfiguration.getProtocol());
166                 httpConnection.setLocalAddress(hostConfiguration.getLocalAddress());
167 
168                 httpConnection.setProxyHost(hostConfiguration.getProxyHost());
169                 httpConnection.setProxyPort(hostConfiguration.getProxyPort());
170             } else {
171                 finishLastResponse(httpConnection);
172             }
173         }
174 
175         // remove the connection from the timeout handler
176         idleStartTime = Long.MAX_VALUE;
177 
178         if (inUse) LOG.warn(MISUSE_MESSAGE);
179         inUse = true;
180         
181         return httpConnection;
182     }
183 
184 	/***
185 	 * @see HttpConnectionManager#getConnection(HostConfiguration, long)
186 	 * 
187 	 * @deprecated Use #getConnectionWithTimeout(HostConfiguration, long)
188 	 */
189 	public HttpConnection getConnection(
190 		HostConfiguration hostConfiguration, long timeout) {
191         return getConnectionWithTimeout(hostConfiguration, timeout);
192 	}
193 
194     /***
195      * @see HttpConnectionManager#releaseConnection(org.apache.commons.httpclient.HttpConnection)
196      */
197     public void releaseConnection(HttpConnection conn) {
198         if (conn != httpConnection) {
199             throw new IllegalStateException("Unexpected release of an unknown connection.");
200         }
201 
202         finishLastResponse(httpConnection);
203         
204         inUse = false;
205 
206         // track the time the connection was made idle
207         idleStartTime = System.currentTimeMillis();
208     }
209 
210     /***
211      * Returns {@link HttpConnectionManagerParams parameters} associated 
212      * with this connection manager.
213      * 
214      * @since 2.1
215      * 
216      * @see HttpConnectionManagerParams
217      */
218     public HttpConnectionManagerParams getParams() {
219         return this.params;
220     }
221 
222     /***
223      * Assigns {@link HttpConnectionManagerParams parameters} for this 
224      * connection manager.
225      * 
226      * @since 2.1
227      * 
228      * @see HttpConnectionManagerParams
229      */
230     public void setParams(final HttpConnectionManagerParams params) {
231         if (params == null) {
232             throw new IllegalArgumentException("Parameters may not be null");
233         }
234         this.params = params;
235     }
236     
237     /***
238      * @since 3.0
239      */
240     public void closeIdleConnections(long idleTimeout) {
241         long maxIdleTime = System.currentTimeMillis() - idleTimeout;
242         if (idleStartTime <= maxIdleTime) {
243             httpConnection.close();
244         }
245     }
246 }