View Javadoc

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