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
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
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
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
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
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
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
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
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 }