View Javadoc

1   /*
2    * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/oac.hc3x/trunk/src/java/org/apache/commons/httpclient/HttpClient.java $
3    * $Revision$
4    * $Date$
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$ $Date$
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 }