HttpClient.java
  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  }