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: 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 }