View Javadoc

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