View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpClient.java,v 1.76 2003/05/12 02:42:42 mbecke Exp $ 3 * $Revision: 1.76 $ 4 * $Date: 2003/05/12 02:42:42 $ 5 * 6 * ==================================================================== 7 * 8 * The Apache Software License, Version 1.1 9 * 10 * Copyright (c) 1999-2003 The Apache Software Foundation. All rights 11 * reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in 22 * the documentation and/or other materials provided with the 23 * distribution. 24 * 25 * 3. The end-user documentation included with the redistribution, if 26 * any, must include the following acknowlegement: 27 * "This product includes software developed by the 28 * Apache Software Foundation (http://www.apache.org/)." 29 * Alternately, this acknowlegement may appear in the software itself, 30 * if and wherever such third-party acknowlegements normally appear. 31 * 32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 33 * Foundation" must not be used to endorse or promote products derived 34 * from this software without prior written permission. For written 35 * permission, please contact apache@apache.org. 36 * 37 * 5. Products derived from this software may not be called "Apache" 38 * nor may "Apache" appear in their names without prior written 39 * permission of the Apache Group. 40 * 41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 * SUCH DAMAGE. 53 * ==================================================================== 54 * 55 * This software consists of voluntary contributions made by many 56 * individuals on behalf of the Apache Software Foundation. For more 57 * information on the Apache Software Foundation, please see 58 * <http://www.apache.org/>;. 59 * 60 * [Additional notices, if required by prior licensing conditions] 61 * 62 */ 63 64 package org.apache.commons.httpclient; 65 66 import java.io.IOException; 67 import java.net.URL; 68 import java.security.Security; 69 import java.security.Provider; 70 71 import org.apache.commons.httpclient.protocol.Protocol; 72 import org.apache.commons.logging.Log; 73 import org.apache.commons.logging.LogFactory; 74 75 76 /*** 77 * <p> 78 * An HTTP "user-agent", containing an {@link HttpState} and 79 * one or more {@link HttpConnection}s, to which 80 * {@link HttpMethod}s can be applied. 81 * </p> 82 * @author <a href="mailto:remm@apache.org">Remy Maucherat</a> 83 * @author <a href="mailto:rwaldhoff@apache.org">Rodney Waldhoff</a> 84 * @author Sean C. Sullivan 85 * @author <a href="mailto:dion@apache.org">dIon Gillard</a> 86 * @author Ortwin Gl�ck 87 * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a> 88 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> 89 * @author Sam Maloney 90 * @author Laura Werner 91 * 92 * @version $Revision: 1.76 $ $Date: 2003/05/12 02:42:42 $ 93 */ 94 public class HttpClient { 95 96 97 // -------------------------------------------------------------- Constants 98 99 /*** Log object for this class. */ 100 private static final Log LOG = LogFactory.getLog(HttpClient.class); 101 102 static { 103 if (LOG.isDebugEnabled()) { 104 LOG.debug("Java version: " + System.getProperty("java.version")); 105 LOG.debug("Java vendor: " + System.getProperty("java.vendor")); 106 LOG.debug("Java class path: " + System.getProperty("java.class.path")); 107 LOG.debug("Operating system name: " + System.getProperty("os.name")); 108 LOG.debug("Operating system architecture: " + System.getProperty("os.arch")); 109 LOG.debug("Operating system version: " + System.getProperty("os.version")); 110 111 Provider[] providers = Security.getProviders(); 112 for (int i = 0; i < providers.length; i++) { 113 Provider provider = providers[i]; 114 LOG.debug(provider.getName() + " " + provider.getVersion() 115 + ": " + provider.getInfo()); 116 } 117 118 } 119 } 120 // ----------------------------------------------------------- Constructors 121 122 /*** 123 * Creates an HttpClient using <code>SimpleHttpConnectionManager</code>. 124 * 125 * @see SimpleHttpConnectionManager 126 */ 127 public HttpClient() { 128 this(new SimpleHttpConnectionManager()); 129 } 130 131 /*** 132 * Creates an HttpClient with a user specified connection manager. 133 * @param httpConnectionManager The connection manager to use. 134 * 135 * @since 2.0 136 */ 137 public HttpClient(HttpConnectionManager httpConnectionManager) { 138 139 if (httpConnectionManager == null) { 140 throw new IllegalArgumentException("httpConnectionManager cannot be null"); 141 } 142 143 this.state = new HttpState(); 144 this.httpConnectionManager = httpConnectionManager; 145 146 this.hostConfiguration = new HostConfiguration(); 147 148 } 149 150 // ----------------------------------------------------- Instance Variables 151 152 /*** The current connection manager */ 153 private HttpConnectionManager httpConnectionManager; 154 155 /*** 156 * My {@link HttpState state}. 157 */ 158 private HttpState state; 159 160 /*** the timout when waiting for a connection from the connectionManager */ 161 private long httpConnectionTimeout = 0; 162 163 /*** The timeout in milliseconds*/ 164 private int timeoutInMilliseconds = 0; 165 166 /*** The connection timeout. */ 167 private int connectionTimeout = 0; 168 169 /*** The host configuration to use */ 170 private HostConfiguration hostConfiguration; 171 172 /*** True if strict mode is enabled. */ 173 private boolean strictMode = false; 174 175 // ------------------------------------------------------------- Properties 176 177 /*** 178 * Get my {@link HttpState state}. 179 * 180 * @see #setState(HttpState) 181 * @return the shared client state 182 */ 183 public synchronized HttpState getState() { 184 return state; 185 } 186 187 /*** 188 * Set my {@link HttpState state}. 189 * 190 * @see #getState() 191 * @param state the new state for the client 192 */ 193 public synchronized void setState(HttpState state) { 194 this.state = state; 195 } 196 197 /*** 198 * 199 * @param strictMode <code>true</code> if strict mode should be used 200 * 201 * @see #isStrictMode() 202 * 203 */ 204 public synchronized void setStrictMode(boolean strictMode) { 205 this.strictMode = strictMode; 206 } 207 208 /*** 209 * 210 * @return <code>true</code> if strict mode being used 211 * 212 * @see #setStrictMode(boolean) 213 * 214 */ 215 public synchronized boolean isStrictMode() { 216 return strictMode; 217 } 218 219 /*** 220 * Sets the SO_TIMEOUT which is the timeout for waiting for data. 221 * 222 * A timeout value of zero is interpreted as an infinite timeout. 223 * 224 * @param newTimeoutInMilliseconds Timeout in milliseconds 225 * 226 */ 227 public synchronized void setTimeout(int newTimeoutInMilliseconds) { 228 this.timeoutInMilliseconds = newTimeoutInMilliseconds; 229 } 230 231 /*** 232 * Sets the timeout used when retrieving an HttpConnection from the 233 * HttpConnectionManager. 234 * 235 * @param timeout the timeout in milliseconds 236 * 237 * @see HttpConnectionManager#getConnection(HostConfiguration, long) 238 */ 239 public synchronized void setHttpConnectionFactoryTimeout(long timeout) { 240 this.httpConnectionTimeout = timeout; 241 } 242 243 /*** 244 * Sets the timeout until a connection is etablished. A value of 0 means 245 * the timeout is not used. The default value is 0. 246 * @see HttpConnection#setConnectionTimeout(int) 247 * @param newTimeoutInMilliseconds Timeout in milliseconds. 248 */ 249 public synchronized void setConnectionTimeout(int newTimeoutInMilliseconds) { 250 this.connectionTimeout = newTimeoutInMilliseconds; 251 } 252 253 // --------------------------------------------------------- Public Methods 254 255 /*** 256 * @deprecated use hostConfiguration 257 * 258 * Sets the host, port and protocol(http) to be used when executing a 259 * method. 260 * 261 * @param host the host to connect to 262 * @param port the port to connect to 263 * 264 * @see #getHostConfiguration() 265 */ 266 public void startSession(String host, int port) { 267 LOG.trace("enter HttpClient.startSession(String, int)"); 268 startSession(host, port, false); 269 } 270 271 /*** 272 * @deprecated use hostConfiguration 273 * 274 * Sets the host, port and protocol to be used when executing a method. 275 * 276 * @param host the host to connect to 277 * @param port the port to connect to 278 * @param https when <code>true</code>, create an HTTPS session 279 * 280 * @see #getHostConfiguration() 281 */ 282 public void startSession(String host, int port, boolean https) { 283 LOG.trace("enter HttpClient.startSession(String, int, boolean)"); 284 285 if (LOG.isDebugEnabled()) { 286 LOG.debug("HttpClient.startSession(String,int,boolean): Host:" 287 + host + " Port:" + port + " HTTPS:" + https); 288 } 289 290 this.hostConfiguration.setHost(host, port, https ? "https" : "http"); 291 } 292 293 /*** 294 * @deprecated use hostConfiguration and httpState 295 * 296 * Sets the host, port, protocol(http) and credentials to be used when 297 * executing a method. 298 * 299 * @param host the host to connect to 300 * @param port the port to connect to 301 * @param creds the default credentials to use 302 * 303 * @see #getHostConfiguration() 304 * @see #getState() 305 * @see #startSession(String, int, Credentials, boolean) 306 */ 307 public void startSession(String host, int port, Credentials creds) { 308 LOG.trace("enter HttpClient.startSession(String, int, Credentials)"); 309 startSession(host, port, creds, false); 310 } 311 312 /*** 313 * @deprecated use hostConfiguration and httpState 314 * 315 * Sets the host, port, protocol and credentials to be used when executing a 316 * method. 317 * 318 * @param host the host to connect to 319 * @param port the port to connect to 320 * @param creds the default credentials to use 321 * @param https when <code>true</code>, create an HTTPS session 322 * 323 * @see #getHostConfiguration() 324 * @see #getState() 325 */ 326 public void startSession(String host, int port, Credentials creds, boolean https) { 327 LOG.trace("enter HttpClient.startSession(String, int, Credentials, boolean)"); 328 329 if (LOG.isDebugEnabled()) { 330 LOG.debug( 331 "Starting HttpClient session" 332 + " Host:" + host 333 + " Port:" + port + " Credentials:" + creds 334 + " HTTPS:" + https); 335 } 336 getState().setCredentials(null, creds); 337 this.hostConfiguration.setHost( 338 host, 339 port, 340 https ? "https" : "http" 341 ); 342 } 343 344 /*** 345 * @deprecated use hostConfiguration and httpState 346 * 347 * Sets the host, port, protocol and credentials to be used when executing a 348 * method using the server specified by the scheme, userinfo, host and port 349 * of the given <i>uri</i>. 350 * <p> 351 * Note that the path component is not utilized. 352 * <p> 353 * @param uri an <code>HttpURL</code> or <code>HttpsURL</code> instance; the 354 * {@link URI URI} from which the scheme, userinfo, host and port of the 355 * session are determined 356 * 357 * @throws IllegalStateException not enough information to process 358 * @throws URIException If the URI is bad. 359 * 360 * @see #getHostConfiguration() 361 * @see #getState() 362 */ 363 public void startSession(URI uri) 364 throws URIException, IllegalStateException { 365 366 LOG.trace("enter HttpClient.startSession(URI)"); 367 368 String scheme = uri.getScheme(); 369 if (scheme == null) { // it may a URI instance or abs_path 370 LOG.error("no scheme to start a session"); 371 throw new IllegalStateException("no scheme to start a session"); 372 } 373 374 Protocol protocol = Protocol.getProtocol(scheme); 375 376 String userinfo = uri.getUserinfo(); 377 if (userinfo != null) { 378 getState().setCredentials(null, 379 new UsernamePasswordCredentials(userinfo)); 380 } 381 String host = uri.getHost(); 382 if (host == null || host.length() == 0) { 383 LOG.error("no host to start a session"); 384 throw new IllegalStateException("no host to start a session"); 385 } 386 int port = uri.getPort(); 387 if (port == -1) { // neither HttpURL or HttpsURL instance 388 LOG.error("HttpURL or HttpsURL instance required"); 389 throw new IllegalStateException 390 ("HttpURL or HttpsURL instance required"); 391 } 392 this.hostConfiguration.setHost(host, null, port, protocol); 393 } 394 395 /*** 396 * @deprecated use hostConfiguration 397 * 398 * Sets the host, port and protocol to be used when executing a method. 399 * <p> 400 * Note that everything but the protocol, host and port of the 401 * given <i>url</i> is ignored. 402 * </p> 403 * @param url the {@link URL URL} from which the protocol, host, and port of 404 * the session are determined 405 * 406 * @exception IllegalArgumentException if the protocol is not http or https 407 * 408 * @see #getHostConfiguration() 409 */ 410 public void startSession(URL url) throws IllegalArgumentException { 411 LOG.trace("enter HttpClient.startSession(String, int, Credentials, boolean)"); 412 413 int port = url.getPort(); 414 Protocol protocol = Protocol.getProtocol(url.getProtocol()); 415 416 hostConfiguration.setHost(url.getHost(), null, port, protocol); 417 } 418 419 /*** 420 * @deprecated use hostConfiguration and httpState 421 * 422 * Sets the host, port, protocol and credentials to be used when executing a 423 * method. 424 * <p> 425 * Note that everything but the protocol, host and port of the 426 * given <i>url</i> is ignored. 427 * </p> 428 * @param url the {@link URL URL} from which the protocol, host, and port of 429 * the session are determined 430 * @param creds the default credentials to use 431 * 432 * @exception IllegalArgumentException if the protocol is not http or https 433 * 434 * @see #getHostConfiguration() 435 * @see #getState() 436 */ 437 public void startSession(URL url, Credentials creds) 438 throws IllegalArgumentException { 439 440 LOG.trace("enter HttpClient.startSession(URL, Credentials)"); 441 getState().setCredentials(null, creds); 442 startSession(url); 443 } 444 445 /*** 446 * @deprecated use hostConfiguration 447 * 448 * Sets the host, port, protocol(http) and proxy to be used when executing a 449 * method. 450 * 451 * @param host the host to connect to 452 * @param port the port to connect to 453 * @param proxyhost the proxy host to connect via 454 * @param proxyport the proxy port to connect via 455 * 456 * @see #getHostConfiguration() 457 */ 458 public void startSession(String host, int port, String proxyhost, int proxyport) { 459 LOG.trace("enter HttpClient.startSession(String, int, String, int)"); 460 startSession(host, port, proxyhost, proxyport, false); 461 } 462 463 /*** 464 * @deprecated use hostConfiguration 465 * 466 * Sets the host, port, protocol and proxy to be used when executing a 467 * method. 468 * 469 * @param host the host to connect to 470 * @param port the port to connect to 471 * @param proxyhost the proxy host to connect via 472 * @param proxyport the proxy port to connect via 473 * @param secure whether or not to connect using HTTPS 474 * 475 * @see #getHostConfiguration() 476 */ 477 public void startSession(String host, int port, 478 String proxyhost, int proxyport, boolean secure) { 479 480 LOG.trace("enter HttpClient.startSession(" 481 + "String, int, String, int, boolean)"); 482 this.hostConfiguration.setHost (host, port, secure ? "https" : "http"); 483 this.hostConfiguration.setProxy(proxyhost, proxyport); 484 } 485 486 /*** 487 * Executes the given method. 488 * 489 * @param method the {@link HttpMethod} to execute. 490 * @return the method's response code 491 * 492 * @throws IOException if an I/O error occurs 493 * @throws HttpException if a protocol exception occurs 494 */ 495 public int executeMethod(HttpMethod method) 496 throws IOException, HttpException { 497 498 LOG.trace("enter HttpClient.executeMethod(HttpMethod)"); 499 // execute this method and use its host configuration, if it has one 500 return executeMethod( 501 method.getHostConfiguration() != null 502 ? method.getHostConfiguration() 503 : getHostConfiguration(), 504 method, 505 null 506 ); 507 508 } 509 510 /*** 511 * Executes the given method. 512 * 513 * @param hostConfiguration The configuration to use. 514 * @param method the {@link HttpMethod} to execute. 515 * @return the method's response code 516 * 517 * @throws IOException if an I/O error occurs 518 * @throws HttpException if a protocol exception occurs 519 * @since 2.0 520 */ 521 public int executeMethod(HostConfiguration hostConfiguration, HttpMethod method) 522 throws IOException, 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 method. 533 * 534 * @param hostConfiguration The configuration to use. 535 * @param method the {@link HttpMethod} to execute. 536 * @param state the {@link HttpState} to use when executing the method. 537 * If <code>null</code>, the state returned by {@link #getState} will be used instead. 538 * 539 * @return the method's response code 540 * 541 * @throws IOException if an I/O error occurs 542 * @throws HttpException if a protocol exception occurs 543 * @since 2.0 544 */ 545 public int executeMethod(HostConfiguration hostConfiguration, 546 HttpMethod method, HttpState state) 547 throws IOException, HttpException { 548 549 LOG.trace("enter HttpClient.executeMethod(HostConfiguration,HttpMethod,HttpState)"); 550 551 if (method == null) { 552 throw new IllegalArgumentException("HttpMethod parameter may not be null"); 553 } 554 555 int soTimeout = 0; 556 boolean strictMode = false; 557 int connectionTimeout = 0; 558 long httpConnectionTimeout = 0; 559 HostConfiguration defaultHostConfiguration = null; 560 561 /* access all synchronized data in a single block, this will keeps us 562 * from accessing data asynchronously as well having to regain the lock 563 * for each item. 564 */ 565 synchronized (this) { 566 soTimeout = this.timeoutInMilliseconds; 567 strictMode = this.strictMode; 568 connectionTimeout = this.connectionTimeout; 569 httpConnectionTimeout = this.httpConnectionTimeout; 570 if (state == null) { 571 state = getState(); 572 } 573 defaultHostConfiguration = getHostConfiguration(); 574 } 575 576 HostConfiguration methodConfiguration 577 = new HostConfiguration(hostConfiguration); 578 579 if (hostConfiguration != defaultHostConfiguration) { 580 // we may need to apply some defaults 581 if (!methodConfiguration.isHostSet()) { 582 methodConfiguration.setHost( 583 defaultHostConfiguration.getHost(), 584 defaultHostConfiguration.getVirtualHost(), 585 defaultHostConfiguration.getPort(), 586 defaultHostConfiguration.getProtocol() 587 ); 588 } 589 if (!methodConfiguration.isProxySet() 590 && defaultHostConfiguration.isProxySet()) { 591 592 methodConfiguration.setProxy( 593 defaultHostConfiguration.getProxyHost(), 594 defaultHostConfiguration.getProxyPort() 595 ); 596 } 597 if (methodConfiguration.getLocalAddress() == null 598 && defaultHostConfiguration.getLocalAddress() != null) { 599 600 methodConfiguration.setLocalAddress(defaultHostConfiguration.getLocalAddress()); 601 } 602 } 603 604 HttpConnectionManager connmanager = this.httpConnectionManager; 605 if (state.getHttpConnectionManager() != null) { 606 connmanager = state.getHttpConnectionManager(); 607 } 608 609 HttpConnection connection = connmanager.getConnection( 610 methodConfiguration, 611 httpConnectionTimeout 612 ); 613 614 try { 615 // Catch all possible exceptions to make sure to release the 616 // connection, as although the user may call 617 // Method->releaseConnection(), the method doesn't know about the 618 // connection until HttpMethod.execute() is called. 619 620 method.setStrictMode(strictMode); 621 622 if (!connection.isOpen()) { 623 connection.setSoTimeout(soTimeout); 624 connection.setConnectionTimeout(connectionTimeout); 625 connection.open(); 626 if (connection.isProxied() && connection.isSecure()) { 627 method = new ConnectMethod(method); 628 } 629 } 630 } catch (IOException e) { 631 connection.releaseConnection(); 632 throw e; 633 } catch (RuntimeException e) { 634 connection.releaseConnection(); 635 throw e; 636 } 637 638 return method.execute(state, connection); 639 } 640 641 /*** 642 * @deprecated this method has no effect. HttpMethod.releaseConnection() 643 * should be used to release resources after a HttpMethod has been executed. 644 * 645 * @see HttpMethod#releaseConnection() 646 */ 647 public void endSession() throws IOException { 648 } 649 650 /*** 651 * Return the host that the client is accessing. 652 * 653 * @return The host that the client is accessing, or <code>null</code> if 654 * the session has not been started via startSession. 655 */ 656 public String getHost() { 657 return hostConfiguration.getHost(); 658 } 659 660 /*** 661 * Return the port that the client is accessing. 662 * 663 * @return The port that the client is accessing, or -1 if the session 664 * has not been started via startSession(). 665 */ 666 public int getPort() { 667 return hostConfiguration.getPort(); 668 } 669 670 /*** 671 * Returns the hostConfiguration. 672 * @return HostConfiguration 673 * 674 * @since 2.0 675 */ 676 public synchronized HostConfiguration getHostConfiguration() { 677 return hostConfiguration; 678 } 679 680 /*** 681 * Sets the hostConfiguration. 682 * @param hostConfiguration The hostConfiguration to set 683 * 684 * @since 2.0 685 */ 686 public synchronized void setHostConfiguration(HostConfiguration hostConfiguration) { 687 this.hostConfiguration = hostConfiguration; 688 } 689 690 /*** 691 * Returns the httpConnectionManager. 692 * @return HttpConnectionManager 693 * 694 * @since 2.0 695 */ 696 public synchronized HttpConnectionManager getHttpConnectionManager() { 697 return httpConnectionManager; 698 } 699 700 /*** 701 * Sets the httpConnectionManager. 702 * @param httpConnectionManager The httpConnectionManager to set 703 * 704 * @since 2.0 705 */ 706 public synchronized void setHttpConnectionManager( 707 HttpConnectionManager httpConnectionManager 708 ) { 709 this.httpConnectionManager = httpConnectionManager; 710 } 711 712 }

This page was automatically generated by Maven