View Javadoc

    1   /*
    2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/HttpClient.java,v 1.98 2004/10/07 16:14:15 olegk Exp $
    3    * $Revision: 509577 $
    4    * $Date: 2007-02-20 15:28:18 +0100 (Tue, 20 Feb 2007) $
    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.security.Provider;
    35  import java.security.Security;
    36
    37  import org.apache.commons.httpclient.params.HttpClientParams;
    38  import org.apache.commons.logging.Log;
    39  import org.apache.commons.logging.LogFactory;
    40
    41  /**
    42   * <p>
    43   * An HTTP "user-agent", containing an {@link HttpState HTTP state} and
    44   * one or more {@link HttpConnection HTTP connections}, to which
    45   * {@link HttpMethod HTTP methods} can be applied.
    46   * </p>
    47   * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
    48   * @author <a href="mailto:rwaldhoff@apache.org">Rodney Waldhoff</a>
    49   * @author Sean C. Sullivan
    50   * @author <a href="mailto:dion@apache.org">dIon Gillard</a>
    51   * @author Ortwin Gl?ck
    52   * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
    53   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
    54   * @author Sam Maloney
    55   * @author Laura Werner
    56   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
    57   *
    58   * @version $Revision: 509577 $ $Date: 2007-02-20 15:28:18 +0100 (Tue, 20 Feb 2007) $
    59   */
    60  public class HttpClient {
    61
    62
    63      // -------------------------------------------------------------- Constants
    64
    65      /** Log object for this class. */
    66      private static final Log LOG = LogFactory.getLog(HttpClient.class);
    67
    68      static {
    69
    70          if (LOG.isDebugEnabled()) {
    71              try {
    72                  LOG.debug("Java version: " + System.getProperty("java.version"));
    73                  LOG.debug("Java vendor: " + System.getProperty("java.vendor"));
    74                  LOG.debug("Java class path: " + System.getProperty("java.class.path"));
    75                  LOG.debug("Operating system name: " + System.getProperty("os.name"));
    76                  LOG.debug("Operating system architecture: " + System.getProperty("os.arch"));
    77                  LOG.debug("Operating system version: " + System.getProperty("os.version"));
    78
    79                  Provider[] providers = Security.getProviders();
    80                  for (int i = 0; i < providers.length; i++) {
    81                      Provider provider = providers[i];
    82                      LOG.debug(provider.getName() + " " + provider.getVersion()
    83                         + ": " + provider.getInfo());
    84                  }
    85              } catch (SecurityException ignore) {
    86              }
    87          }
    88      }
    89      // ----------------------------------------------------------- Constructors
    90
    91      /**
    92       * Creates an instance of HttpClient using default {@link HttpClientParams parameter set}.
    93       *
    94       * @see HttpClientParams
    95       */
    96      public HttpClient() {
    97          this(new HttpClientParams());
    98      }
    99
    100     /**
    101      * Creates an instance of HttpClient using the given
    102      * {@link HttpClientParams parameter set}.
    103      *
    104      * @param params The {@link HttpClientParams parameters} to use.
    105      *
    106      * @see HttpClientParams
    107      *
    108      * @since 3.0
    109      */
    110     public HttpClient(HttpClientParams params) {
    111         super();
    112         if (params == null) {
    113             throw new IllegalArgumentException("Params may not be null");
    114         }
    115         this.params = params;
    116         this.httpConnectionManager = null;
    117         Class clazz = params.getConnectionManagerClass();
    118         if (clazz != null) {
    119             try {
    120                 this.httpConnectionManager = (HttpConnectionManager) clazz.newInstance();
    121             } catch (Exception e) {
    122                 LOG.warn("Error instantiating connection manager class, defaulting to"
    123                     + " SimpleHttpConnectionManager",
    124                     e);
    125             }
    126         }
    127         if (this.httpConnectionManager == null) {
    128             this.httpConnectionManager = new SimpleHttpConnectionManager();
    129         }
    130         if (this.httpConnectionManager != null) {
    131             this.httpConnectionManager.getParams().setDefaults(this.params);
    132         }
    133     }
    134
    135     /**
    136      * Creates an instance of HttpClient with a user specified
    137      * {@link HttpClientParams parameter set} and
    138      * {@link HttpConnectionManager HTTP connection manager}.
    139      *
    140      * @param params The {@link HttpClientParams parameters} to use.
    141      * @param httpConnectionManager The {@link HttpConnectionManager connection manager}
    142      * to use.
    143      *
    144      * @since 3.0
    145      */
    146     public HttpClient(HttpClientParams params, HttpConnectionManager httpConnectionManager) {
    147         super();
    148         if (httpConnectionManager == null) {
    149             throw new IllegalArgumentException("httpConnectionManager cannot be null");
    150         }
    151         if (params == null) {
    152             throw new IllegalArgumentException("Params may not be null");
    153         }
    154         this.params = params;
    155         this.httpConnectionManager = httpConnectionManager;
    156         this.httpConnectionManager.getParams().setDefaults(this.params);
    157     }
    158
    159     /**
    160      * Creates an instance of HttpClient with a user specified
    161      * {@link HttpConnectionManager HTTP connection manager}.
    162      *
    163      * @param httpConnectionManager The {@link HttpConnectionManager connection manager}
    164      * to use.
    165      *
    166      * @since 2.0
    167      */
    168     public HttpClient(HttpConnectionManager httpConnectionManager) {
    169         this(new HttpClientParams(), httpConnectionManager);
    170     }
    171
    172     // ----------------------------------------------------- Instance Variables
    173
    174     /**
    175      * The {@link HttpConnectionManager connection manager} being used to manage
    176      * connections for this HttpClient
    177      */
    178     private HttpConnectionManager httpConnectionManager;
    179
    180     /**
    181      * The {@link HttpState HTTP state} associated with this HttpClient.
    182      */
    183     private HttpState state = new HttpState();
    184
    185     /**
    186      * The {@link HttpClientParams collection of parameters} associated with this HttpClient.
    187      */
    188     private HttpClientParams params = null;
    189
    190     /**
    191      * The {@link HostConfiguration host configuration} associated with
    192      * the HttpClient
    193      */
    194     private HostConfiguration hostConfiguration = new HostConfiguration();
    195
    196     // ------------------------------------------------------------- Properties
    197
    198     /**
    199      * Returns {@link HttpState HTTP state} associated with the HttpClient.
    200      *
    201      * @see #setState(HttpState)
    202      * @return the shared client state
    203      */
    204     public synchronized HttpState getState() {
    205         return state;
    206     }
    207
    208     /**
    209      * Assigns {@link HttpState HTTP state} for the HttpClient.
    210      *
    211      * @see #getState()
    212      * @param state the new {@link HttpState HTTP state} for the client
    213      */
    214     public synchronized void setState(HttpState state) {
    215         this.state = state;
    216     }
    217
    218     /**
    219      * Defines how strictly the method follows the HTTP protocol specification
    220      * (see RFC 2616 and other relevant RFCs).
    221      *
    222      * In the strict mode the method precisely
    223      * implements the requirements of the specification, whereas in non-strict mode
    224      * it attempts to mimic the exact behaviour of commonly used HTTP agents,
    225      * which many HTTP servers expect.
    226      *
    227      * @param strictMode <tt>true</tt> for strict mode, <tt>false</tt> otherwise
    228      *
    229      * @see #isStrictMode()
    230      *
    231      * @deprecated Use {@link HttpClientParams#setParameter(String, Object)}
    232      * to exercise a more granular control over HTTP protocol strictness.
    233      */
    234     public synchronized void setStrictMode(boolean strictMode) {
    235         if (strictMode) {
    236             this.params.makeStrict();
    237         } else {
    238             this.params.makeLenient();
    239         }
    240     }
    241
    242     /**
    243      * Returns the value of the strict mode flag.
    244      *
    245      * @return <tt>true</tt> if strict mode is enabled, <tt>false</tt> otherwise
    246      *
    247      * @see #setStrictMode(boolean)
    248      *
    249      * @deprecated Use
    250      * {@link org.apache.commons.httpclient.params.HttpClientParams#getParameter(String)}
    251      * to exercise a more granular control over HTTP protocol strictness.
    252      */
    253     public synchronized boolean isStrictMode() {
    254         return false;
    255     }
    256
    257     /**
    258      * Sets the socket timeout (<tt>SO_TIMEOUT</tt>) in milliseconds which is the
    259      * timeout for waiting for data. A timeout value of zero is interpreted as an
    260      * infinite timeout.
    261      *
    262      * @param newTimeoutInMilliseconds Timeout in milliseconds
    263      *
    264      * @deprecated Use
    265      * {@link org.apache.commons.httpclient.params.HttpConnectionManagerParams#setSoTimeout(int)},
    266      * {@link HttpConnectionManager#getParams()}.
    267      *
    268      */
    269     public synchronized void setTimeout(int newTimeoutInMilliseconds) {
    270         this.params.setSoTimeout(newTimeoutInMilliseconds);
    271     }
    272
    273     /**
    274      * Sets the timeout in milliseconds used when retrieving an
    275      * {@link HttpConnection HTTP connection} from the
    276      * {@link HttpConnectionManager HTTP connection manager}.
    277      *
    278      * @param timeout the timeout in milliseconds
    279      *
    280      * @see HttpConnectionManager#getConnection(HostConfiguration, long)
    281      *
    282      * @deprecated Use
    283      * {@link org.apache.commons.httpclient.params.HttpClientParams#setConnectionManagerTimeout(long)},
    284      * {@link HttpClient#getParams()}
    285      */
    286     public synchronized void setHttpConnectionFactoryTimeout(long timeout) {
    287         this.params.setConnectionManagerTimeout(timeout);
    288     }
    289
    290     /**
    291      * Sets the timeout until a connection is etablished. A value of zero
    292      * means the timeout is not used. The default value is zero.
    293      *
    294      * @see HttpConnection#setConnectionTimeout(int)
    295      * @param newTimeoutInMilliseconds Timeout in milliseconds.
    296      *
    297      * @deprecated Use
    298      * {@link org.apache.commons.httpclient.params.HttpConnectionManagerParams#setConnectionTimeout(int)},
    299      * {@link HttpConnectionManager#getParams()}.
    300      */
    301     public synchronized void setConnectionTimeout(int newTimeoutInMilliseconds) {
    302        this.httpConnectionManager.getParams().setConnectionTimeout(newTimeoutInMilliseconds);
    303     }
    304
    305     // --------------------------------------------------------- Public Methods
    306
    307    /**
    308      * Executes the given {@link HttpMethod HTTP method}.
    309      *
    310      * @param method the {@link HttpMethod HTTP method} to execute.
    311      * @return the method's response code
    312      *
    313      * @throws IOException If an I/O (transport) error occurs. Some transport exceptions
    314      *                     can be recovered from.
    315      * @throws HttpException  If a protocol exception occurs. Usually protocol exceptions
    316      *                    cannot be recovered from.
    317      */
    318     public int executeMethod(HttpMethod method)
    319         throws IOException, HttpException  {
    320
    321         LOG.trace("enter HttpClient.executeMethod(HttpMethod)");
    322         // execute this method and use its host configuration, if it has one
    323         return executeMethod(null, method, null);
    324     }
    325
    326     /**
    327     * Executes the given {@link HttpMethod HTTP method} using custom
    328     * {@link HostConfiguration host configuration}.
    329     *
    330     * @param hostConfiguration The {@link HostConfiguration host configuration} to use.
    331      * If <code>null</code>, the host configuration returned by {@link #getHostConfiguration} will be used.
    332     * @param method the {@link HttpMethod HTTP method} to execute.
    333     * @return the method's response code
    334     *
    335     * @throws IOException If an I/O (transport) error occurs. Some transport exceptions
    336     *                     can be recovered from.
    337     * @throws HttpException  If a protocol exception occurs. Usually protocol exceptions
    338     *                    cannot be recovered from.
    339     * @since 2.0
    340     */
    341     public int executeMethod(final HostConfiguration hostConfiguration, final HttpMethod method)
    342         throws IOException, HttpException {
    343
    344         LOG.trace("enter HttpClient.executeMethod(HostConfiguration,HttpMethod)");
    345
    346         return executeMethod(hostConfiguration, method, null);
    347     }
    348
    349
    350
    351     /**
    352      * Executes the given {@link HttpMethod HTTP method} using the given custom
    353      * {@link HostConfiguration host configuration} with the given custom
    354      * {@link HttpState HTTP state}.
    355      *
    356      * @param hostconfig The {@link HostConfiguration host configuration} to use.
    357      * If <code>null</code>, the host configuration returned by {@link #getHostConfiguration} will be used.
    358      * @param method the {@link HttpMethod HTTP method} to execute.
    359      * @param state the {@link HttpState HTTP state} to use when executing the method.
    360      * If <code>null</code>, the state returned by {@link #getState} will be used.
    361      *
    362      * @return the method's response code
    363      *
    364      * @throws IOException If an I/O (transport) error occurs. Some transport exceptions
    365      *                     can be recovered from.
    366      * @throws HttpException  If a protocol exception occurs. Usually protocol exceptions
    367      *                    cannot be recovered from.
    368      * @since 2.0
    369      */
    370     public int executeMethod(HostConfiguration hostconfig,
    371         final HttpMethod method, final HttpState state)
    372         throws IOException, HttpException  {
    373
    374         LOG.trace("enter HttpClient.executeMethod(HostConfiguration,HttpMethod,HttpState)");
    375
    376         if (method == null) {
    377             throw new IllegalArgumentException("HttpMethod parameter may not be null");
    378         }
    379         HostConfiguration defaulthostconfig = getHostConfiguration();
    380         if (hostconfig == null) {
    381             hostconfig = defaulthostconfig;
    382         }
    383         URI uri = method.getURI();
    384         if (hostconfig == defaulthostconfig || uri.isAbsoluteURI()) {
    385             // make a deep copy of the host defaults
    386             hostconfig = (HostConfiguration) hostconfig.clone();
    387             if (uri.isAbsoluteURI()) {
    388                 hostconfig.setHost(uri);
    389             }
    390         }
    391
    392         HttpMethodDirector methodDirector = new HttpMethodDirector(
    393                 getHttpConnectionManager(),
    394                 hostconfig,
    395                 this.params,
    396                 (state == null ? getState() : state));
    397         methodDirector.executeMethod(method);
    398         return method.getStatusCode();
    399     }
    400
    401     /**
    402       * Returns the default host.
    403       *
    404       * @return The default host.
    405       *
    406       * @deprecated use #getHostConfiguration()
    407       */
    408      public String getHost() {
    409          return hostConfiguration.getHost();
    410      }
    411
    412      /**
    413       * Returns the default port.
    414       *
    415       * @return The default port.
    416       *
    417       * @deprecated use #getHostConfiguration()
    418       */
    419      public int getPort() {
    420          return hostConfiguration.getPort();
    421      }
    422
    423     /**
    424      * Returns the {@link HostConfiguration host configuration} associated with the
    425      * HttpClient.
    426      *
    427      * @return {@link HostConfiguration host configuration}
    428      *
    429      * @since 2.0
    430      */
    431     public synchronized HostConfiguration getHostConfiguration() {
    432         return hostConfiguration;
    433     }
    434
    435     /**
    436      * Assigns the {@link HostConfiguration host configuration} to use with the
    437      * HttpClient.
    438      *
    439      * @param hostConfiguration The {@link HostConfiguration host configuration} to set
    440      *
    441      * @since 2.0
    442      */
    443     public synchronized void setHostConfiguration(HostConfiguration hostConfiguration) {
    444         this.hostConfiguration = hostConfiguration;
    445     }
    446
    447     /**
    448      * Returns the {@link HttpConnectionManager HTTP connection manager} associated
    449      * with the HttpClient.
    450      *
    451      * @return {@link HttpConnectionManager HTTP connection manager}
    452      *
    453      * @since 2.0
    454      */
    455     public synchronized HttpConnectionManager getHttpConnectionManager() {
    456         return httpConnectionManager;
    457     }
    458
    459     /**
    460      * Assigns the {@link HttpConnectionManager HTTP connection manager} to use with
    461      * the HttpClient.
    462      *
    463      * @param httpConnectionManager The {@link HttpConnectionManager HTTP connection manager}
    464      *  to set
    465      *
    466      * @since 2.0
    467      */
    468     public synchronized void setHttpConnectionManager(
    469         HttpConnectionManager httpConnectionManager
    470     ) {
    471         this.httpConnectionManager = httpConnectionManager;
    472         if (this.httpConnectionManager != null) {
    473             this.httpConnectionManager.getParams().setDefaults(this.params);
    474         }
    475     }
    476
    477     /**
    478      * Returns {@link HttpClientParams HTTP protocol parameters} associated with this HttpClient.
    479      *
    480      * @since 3.0
    481      *
    482      * @see HttpClientParams
    483      */
    484     public HttpClientParams getParams() {
    485         return this.params;
    486     }
    487
    488     /**
    489      * Assigns {@link HttpClientParams HTTP protocol parameters} for this HttpClient.
    490      *
    491      * @since 3.0
    492      *
    493      * @see HttpClientParams
    494      */
    495     public void setParams(final HttpClientParams params) {
    496         if (params == null) {
    497             throw new IllegalArgumentException("Parameters may not be null");
    498         }
    499         this.params = params;
    500     }
    501
    502 }