View Javadoc

1   /*
2    * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HostConfiguration.java,v 1.19 2004/07/17 18:58:33 mbecke Exp $
3    * $Revision: 1.19 $
4    * $Date: 2004/07/17 18:58:33 $
5    *
6    * ====================================================================
7    *
8    *  Copyright 2002-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 org.apache.commons.httpclient.params.HostParams;
33  import org.apache.commons.httpclient.protocol.Protocol;
34  
35  import java.net.InetAddress;
36  
37  /***
38   * Holds all of the variables needed to describe an HTTP connection to a host.  This includes 
39   * remote host, port and protocol, proxy host and port, local address, and virtual host.
40   * 
41   * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
42   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
43   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
44   * @author Laura Werner
45   * 
46   * @since 2.0 
47   */
48  public class HostConfiguration implements Cloneable {
49  
50      /***
51       * A value to represent any host configuration, instead of using something like
52       * <code>null</code>. This value should be treated as immutable and only used in 
53       * lookups and other such places to represent "any" host config.
54       */
55      public static final HostConfiguration ANY_HOST_CONFIGURATION = new HostConfiguration();
56  
57      /*** The host to use. */
58      private String host;
59  
60      /*** The virtual host to use. */
61      private String virtualHost;
62  
63      /*** The port to use. */
64      private int port;
65  
66      /*** The protocol */
67      private Protocol protocol;
68  
69      /*** True if a host has been set */
70      private boolean hostSet;
71  
72      /*** The host name of the proxy server */
73      private String proxyHost;
74  
75      /*** The port number of the proxy server */
76      private int proxyPort;
77  
78      /*** True if a proxy server has been set */
79      private boolean proxySet;
80      
81      /*** The local address to use when creating the socket, or null to use the default */
82      private InetAddress localAddress;
83  
84      /*** Parameters specific to this host */
85      private HostParams params;
86  
87      /***
88       * Constructor for HostConfiguration.
89       */
90      public HostConfiguration() {
91          
92          this.host = null;
93          this.virtualHost = null;
94          this.port = -1;
95          this.protocol = null;
96          this.hostSet = false;
97          
98          this.proxyHost = null;
99          this.proxyPort = -1;
100         this.proxySet = false;
101         this.localAddress = null;
102         this.params = new HostParams();
103     }
104     
105     /***
106      * Copy constructor for HostConfiguration
107      * 
108      * @param hostConfiguration the hostConfiguration to copy
109      */
110     public HostConfiguration (HostConfiguration hostConfiguration) {
111         
112         // wrap all of the assignments in a synchronized block to avoid
113         // having to negotiate the monitor for each method call
114         synchronized (hostConfiguration) {            
115             this.host = hostConfiguration.getHost();
116             this.virtualHost = hostConfiguration.getVirtualHost();
117             this.port = hostConfiguration.getPort();
118             this.protocol = hostConfiguration.getProtocol();
119             this.hostSet = hostConfiguration.isHostSet();
120             
121             this.proxyHost = hostConfiguration.getProxyHost();
122             this.proxyPort = hostConfiguration.getProxyPort();
123             this.proxySet = hostConfiguration.isProxySet();
124             this.localAddress = hostConfiguration.getLocalAddress();
125             try {
126                 this.params = (HostParams)hostConfiguration.getParams().clone();
127             } catch (CloneNotSupportedException e) {
128                 this.params = new HostParams();
129             }
130         }
131         
132     }
133 
134     /***
135      * @see java.lang.Object#clone()
136      */
137     public Object clone() {
138         return new HostConfiguration(this);
139     }    
140     
141     /***
142      * @see java.lang.Object#toString()
143      */
144     public synchronized String toString() {
145         
146         boolean appendComma = false;
147         
148         StringBuffer b = new StringBuffer(50);        
149         b.append("HostConfiguration[");
150         
151         if (isHostSet()) {
152             appendComma = true;
153             b.append("host=").append(host);
154             b.append(", protocol=").append(protocol);
155             b.append(", port=").append(port);
156             if (virtualHost != null) {
157                 b.append(", virtualHost=").append(virtualHost);
158             }
159         }
160         if (isProxySet()) {
161             if (appendComma) {
162                 b.append(", ");
163             } else {
164                 appendComma = true;
165             }
166             b.append("proxyHost=").append(proxyHost);
167             b.append(", proxyPort=").append(proxyPort);
168         }
169         if (localAddress != null) {
170             if (appendComma) {
171                 b.append(", ");
172             } else {
173                 appendComma = true;
174             }
175             b.append("localAddress=").append(localAddress);
176         }
177         
178         b.append("]");
179         return b.toString();
180     }    
181     
182     /***
183      * Tests if the host configuration equals the configuration set on the
184      * connection. True only if the host, port, protocol, local address and virtual address
185      * are equal.  If no host configuration has been set false will be returned.
186      * 
187      * @param connection the connection to test against
188      * @return <code>true</code> if the connection's host information equals that of this
189      * configuration
190      * 
191      * @see #proxyEquals(HttpConnection)
192      * @see #isHostSet()
193      */
194     public synchronized boolean hostEquals(HttpConnection connection) {
195         
196         if (hostSet) {
197             if (!this.host.equalsIgnoreCase(connection.getHost())) {
198                 return false;
199             }
200             if (this.virtualHost != null) {
201                 if (!this.virtualHost.equalsIgnoreCase(connection.getVirtualHost())) {
202                     return false;
203                 }
204             } else {
205                 if (connection.getVirtualHost() != null) {
206                     return false; 
207                 }
208             }
209             if (this.port != connection.getPort()) {
210                 return false;
211             }
212             if (!this.protocol.equals(connection.getProtocol())) {
213                 return false;
214             }
215             if (this.localAddress != null) {
216                 if (!this.localAddress.equals(connection.getLocalAddress())) {
217                     return false;
218                 }
219             } else {
220                 if (connection.getLocalAddress() != null) {
221                     return false; 
222                 }
223             }
224             return true;
225         } else {
226             return false;   
227         }
228         
229     }
230 
231     /***
232      * Tests if the proxy configuration equals the configuration set on the
233      * connection. True only if the proxyHost and proxyPort are equal.
234      *
235      * @param connection the connection to test against
236      * @return <code>true</code> if the connection's proxy information equals that of this
237      * configuration
238      *
239      * @see #hostEquals(HttpConnection)
240      */
241     public synchronized boolean proxyEquals(HttpConnection connection) {
242         
243         if (proxyHost == null) {
244             return connection.getProxyHost() == null;   
245         } else {
246             return (
247                 proxyHost.equalsIgnoreCase(connection.getProxyHost())
248                 && proxyPort == connection.getProxyPort()
249             );
250         }
251     }    
252     
253     /***
254      * Returns true if the host is set.
255      * @return <code>true</code> if the host is set.
256      */
257     public synchronized boolean isHostSet() {
258         return hostSet;
259     }
260 
261     /***
262      * Sets the given host, port and protocol
263      * 
264      * @param host the host(IP or DNS name)
265      * @param port The port
266      * @param protocol The protocol.
267      */
268     public synchronized void setHost(String host, int port, String protocol) {
269         setHost(host, null, port, Protocol.getProtocol(protocol));
270     }
271     
272     /***
273      * Sets the given host, virtual host, port and protocol.
274      * 
275      * @param host the host(IP or DNS name)
276      * @param virtualHost the virtual host name or <code>null</code>
277      * @param port the host port or -1 to use protocol default
278      * @param protocol the protocol
279      */
280     public synchronized void setHost(String host, String virtualHost, int port, 
281         Protocol protocol) {
282             
283         if (host == null) {
284             throw new IllegalArgumentException("host must not be null");   
285         }
286         if (protocol == null) {
287             throw new IllegalArgumentException("protocol must not be null");   
288         }
289         
290         this.host = host;
291         this.virtualHost = virtualHost;
292         this.port = port == -1 ? protocol.getDefaultPort() : port;
293         this.protocol = protocol;
294         
295         this.hostSet = true;
296     }
297 
298     /***
299      * Sets the given host, port and protocol.
300      *   
301      * @param host the host(IP or DNS name)
302      * @param port The port
303      * @param protocol the protocol
304      */
305     public synchronized void setHost(String host, int port, Protocol protocol) {
306         setHost(host, null, port, protocol);
307     }
308 
309     /***
310      * Sets the given host and port.  Uses the default protocol "http".
311      * 
312      * @param host the host(IP or DNS name)
313      * @param port The port
314      */
315     public synchronized void setHost(String host, int port) {
316         setHost(host, null, port, Protocol.getProtocol("http"));
317     }
318     
319     /***
320      * Set the given host. Uses the default protocol("http") and its port.
321      * 
322      * @param host The host(IP or DNS name).
323      */
324     public synchronized void setHost(String host) {
325         Protocol defaultProtocol = Protocol.getProtocol("http"); 
326         setHost(host, null, defaultProtocol.getDefaultPort(), defaultProtocol);
327     }
328     
329     /***
330      * Sets the protocol, host and port from the given URI.
331      * @param uri the URI.
332      */
333     public synchronized void setHost(URI uri) {
334         try {
335             setHost(uri.getHost(), uri.getPort(), uri.getScheme());
336         } catch (URIException e) {
337             throw new IllegalArgumentException(e.toString());
338         }
339     }
340 
341     /***
342      * Return the host url.
343      * 
344      * @return The host url.
345      */
346     public synchronized String getHostURL() {
347         
348         if (!hostSet) {
349             throw new IllegalStateException("a default host must be set to "
350                 + "create a host URL" 
351             );   
352         }
353         
354         String url = protocol.getScheme() + "://" + host;
355         
356         if (port != -1 && port != protocol.getDefaultPort()) {
357             url += ":" + port;
358         }
359         
360         return url;
361     }
362 
363     /***
364      * Returns the host.
365      * 
366      * @return the host(IP or DNS name), or <code>null</code> if not set
367      * 
368      * @see #isHostSet()
369      */
370     public synchronized String getHost() {
371         return host;
372     }
373 
374     /***
375      * Returns the virtual host.
376      * 
377      * @return the virtual host name, or <code>null</code> if not set
378      */
379     public synchronized String getVirtualHost() {
380         return virtualHost;
381     }
382 
383     /***
384      * Returns the port.
385      * 
386      * @return the host port, or <code>-1</code> if not set
387      * 
388      * @see #isHostSet()
389      */
390     public synchronized int getPort() {
391         return port;
392     }
393 
394     /***
395      * Returns the protocol.
396      * @return The protocol.
397      */
398     public synchronized Protocol getProtocol() {
399         return protocol;
400     }
401 
402     /***
403      * Tests if the proxy host/port have been set.
404      * 
405      * @return <code>true</code> if a proxy server has been set.
406      * 
407      * @see #setProxy(String, int)
408      */    
409     public synchronized boolean isProxySet() {
410         return proxySet;   
411     }
412 
413     /***
414      * Set the proxy settings.
415      * @param proxyHost The proxy host
416      * @param proxyPort The proxy port
417      */
418     public synchronized void setProxy(String proxyHost, int proxyPort) {
419         
420         this.proxyHost = proxyHost;
421         this.proxyPort = proxyPort;
422         
423         this.proxySet = true;
424     }
425 
426     /***
427      * Returns the proxyHost.
428      * 
429      * @return the proxy host, or <code>null</code> if not set
430      * 
431      * @see #isProxySet()
432      */
433     public synchronized String getProxyHost() {
434         return proxyHost;
435     }
436 
437     /***
438      * Returns the proxyPort.
439      * 
440      * @return the proxy port, or <code>-1</code> if not set
441      * 
442      * @see #isProxySet()
443      */
444     public synchronized int getProxyPort() {
445         return proxyPort;
446     }
447 
448     /***
449      * Set the local address to be used when creating connections.
450      * If this is unset, the default address will be used.
451      * This is useful for specifying the interface to use on multi-homed or clustered systems.
452      * 
453      * @param localAddress the local address to use
454      */
455     public synchronized void setLocalAddress(InetAddress localAddress) {
456         this.localAddress = localAddress;
457     }
458 
459     /***
460      * Return the local address to be used when creating connections.
461      * If this is unset, the default address should be used.
462      * 
463      * @return the local address to be used when creating Sockets, or <code>null</code>
464      */
465     public synchronized InetAddress getLocalAddress() {
466         return this.localAddress;
467     }
468     
469     /***
470      * Returns {@link HostParams HTTP protocol parameters} associated with this host.
471      *
472      * @return HTTP parameters.
473      *
474      * @since 3.0
475      */
476     public HostParams getParams() {
477         return this.params;
478     }
479 
480     /***
481      * Assigns {@link HostParams HTTP protocol parameters} specific to this host.
482      * 
483      * @since 3.0
484      * 
485      * @see HostParams
486      */
487     public void setParams(final HostParams params) {
488         if (params == null) {
489             throw new IllegalArgumentException("Parameters may not be null");
490         }
491         this.params = params;
492     }
493 
494     /***
495      * @see java.lang.Object#equals(java.lang.Object)
496      */
497     public synchronized boolean equals(Object o) {
498         
499         if (o instanceof HostConfiguration) {
500             
501             // shortcut if we're comparing with ourselves
502             if (o == this) { 
503                 return true;
504             }
505             
506             HostConfiguration config = (HostConfiguration) o;
507             
508             if (hostSet) {
509                 if (!host.equalsIgnoreCase(config.getHost())) {
510                     return false;
511                 }
512                 if (virtualHost != null) {
513                     if (!virtualHost.equalsIgnoreCase(config.getVirtualHost())) {
514                         return false;
515                     }
516                 } else {
517                     if (config.getVirtualHost() != null) {
518                         return false;
519                     }
520                 }
521                 if (port != config.getPort()) {
522                     return false;
523                 }
524                 if (!protocol.equals(config.getProtocol())) {
525                     return false;
526                 }
527             } else if (config.isHostSet()) {
528                 return false;
529             }
530             if (proxyHost != null) {
531                 if (!proxyHost.equalsIgnoreCase (config.getProxyHost())
532                     || proxyPort != config.getProxyPort()) {
533                     // either proxyHost or proxyPort don't match
534                     return false;
535                 }
536             } else if (config.getProxyHost() != null) {
537                 return false;
538             }            
539             if (localAddress != null) {
540                 if (!localAddress.equals(config.getLocalAddress())) {
541                     return false;
542                 }
543             } else {
544                 if (config.getLocalAddress() != null) {
545                     return false; 
546                 }
547             }
548 
549             // everything matches
550             return true;
551 
552         } else {
553             return false;
554         }
555         
556     }
557 
558     /***
559      * @see java.lang.Object#hashCode()
560      */
561     public int hashCode() {
562         
563         if (host != null) {
564             return host.hashCode();
565         } else if (proxyHost != null) {
566             return proxyHost.hashCode();   
567         } else {
568             return super.hashCode();
569         }
570     }
571 
572 }