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