View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http;
29  
30  import java.io.Serializable;
31  import java.net.InetAddress;
32  import java.util.Locale;
33  
34  import org.apache.http.annotation.Immutable;
35  import org.apache.http.util.Args;
36  import org.apache.http.util.LangUtils;
37  
38  /**
39   * Holds all of the variables needed to describe an HTTP connection to a host.
40   * This includes remote host name, port and scheme.
41   *
42   *
43   * @since 4.0
44   */
45  @Immutable
46  public final class HttpHost implements Cloneable, Serializable {
47  
48      private static final long serialVersionUID = -7529410654042457626L;
49  
50      /** The default scheme is "http". */
51      public static final String DEFAULT_SCHEME_NAME = "http";
52  
53      /** The host to use. */
54      protected final String hostname;
55  
56      /** The lowercase host, for {@link #equals} and {@link #hashCode}. */
57      protected final String lcHostname;
58  
59  
60      /** The port to use, defaults to -1 if not set. */
61      protected final int port;
62  
63      /** The scheme (lowercased) */
64      protected final String schemeName;
65  
66      protected final InetAddress address;
67  
68      /**
69       * Creates a new {@link HttpHost HttpHost}, specifying all values.
70       * Constructor for HttpHost.
71       *
72       * @param hostname  the hostname (IP or DNS name)
73       * @param port      the port number.
74       *                  <code>-1</code> indicates the scheme default port.
75       * @param scheme    the name of the scheme.
76       *                  <code>null</code> indicates the
77       *                  {@link #DEFAULT_SCHEME_NAME default scheme}
78       */
79      public HttpHost(final String hostname, final int port, final String scheme) {
80          super();
81          this.hostname   = Args.notBlank(hostname, "Host name");
82          this.lcHostname = hostname.toLowerCase(Locale.ENGLISH);
83          if (scheme != null) {
84              this.schemeName = scheme.toLowerCase(Locale.ENGLISH);
85          } else {
86              this.schemeName = DEFAULT_SCHEME_NAME;
87          }
88          this.port = port;
89          this.address = null;
90      }
91  
92      /**
93       * Creates a new {@link HttpHost HttpHost}, with default scheme.
94       *
95       * @param hostname  the hostname (IP or DNS name)
96       * @param port      the port number.
97       *                  <code>-1</code> indicates the scheme default port.
98       */
99      public HttpHost(final String hostname, final int port) {
100         this(hostname, port, null);
101     }
102 
103     /**
104      * Creates a new {@link HttpHost HttpHost}, with default scheme and port.
105      *
106      * @param hostname  the hostname (IP or DNS name)
107      */
108     public HttpHost(final String hostname) {
109         this(hostname, -1, null);
110     }
111 
112     /**
113      * Creates a new {@link HttpHost HttpHost}, specifying all values.
114      * Constructor for HttpHost.
115      *
116      * @param address   the inet address.
117      * @param port      the port number.
118      *                  <code>-1</code> indicates the scheme default port.
119      * @param scheme    the name of the scheme.
120      *                  <code>null</code> indicates the
121      *                  {@link #DEFAULT_SCHEME_NAME default scheme}
122      *
123      * @since 4.3
124      */
125     public HttpHost(final InetAddress address, final int port, final String scheme) {
126         super();
127         this.address = Args.notNull(address, "Inet address");
128         this.hostname = address.getHostAddress();
129         this.lcHostname = this.hostname.toLowerCase(Locale.ENGLISH);
130         if (scheme != null) {
131             this.schemeName = scheme.toLowerCase(Locale.ENGLISH);
132         } else {
133             this.schemeName = DEFAULT_SCHEME_NAME;
134         }
135         this.port = port;
136     }
137 
138     /**
139      * Creates a new {@link HttpHost HttpHost}, with default scheme.
140      *
141      * @param address   the inet address.
142      * @param port      the port number.
143      *                  <code>-1</code> indicates the scheme default port.
144      *
145      * @since 4.3
146      */
147     public HttpHost(final InetAddress address, final int port) {
148         this(address, port, null);
149     }
150 
151     /**
152      * Creates a new {@link HttpHost HttpHost}, with default scheme and port.
153      *
154      * @param address   the inet address.
155      *
156      * @since 4.3
157      */
158     public HttpHost(final InetAddress address) {
159         this(address, -1, null);
160     }
161 
162     /**
163      * Copy constructor for {@link HttpHost HttpHost}.
164      *
165      * @param httphost the HTTP host to copy details from
166      */
167     public HttpHost (final HttpHost httphost) {
168         super();
169         Args.notNull(httphost, "HTTP host");
170         this.hostname   = httphost.hostname;
171         this.lcHostname = httphost.lcHostname;
172         this.schemeName = httphost.schemeName;
173         this.port = httphost.port;
174         this.address = httphost.address;
175     }
176 
177     /**
178      * Returns the host name.
179      *
180      * @return the host name (IP or DNS name)
181      */
182     public String getHostName() {
183         return this.hostname;
184     }
185 
186     /**
187      * Returns the port.
188      *
189      * @return the host port, or <code>-1</code> if not set
190      */
191     public int getPort() {
192         return this.port;
193     }
194 
195     /**
196      * Returns the scheme name.
197      *
198      * @return the scheme name
199      */
200     public String getSchemeName() {
201         return this.schemeName;
202     }
203 
204     /**
205      * Returns the inet address if explicitly set by a constructor,
206      *   <code>null</code> otherwise.
207      * @return the inet address
208      *
209      * @since 4.3
210      */
211     public InetAddress getAddress() {
212         return this.address;
213     }
214 
215     /**
216      * Return the host URI, as a string.
217      *
218      * @return the host URI
219      */
220     public String toURI() {
221         final StringBuilder buffer = new StringBuilder();
222         buffer.append(this.schemeName);
223         buffer.append("://");
224         buffer.append(this.hostname);
225         if (this.port != -1) {
226             buffer.append(':');
227             buffer.append(Integer.toString(this.port));
228         }
229         return buffer.toString();
230     }
231 
232 
233     /**
234      * Obtains the host string, without scheme prefix.
235      *
236      * @return  the host string, for example <code>localhost:8080</code>
237      */
238     public String toHostString() {
239         if (this.port != -1) {
240             //the highest port number is 65535, which is length 6 with the addition of the colon
241             final StringBuilder buffer = new StringBuilder(this.hostname.length() + 6);
242             buffer.append(this.hostname);
243             buffer.append(":");
244             buffer.append(Integer.toString(this.port));
245             return buffer.toString();
246         } else {
247             return this.hostname;
248         }
249     }
250 
251 
252     @Override
253     public String toString() {
254         return toURI();
255     }
256 
257 
258     @Override
259     public boolean equals(final Object obj) {
260         if (this == obj) {
261             return true;
262         }
263         if (obj instanceof HttpHost) {
264             final HttpHost that = (HttpHost) obj;
265             return this.lcHostname.equals(that.lcHostname)
266                 && this.port == that.port
267                 && this.schemeName.equals(that.schemeName);
268         } else {
269             return false;
270         }
271     }
272 
273     /**
274      * @see java.lang.Object#hashCode()
275      */
276     @Override
277     public int hashCode() {
278         int hash = LangUtils.HASH_SEED;
279         hash = LangUtils.hashCode(hash, this.lcHostname);
280         hash = LangUtils.hashCode(hash, this.port);
281         hash = LangUtils.hashCode(hash, this.schemeName);
282         return hash;
283     }
284 
285     @Override
286     public Object clone() throws CloneNotSupportedException {
287         return super.clone();
288     }
289 
290 }