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