1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
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
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
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
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
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
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
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 }