KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > httpclient > HttpClient


1 /*
2  * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpClient.java,v 1.76.2.6 2004/04/09 12:04:12 olegk Exp $
3  * $Revision: 1.76.2.6 $
4  * $Date: 2004/04/09 12:04:12 $
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  * [Additional notices, if required by prior licensing conditions]
29  *
30  */

31
32 package org.apache.commons.httpclient;
33
34 import java.io.IOException JavaDoc;
35 import java.net.URL JavaDoc;
36 import java.security.Security JavaDoc;
37 import java.security.Provider JavaDoc;
38
39 import org.apache.commons.httpclient.protocol.Protocol;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42
43
44 /**
45  * <p>
46  * An HTTP "user-agent", containing an {@link HttpState HTTP state} and
47  * one or more {@link HttpConnection HTTP connections}, to which
48  * {@link HttpMethod HTTP methods} can be applied.
49  * </p>
50  * @author <a HREF="mailto:remm@apache.org">Remy Maucherat</a>
51  * @author <a HREF="mailto:rwaldhoff@apache.org">Rodney Waldhoff</a>
52  * @author Sean C. Sullivan
53  * @author <a HREF="mailto:dion@apache.org">dIon Gillard</a>
54  * @author Ortwin Glück
55  * @author <a HREF="mailto:becke@u.washington.edu">Michael Becke</a>
56  * @author <a HREF="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
57  * @author Sam Maloney
58  * @author Laura Werner
59  * @author <a HREF="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
60  *
61  * @version $Revision: 1.76.2.6 $ $Date: 2004/04/09 12:04:12 $
62  */

