• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/routing/HttpRoute.java $
3  * $Revision: 653041 $
4  * $Date: 2008-05-03 03:39:28 -0700 (Sat, 03 May 2008) $
5  *
6  * ====================================================================
7  * Licensed to the Apache Software Foundation (ASF) under one
8  * or more contributor license agreements.  See the NOTICE file
9  * distributed with this work for additional information
10  * regarding copyright ownership.  The ASF licenses this file
11  * to you under the Apache License, Version 2.0 (the
12  * "License"); you may not use this file except in compliance
13  * with the License.  You may obtain a copy of the License at
14  *
15  *   http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing,
18  * software distributed under the License is distributed on an
19  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20  * KIND, either express or implied.  See the License for the
21  * specific language governing permissions and limitations
22  * under the License.
23  * ====================================================================
24  *
25  * This software consists of voluntary contributions made by many
26  * individuals on behalf of the Apache Software Foundation.  For more
27  * information on the Apache Software Foundation, please see
28  * <http://www.apache.org/>.
29  *
30  */
31 
32 package org.apache.http.conn.routing;
33 
34 import java.net.InetAddress;
35 
36 import org.apache.http.HttpHost;
37 
38 /**
39  * The route for a request.
40  * Instances of this class are unmodifiable and therefore suitable
41  * for use as lookup keys.
42  *
43  * @author <a href="mailto:rolandw at apache.org">Roland Weber</a>
44  *
45  *
46  * <!-- empty lines to avoid svn diff problems -->
47  * @version $Revision: 653041 $
48  *
49  * @since 4.0
50  *
51  * @deprecated Please use {@link java.net.URL#openConnection} instead.
52  *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
53  *     for further details.
54  */
55 @Deprecated
56 public final class HttpRoute implements RouteInfo, Cloneable {
57 
58     /** The target host to connect to. */
59     private final HttpHost targetHost;
60 
61     /**
62      * The local address to connect from.
63      * <code>null</code> indicates that the default should be used.
64      */
65     private final InetAddress localAddress;
66 
67     /** The proxy servers, if any. */
68     private final HttpHost[] proxyChain;
69 
70     /** Whether the the route is tunnelled through the proxy. */
71     private final TunnelType tunnelled;
72 
73     /** Whether the route is layered. */
74     private final LayerType layered;
75 
76     /** Whether the route is (supposed to be) secure. */
77     private final boolean secure;
78 
79 
80     /**
81      * Internal, fully-specified constructor.
82      * This constructor does <i>not</i> clone the proxy chain array,
83      * nor test it for <code>null</code> elements. This conversion and
84      * check is the responsibility of the public constructors.
85      * The order of arguments here is different from the similar public
86      * constructor, as required by Java.
87      *
88      * @param local     the local address to route from, or
89      *                  <code>null</code> for the default
90      * @param target    the host to which to route
91      * @param proxies   the proxy chain to use, or
92      *                  <code>null</code> for a direct route
93      * @param secure    <code>true</code> if the route is (to be) secure,
94      *                  <code>false</code> otherwise
95      * @param tunnelled the tunnel type of this route, or
96      *                  <code>null</code> for PLAIN
97      * @param layered   the layering type of this route, or
98      *                  <code>null</code> for PLAIN
99      */
HttpRoute(InetAddress local, HttpHost target, HttpHost[] proxies, boolean secure, TunnelType tunnelled, LayerType layered)100     private HttpRoute(InetAddress local,
101                       HttpHost target, HttpHost[] proxies,
102                       boolean secure,
103                       TunnelType tunnelled, LayerType layered) {
104         if (target == null) {
105             throw new IllegalArgumentException
106                 ("Target host may not be null.");
107         }
108         if ((tunnelled == TunnelType.TUNNELLED) && (proxies == null)) {
109             throw new IllegalArgumentException
110                 ("Proxy required if tunnelled.");
111         }
112 
113         // tunnelled is already checked above, that is in line with the default
114         if (tunnelled == null)
115             tunnelled = TunnelType.PLAIN;
116         if (layered == null)
117             layered = LayerType.PLAIN;
118 
119         this.targetHost   = target;
120         this.localAddress = local;
121         this.proxyChain   = proxies;
122         this.secure       = secure;
123         this.tunnelled    = tunnelled;
124         this.layered      = layered;
125     }
126 
127 
128     /**
129      * Creates a new route with all attributes specified explicitly.
130      *
131      * @param target    the host to which to route
132      * @param local     the local address to route from, or
133      *                  <code>null</code> for the default
134      * @param proxies   the proxy chain to use, or
135      *                  <code>null</code> for a direct route
136      * @param secure    <code>true</code> if the route is (to be) secure,
137      *                  <code>false</code> otherwise
138      * @param tunnelled the tunnel type of this route
139      * @param layered   the layering type of this route
140      */
HttpRoute(HttpHost target, InetAddress local, HttpHost[] proxies, boolean secure, TunnelType tunnelled, LayerType layered)141     public HttpRoute(HttpHost target, InetAddress local, HttpHost[] proxies,
142                      boolean secure, TunnelType tunnelled, LayerType layered) {
143         this(local, target, toChain(proxies), secure, tunnelled, layered);
144     }
145 
146 
147     /**
148      * Creates a new route with at most one proxy.
149      *
150      * @param target    the host to which to route
151      * @param local     the local address to route from, or
152      *                  <code>null</code> for the default
153      * @param proxy     the proxy to use, or
154      *                  <code>null</code> for a direct route
155      * @param secure    <code>true</code> if the route is (to be) secure,
156      *                  <code>false</code> otherwise
157      * @param tunnelled <code>true</code> if the route is (to be) tunnelled
158      *                  via the proxy,
159      *                  <code>false</code> otherwise
160      * @param layered   <code>true</code> if the route includes a
161      *                  layered protocol,
162      *                  <code>false</code> otherwise
163      */
HttpRoute(HttpHost target, InetAddress local, HttpHost proxy, boolean secure, TunnelType tunnelled, LayerType layered)164     public HttpRoute(HttpHost target, InetAddress local, HttpHost proxy,
165                      boolean secure, TunnelType tunnelled, LayerType layered) {
166         this(local, target, toChain(proxy), secure, tunnelled, layered);
167     }
168 
169 
170     /**
171      * Creates a new direct route.
172      * That is a route without a proxy.
173      *
174      * @param target    the host to which to route
175      * @param local     the local address to route from, or
176      *                  <code>null</code> for the default
177      * @param secure    <code>true</code> if the route is (to be) secure,
178      *                  <code>false</code> otherwise
179      */
HttpRoute(HttpHost target, InetAddress local, boolean secure)180     public HttpRoute(HttpHost target, InetAddress local, boolean secure) {
181         this(local, target, null, secure, TunnelType.PLAIN, LayerType.PLAIN);
182     }
183 
184 
185     /**
186      * Creates a new direct insecure route.
187      *
188      * @param target    the host to which to route
189      */
HttpRoute(HttpHost target)190     public HttpRoute(HttpHost target) {
191         this(null, target, null, false, TunnelType.PLAIN, LayerType.PLAIN);
192     }
193 
194 
195     /**
196      * Creates a new route through a proxy.
197      * When using this constructor, the <code>proxy</code> MUST be given.
198      * For convenience, it is assumed that a secure connection will be
199      * layered over a tunnel through the proxy.
200      *
201      * @param target    the host to which to route
202      * @param local     the local address to route from, or
203      *                  <code>null</code> for the default
204      * @param proxy     the proxy to use
205      * @param secure    <code>true</code> if the route is (to be) secure,
206      *                  <code>false</code> otherwise
207      */
HttpRoute(HttpHost target, InetAddress local, HttpHost proxy, boolean secure)208     public HttpRoute(HttpHost target, InetAddress local, HttpHost proxy,
209                      boolean secure) {
210         this(local, target, toChain(proxy), secure,
211              secure ? TunnelType.TUNNELLED : TunnelType.PLAIN,
212              secure ? LayerType.LAYERED    : LayerType.PLAIN);
213         if (proxy == null) {
214             throw new IllegalArgumentException
215                 ("Proxy host may not be null.");
216         }
217     }
218 
219 
220     /**
221      * Helper to convert a proxy to a proxy chain.
222      *
223      * @param proxy     the only proxy in the chain, or <code>null</code>
224      *
225      * @return  a proxy chain array, or <code>null</code>
226      */
toChain(HttpHost proxy)227     private static HttpHost[] toChain(HttpHost proxy) {
228         if (proxy == null)
229             return null;
230 
231         return new HttpHost[]{ proxy };
232     }
233 
234 
235     /**
236      * Helper to duplicate and check a proxy chain.
237      * An empty proxy chain is converted to <code>null</code>.
238      *
239      * @param proxies   the proxy chain to duplicate, or <code>null</code>
240      *
241      * @return  a new proxy chain array, or <code>null</code>
242      */
toChain(HttpHost[] proxies)243     private static HttpHost[] toChain(HttpHost[] proxies) {
244         if ((proxies == null) || (proxies.length < 1))
245             return null;
246 
247         for (HttpHost proxy : proxies) {
248             if (proxy == null)
249                 throw new IllegalArgumentException
250                         ("Proxy chain may not contain null elements.");
251         }
252 
253         // copy the proxy chain, the traditional way
254         HttpHost[] result = new HttpHost[proxies.length];
255         System.arraycopy(proxies, 0, result, 0, proxies.length);
256 
257         return result;
258     }
259 
260 
261 
262     // non-JavaDoc, see interface RouteInfo
getTargetHost()263     public final HttpHost getTargetHost() {
264         return this.targetHost;
265     }
266 
267 
268     // non-JavaDoc, see interface RouteInfo
getLocalAddress()269     public final InetAddress getLocalAddress() {
270         return this.localAddress;
271     }
272 
273 
274     // non-JavaDoc, see interface RouteInfo
getHopCount()275     public final int getHopCount() {
276         return (proxyChain == null) ? 1 : (proxyChain.length+1);
277     }
278 
279 
280     // non-JavaDoc, see interface RouteInfo
getHopTarget(int hop)281     public final HttpHost getHopTarget(int hop) {
282         if (hop < 0)
283             throw new IllegalArgumentException
284                 ("Hop index must not be negative: " + hop);
285         final int hopcount = getHopCount();
286         if (hop >= hopcount)
287             throw new IllegalArgumentException
288                 ("Hop index " + hop +
289                  " exceeds route length " + hopcount);
290 
291         HttpHost result = null;
292         if (hop < hopcount-1)
293             result = this.proxyChain[hop];
294         else
295             result = this.targetHost;
296 
297         return result;
298     }
299 
300 
301     // non-JavaDoc, see interface RouteInfo
getProxyHost()302     public final HttpHost getProxyHost() {
303         return (this.proxyChain == null) ? null : this.proxyChain[0];
304     }
305 
306 
307     // non-JavaDoc, see interface RouteInfo
getTunnelType()308     public final TunnelType getTunnelType() {
309         return this.tunnelled;
310     }
311 
312 
313     // non-JavaDoc, see interface RouteInfo
isTunnelled()314     public final boolean isTunnelled() {
315         return (this.tunnelled == TunnelType.TUNNELLED);
316     }
317 
318 
319     // non-JavaDoc, see interface RouteInfo
getLayerType()320     public final LayerType getLayerType() {
321         return this.layered;
322     }
323 
324 
325     // non-JavaDoc, see interface RouteInfo
isLayered()326     public final boolean isLayered() {
327         return (this.layered == LayerType.LAYERED);
328     }
329 
330 
331     // non-JavaDoc, see interface RouteInfo
isSecure()332     public final boolean isSecure() {
333         return this.secure;
334     }
335 
336 
337     /**
338      * Compares this route to another.
339      *
340      * @param o         the object to compare with
341      *
342      * @return  <code>true</code> if the argument is the same route,
343      *          <code>false</code>
344      */
345     @Override
equals(Object o)346     public final boolean equals(Object o) {
347         if (o == this)
348             return true;
349         if (!(o instanceof HttpRoute))
350             return false;
351 
352         HttpRoute that = (HttpRoute) o;
353         boolean equal = this.targetHost.equals(that.targetHost);
354         equal &=
355             ( this.localAddress == that.localAddress) ||
356             ((this.localAddress != null) &&
357               this.localAddress.equals(that.localAddress));
358         equal &=
359             ( this.proxyChain        == that.proxyChain) ||
360             ((this.proxyChain        != null) &&
361              (that.proxyChain        != null) &&
362              (this.proxyChain.length == that.proxyChain.length));
363         // comparison of actual proxies follows below
364         equal &=
365             (this.secure    == that.secure) &&
366             (this.tunnelled == that.tunnelled) &&
367             (this.layered   == that.layered);
368 
369         // chain length has been compared above, now check the proxies
370         if (equal && (this.proxyChain != null)) {
371             for (int i=0; equal && (i<this.proxyChain.length); i++)
372                 equal = this.proxyChain[i].equals(that.proxyChain[i]);
373         }
374 
375         return equal;
376     }
377 
378 
379     /**
380      * Generates a hash code for this route.
381      *
382      * @return  the hash code
383      */
384     @Override
hashCode()385     public final int hashCode() {
386 
387         int hc = this.targetHost.hashCode();
388 
389         if (this.localAddress != null)
390             hc ^= localAddress.hashCode();
391         if (this.proxyChain != null) {
392             hc ^= proxyChain.length;
393             for (HttpHost aProxyChain : proxyChain) hc ^= aProxyChain.hashCode();
394         }
395 
396         if (this.secure)
397             hc ^= 0x11111111;
398 
399         hc ^= this.tunnelled.hashCode();
400         hc ^= this.layered.hashCode();
401 
402         return hc;
403     }
404 
405 
406     /**
407      * Obtains a description of this route.
408      *
409      * @return  a human-readable representation of this route
410      */
411     @Override
toString()412     public final String toString() {
413         StringBuilder cab = new StringBuilder(50 + getHopCount()*30);
414 
415         cab.append("HttpRoute[");
416         if (this.localAddress != null) {
417             cab.append(this.localAddress);
418             cab.append("->");
419         }
420         cab.append('{');
421         if (this.tunnelled == TunnelType.TUNNELLED)
422             cab.append('t');
423         if (this.layered == LayerType.LAYERED)
424             cab.append('l');
425         if (this.secure)
426             cab.append('s');
427         cab.append("}->");
428         if (this.proxyChain != null) {
429             for (HttpHost aProxyChain : this.proxyChain) {
430                 cab.append(aProxyChain);
431                 cab.append("->");
432             }
433         }
434         cab.append(this.targetHost);
435         cab.append(']');
436 
437         return cab.toString();
438     }
439 
440 
441     // default implementation of clone() is sufficient
442     @Override
clone()443     public Object clone() throws CloneNotSupportedException {
444         return super.clone();
445     }
446 
447 
448 } // class HttpRoute
449