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