63 public class HttpClient {
64
65
66     // -------------------------------------------------------------- Constants
67

68     /** Log object for this class. */
69     private static final Log LOG = LogFactory.getLog(HttpClient.class);
70
71     static {
72         if (LOG.isDebugEnabled()) {
73             try {
74                 LOG.debug("Java version: " + System.getProperty("java.version"));
75                 LOG.debug("Java vendor: " + System.getProperty("java.vendor"));
76                 LOG.debug("Java class path: " + System.getProperty("java.class.path"));
77                 LOG.debug("Operating system name: " + System.getProperty("os.name"));
78                 LOG.debug("Operating system architecture: " + System.getProperty("os.arch"));
79                 LOG.debug("Operating system version: " + System.getProperty("os.version"));
80
81                 Provider JavaDoc[] providers = Security.getProviders();
82                 for (int i = 0; i < providers.length; i++) {
83                     Provider JavaDoc provider = providers[i];
84                     LOG.debug(provider.getName() + " " + provider.getVersion()
85                        + ": " + provider.getInfo());
86                 }
87             } catch(SecurityException JavaDoc ignore) {
88             }
89         }
90     }
91     // ----------------------------------------------------------- Constructors
92

93     /**
94      * Creates an instance of HttpClient using a
95      * {@link SimpleHttpConnectionManager simple HTTP connection manager}.
96      *
97      * @see SimpleHttpConnectionManager
98      */

99     public HttpClient() {
100         this(new SimpleHttpConnectionManager());
101     }
102
103     /**
104      * Creates an instance of HttpClient with a user specified connection manager.
105      * @param httpConnectionManager The {@link HttpConnectionManager connection manager}
106      * to use.
107      *
108      * @since 2.0
109      */

110     public HttpClient(HttpConnectionManager httpConnectionManager) {
111
112         if (httpConnectionManager == null) {
113             throw new IllegalArgumentException JavaDoc("httpConnectionManager cannot be null");
114         }
115
116         this.state = new HttpState();
117         this.httpConnectionManager = httpConnectionManager;
118
119         this.hostConfiguration = new HostConfiguration();
120         
121     }
122     
123     // ----------------------------------------------------- Instance Variables
124

125     /**
126      * The {@link HttpConnectionManager connection manager} being used to manage
127      * connections for this HttpClient
128      */

129     private HttpConnectionManager httpConnectionManager;
130
131     /**
132      * The {@link HttpState HTTP state} associated with this HttpClient.
133      */

134     private HttpState state;
135
136     /**
137      * The timout in milliseconds when waiting for a connection from the
138      * {@link HttpConnectionManager connection manager}
139      */

140     private long httpConnectionTimeout = 0;
141
142     /**
143      * The socket timeout in milliseconds.
144      */

145     private int timeoutInMilliseconds = 0;
146
147     /**
148      * The connection timeout in milliseconds.
149      */

150     private int connectionTimeout = 0;
151
152     /**
153      * The {@link HostConfiguration host configuration} associated with
154      * the HttpClient
155      */

156     private HostConfiguration hostConfiguration;
157     
158     /**
159      * True if strict mode is enabled.
160      */

161     private boolean strictMode = false;
162
163     // ------------------------------------------------------------- Properties
164

165     /**
166      * Returns {@link HttpState HTTP state} associated with the HttpClient.
167      *
168      * @see #setState(HttpState)
169      * @return the shared client state
170      */

171     public synchronized HttpState getState() {
172         return state;
173     }
174
175     /**
176      * Assigns {@link HttpState HTTP state} for the HttpClient.
177      *
178      * @see #getState()
179      * @param state the new {@link HttpState HTTP state} for the client
180      */

181     public synchronized void setState(HttpState state) {
182         this.state = state;
183     }
184
185     /**
186      * Defines how strictly the method follows the HTTP protocol specification
187      * (see RFC 2616 and other relevant RFCs).
188      *
189      * In the strict mode the method precisely
190      * implements the requirements of the specification, whereas in non-strict mode
191      * it attempts to mimic the exact behaviour of commonly used HTTP agents,
192      * which many HTTP servers expect.
193      *
194      * @param strictMode <tt>true</tt> for strict mode, <tt>false</tt> otherwise
195      *
196      * @see #isStrictMode()
197      */

198     public synchronized void setStrictMode(boolean strictMode) {
199         this.strictMode = strictMode;
200     }
201
202     /**
203      * Returns the value of the strict mode flag.
204      *
205      * @return <tt>true</tt> if strict mode is enabled, <tt>false</tt> otherwise
206      *
207      * @see #setStrictMode(boolean)
208      */

209     public synchronized boolean isStrictMode() {
210         return strictMode;
211     }
212
213     /**
214      * Sets the socket timeout (<tt>SO_TIMEOUT</tt>) in milliseconds which is the
215      * timeout for waiting for data. A timeout value of zero is interpreted as an
216      * infinite timeout.
217      *
218      * @param newTimeoutInMilliseconds Timeout in milliseconds
219      */

220     public synchronized void setTimeout(int newTimeoutInMilliseconds) {
221         this.timeoutInMilliseconds = newTimeoutInMilliseconds;
222     }
223
224     /**
225      * Sets the timeout in milliseconds used when retrieving an
226      * {@link HttpConnection HTTP connection} from the
227      * {@link HttpConnectionManager HTTP connection manager}.
228      *
229      * @param timeout the timeout in milliseconds
230      *
231      * @see HttpConnectionManager#getConnection(HostConfiguration, long)
232      */

233     public synchronized void setHttpConnectionFactoryTimeout(long timeout) {
234         this.httpConnectionTimeout = timeout;
235     }
236
237     /**
238      * Sets the timeout until a connection is etablished. A timeout value of
239      * zero means the timeout is not used. The default value is zero.
240      *
241      * @param newTimeoutInMilliseconds Timeout in milliseconds.
242      *
243      * @see HttpConnection#setConnectionTimeout(int)
244      */

245     public synchronized void setConnectionTimeout(int newTimeoutInMilliseconds) {
246        this.connectionTimeout = newTimeoutInMilliseconds;
247     }
248
249     // --------------------------------------------------------- Public Methods
250

251     /**
252      * Sets the host, port and default protocol (http) to be used when executing a
253      * method.
254      *
255      * @param host the host to connect to
256      * @param port the port to connect to
257      *
258      * @see #getHostConfiguration()
259      *
260      * @deprecated use {@link HostConfiguration}
261      */

262     public void startSession(String JavaDoc host, int port) {
263         LOG.trace("enter HttpClient.startSession(String, int)");
264         startSession(host, port, false);
265     }
266
267     /**
268      * Sets the host, port and protocol to be used when executing a method.
269      *
270      * @param host the host to connect to
271      * @param port the port to connect to
272      * @param https when <code>true</code>, create an HTTPS session
273      *
274      * @see #getHostConfiguration()
275      *
276      * @deprecated use {@link HostConfiguration}
277      */

278     public void startSession(String JavaDoc host, int port, boolean https) {
279         LOG.trace("enter HttpClient.startSession(String, int, boolean)");
280
281         if (LOG.isDebugEnabled()) {
282             LOG.debug("HttpClient.startSession(String,int,boolean): Host:"
283                 + host + " Port:" + port + " HTTPS:" + https);
284         }
285         
286         this.hostConfiguration.setHost(host, port, https ? "https" : "http");
287     }
288
289     /**
290      * Sets the host, port, default protocol (http) and credentials to be used when
291      * executing a method.
292      *
293      * @param host the host to connect to
294      * @param port the port to connect to
295      * @param creds the default credentials to use
296      *
297      * @see #getHostConfiguration()
298      * @see #getState()
299      * @see #startSession(String, int, Credentials, boolean)
300      *
301      * @deprecated use {@link HostConfiguration} and {@link HttpState}
302      */

303     public void startSession(String JavaDoc host, int port, Credentials creds) {
304         LOG.trace("enter HttpClient.startSession(String, int, Credentials)");
305         startSession(host, port, creds, false);
306     }
307
308     /**
309      * Sets the host, port, protocol and credentials to be used when executing a
310      * method.
311      *
312      * @param host the host to connect to
313      * @param port the port to connect to
314      * @param creds the default credentials to use
315      * @param https when <code>true</code>, create an HTTPS session
316      *
317      * @see #getHostConfiguration()
318      * @see #getState()
319      *
320      * @deprecated use {@link HostConfiguration} and {@link HttpState}
321      */

322     public void startSession(String JavaDoc host, int port, Credentials creds, boolean https) {
323         LOG.trace("enter HttpClient.startSession(String, int, Credentials, boolean)");
324
325         if (LOG.isDebugEnabled()) {
326             LOG.debug(
327                 "Starting HttpClient session"
328                 + " Host:" + host
329                 + " Port:" + port + " Credentials:" + creds
330                 + " HTTPS:" + https);
331         }
332         getState().setCredentials(null, creds);
333         this.hostConfiguration.setHost(
334             host,
335             port,
336             https ? "https" : "http"
337         );
338     }
339
340     /**
341      * Sets the host, port, protocol and credentials to be used when executing a
342      * method using the server specified by the scheme, userinfo, host and port
343      * of the given <i>uri</i>.
344      * <p>
345      * Note that the path component is not utilized.
346      * <p>
347      * @param uri an <code>HttpURL</code> or <code>HttpsURL</code> instance; the
348      * {@link URI URI} from which the scheme, userinfo, host and port of the
349      * session are determined
350      *
351      * @throws IllegalStateException not enough information to process
352      * @throws URIException If the URI is bad.
353      *
354      * @see #getHostConfiguration()
355      *
356      * @deprecated use {@link HostConfiguration}
357      */

358     public void startSession(URI uri)
359         throws URIException, IllegalStateException JavaDoc {
360             
361         LOG.trace("enter HttpClient.startSession(URI)");
362
363         String JavaDoc scheme = uri.getScheme();
364         if (scheme == null) { // it may a URI instance or abs_path
365
LOG.error("no scheme to start a session");
366             throw new IllegalStateException JavaDoc("no scheme to start a session");
367         }
368
369         Protocol protocol = Protocol.getProtocol(scheme);
370
371         String JavaDoc userinfo = uri.getUserinfo();
372         if (userinfo != null) {
373             getState().setCredentials(null,
374                     new UsernamePasswordCredentials(userinfo));
375         }
376         String JavaDoc host = uri.getHost();
377         if (host == null || host.length() == 0) {
378             LOG.error("no host to start a session");
379             throw new IllegalStateException JavaDoc("no host to start a session");
380         }
381         int port = uri.getPort();
382         if (port == -1) { // neither HttpURL or HttpsURL instance
383
LOG.error("HttpURL or HttpsURL instance required");
384             throw new IllegalStateException JavaDoc
385                 ("HttpURL or HttpsURL instance required");
386         }
387         this.hostConfiguration.setHost(host, null, port, protocol);
388     }
389
390     /**
391      * Sets the host, port and protocol to be used when executing a method.
392      * <p>
393      * Note that everything but the protocol, host and port of the
394      * given <i>url</i> is ignored.
395      * </p>
396      * @param url the {@link URL URL} from which the protocol, host, and port of
397      * the session are determined
398      *
399      * @exception IllegalArgumentException if the protocol is not http or https
400      *
401      * @see #getHostConfiguration()
402      *
403      * @deprecated use {@link HostConfiguration}
404      */

405     public void startSession(URL JavaDoc url) throws IllegalArgumentException JavaDoc {
406         LOG.trace("enter HttpClient.startSession(String, int, Credentials, boolean)");
407
408         int port = url.getPort();
409         Protocol protocol = Protocol.getProtocol(url.getProtocol());
410
411         hostConfiguration.setHost(url.getHost(), null, port, protocol);
412     }
413
414     /**
415      * Sets the host, port, protocol and credentials to be used when executing a
416      * method.
417      * <p>
418      * Note that everything but the protocol, host and port of the
419      * given <i>url</i> is ignored.
420      * </p>
421      * @param url the {@link URL URL} from which the protocol, host, and port of
422      * the session are determined
423      * @param creds the default credentials to use
424      *
425      * @exception IllegalArgumentException if the protocol is not http or https
426      *
427      * @see #getHostConfiguration()
428      * @see #getState()
429      *
430      * @deprecated use {@link HostConfiguration} and {@link HttpState}
431      */

432     public void startSession(URL JavaDoc url, Credentials creds)
433         throws IllegalArgumentException JavaDoc {
434             
435         LOG.trace("enter HttpClient.startSession(URL, Credentials)");
436         getState().setCredentials(null, creds);
437         startSession(url);
438     }
439
440     /**
441      * Sets the host, port, protocol(http) and proxy to be used when executing a
442      * method.
443      *
444      * @param host the host to connect to
445      * @param port the port to connect to
446      * @param proxyhost the proxy host to connect via
447      * @param proxyport the proxy port to connect via
448      *
449      * @see #getHostConfiguration()
450      *
451      * @deprecated use {@link HostConfiguration}
452      */

453     public void startSession(String JavaDoc host, int port, String JavaDoc proxyhost, int proxyport) {
454         LOG.trace("enter HttpClient.startSession(String, int, String, int)");
455         startSession(host, port, proxyhost, proxyport, false);
456     }
457
458     /**
459      * Sets the host, port, protocol and proxy to be used when executing a
460      * method.
461      *
462      * @param host the host to connect to
463      * @param port the port to connect to
464      * @param proxyhost the proxy host to connect via
465      * @param proxyport the proxy port to connect via
466      * @param secure whether or not to connect using HTTPS
467      *
468      * @see #getHostConfiguration()
469      *
470      * @deprecated use {@link HostConfiguration}
471      */

472     public void startSession(String JavaDoc host, int port,
473         String JavaDoc proxyhost, int proxyport, boolean secure) {
474             
475         LOG.trace("enter HttpClient.startSession("
476             + "String, int, String, int, boolean)");
477         this.hostConfiguration.setHost (host, port, secure ? "https" : "http");
478         this.hostConfiguration.setProxy(proxyhost, proxyport);
479     }
480
481     /**
482      * Executes the given {@link HttpMethod HTTP method}.
483      *
484      * @param method the {@link HttpMethod HTTP method} to execute.
485      * @return the method's response code
486      *
487      * @throws IOException If an I/O (transport) error occurs. Some transport exceptions
488      * can be recovered from.
489      * @throws HttpException If a protocol exception occurs. Usually protocol exceptions
490      * cannot be recovered from.
491      */

492     public int executeMethod(HttpMethod method)
493         throws IOException JavaDoc, HttpException {
494             
495         LOG.trace("enter HttpClient.executeMethod(HttpMethod)");
496         // execute this method and use its host configuration, if it has one
497
return executeMethod(
498             method.getHostConfiguration() != null
499             ? method.getHostConfiguration()
500             : getHostConfiguration(),
501             method,
502             null
503         );
504         
505     }
506
507     /**
508     * Executes the given {@link HttpMethod HTTP method} using custom
509     * {@link HostConfiguration host configuration}.
510     *
511     * @param hostConfiguration The {@link HostConfiguration host configuration} to use.
512     * @param method the {@link HttpMethod HTTP method} to execute.
513     * @return the method's response code
514     *
515     * @throws IOException If an I/O (transport) error occurs. Some transport exceptions
516     * can be recovered from.
517     * @throws HttpException If a protocol exception occurs. Usually protocol exceptions
518     * cannot be recovered from.
519     * @since 2.0
520     */

521     public int executeMethod(HostConfiguration hostConfiguration, HttpMethod method)
522         throws IOException JavaDoc, HttpException {
523     
524         LOG.trace("enter HttpClient.executeMethod(HostConfiguration,HttpMethod)");
525     
526         return executeMethod(hostConfiguration, method, null);
527     }
528     
529
530     
531     /**
532      * Executes the given {@link HttpMethod HTTP method} using the given custom
533      * {@link HostConfiguration host configuration} with the given custom
534      * {@link HttpState HTTP state}.
535      *
536      * @param hostConfiguration The {@link HostConfiguration host configuration} to use.
537      * @param method the {@link HttpMethod HTTP method} to execute.
538      * @param state the {@link HttpState HTTP state} to use when executing the method.
539      * If <code>null</code>, the state returned by {@link #getState} will be used instead.
540      *
541      * @return the method's response code
542      *
543      * @throws IOException If an I/O (transport) error occurs. Some transport exceptions
544      * can be recovered from.
545      * @throws HttpException If a protocol exception occurs. Usually protocol exceptions
546      * cannot be recovered from.
547      * @since 2.0
548      */

549     public int executeMethod(HostConfiguration hostConfiguration,
550         HttpMethod method, HttpState state)
551         throws IOException JavaDoc, HttpException {
552             
553         LOG.trace("enter HttpClient.executeMethod(HostConfiguration,HttpMethod,HttpState)");
554
555         if (method == null) {
556             throw new IllegalArgumentException JavaDoc("HttpMethod parameter may not be null");
557         }
558
559         int soTimeout = 0;
560         boolean strictMode = false;
561         int connectionTimeout = 0;
562         long httpConnectionTimeout = 0;
563         HostConfiguration defaultHostConfiguration = null;
564
565         /* access all synchronized data in a single block, this will keeps us
566          * from accessing data asynchronously as well having to regain the lock
567          * for each item.
568          */

569         synchronized (this) {
570             soTimeout = this.timeoutInMilliseconds;
571             strictMode = this.strictMode;
572             connectionTimeout = this.connectionTimeout;
573             httpConnectionTimeout = this.httpConnectionTimeout;
574             if (state == null) {
575                 state = getState();
576             }
577             defaultHostConfiguration = getHostConfiguration();
578         }
579
580         HostConfiguration methodConfiguration
581             = new HostConfiguration(hostConfiguration);
582         
583         if (hostConfiguration != defaultHostConfiguration) {
584             // we may need to apply some defaults
585
if (!methodConfiguration.isHostSet()) {
586                 methodConfiguration.setHost(
587                     defaultHostConfiguration.getHost(),
588                     defaultHostConfiguration.getVirtualHost(),
589                     defaultHostConfiguration.getPort(),
590                     defaultHostConfiguration.getProtocol()
591                 );
592             }
593             if (!methodConfiguration.isProxySet()
594                 && defaultHostConfiguration.isProxySet()) {
595                     
596                 methodConfiguration.setProxy(
597                     defaultHostConfiguration.getProxyHost(),
598                     defaultHostConfiguration.getProxyPort()
599                 );
600             }
601             if (methodConfiguration.getLocalAddress() == null
602                 && defaultHostConfiguration.getLocalAddress() != null) {
603                     
604                 methodConfiguration.setLocalAddress(defaultHostConfiguration.getLocalAddress());
605             }
606         }
607         
608         HttpConnectionManager connmanager = this.httpConnectionManager;
609         if (state.getHttpConnectionManager() != null) {
610             connmanager = state.getHttpConnectionManager();
611         }
612
613         HttpConnection connection = connmanager.getConnection(
614             methodConfiguration,
615             httpConnectionTimeout
616         );
617
618         try {
619             // Catch all possible exceptions to make sure to release the
620
// connection, as although the user may call
621
// Method->releaseConnection(), the method doesn't know about the
622
// connection until HttpMethod.execute() is called.
623

624             method.setStrictMode(strictMode);
625             
626             if (!connection.isOpen()) {
627                 connection.setConnectionTimeout(connectionTimeout);
628                 connection.open();
629                 if (connection.isProxied() && connection.isSecure()) {
630                     method = new ConnectMethod(method);
631                 }
632             }
633             connection.setSoTimeout(soTimeout);
634             
635         } catch (IOException JavaDoc e) {
636             connection.releaseConnection();
637             throw e;
638         } catch (RuntimeException JavaDoc e) {
639             connection.releaseConnection();
640             throw e;
641         }
642         
643         return method.execute(state, connection);
644     }
645
646     /**
647      * @deprecated this method has no effect. {@link HttpMethod#releaseConnection()}
648      * should be used to release resources after a HttpMethod has been executed.
649      *
650      * @see HttpMethod#releaseConnection()
651      */

652     public void endSession() throws IOException JavaDoc {
653     }
654
655     /**
656       * Returns the default host.
657       *
658       * @return The default host.
659       *
660       * @deprecated use #getHostConfiguration()
661       */

662      public String JavaDoc getHost() {
663          return hostConfiguration.getHost();
664      }
665
666      /**
667       * Returns the default port.
668       *
669       * @return The default port.
670       *
671       * @deprecated use #getHostConfiguration()
672       */

673      public int getPort() {
674          return hostConfiguration.getPort();
675      }
676      
677     /**
678      * Returns the {@link HostConfiguration host configuration} associated with the
679      * HttpClient.
680      *
681      * @return {@link HostConfiguration host configuration}
682      *
683      * @since 2.0
684      */

685     public synchronized HostConfiguration getHostConfiguration() {
686         return hostConfiguration;
687     }
688
689     /**
690      * Assigns the {@link HostConfiguration host configuration} to use with the
691      * HttpClient.
692      *
693      * @param hostConfiguration The {@link HostConfiguration host configuration} to set
694      *
695      * @since 2.0
696      */

697     public synchronized void setHostConfiguration(HostConfiguration hostConfiguration) {
698         this.hostConfiguration = hostConfiguration;
699     }
700
701     /**
702      * Returns the {@link HttpConnectionManager HTTP connection manager} associated
703      * with the HttpClient.
704      *
705      * @return {@link HttpConnectionManager HTTP connection manager}
706      *
707      * @since 2.0
708      */

709     public synchronized HttpConnectionManager getHttpConnectionManager() {
710         return httpConnectionManager;
711     }
712
713     /**
714      * Assigns the {@link HttpConnectionManager HTTP connection manager} to use with
715      * the HttpClient.
716      *
717      * @param httpConnectionManager The {@link HttpConnectionManager HTTP connection manager}
718      * to set
719      *
720      * @since 2.0
721      */

722     public synchronized void setHttpConnectionManager(
723         HttpConnectionManager httpConnectionManager
724     ) {
725         this.httpConnectionManager = httpConnectionManager;
726     }
727
728 }
729
Popular Tags