1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/* 2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/conn/routing/RouteTracker.java $ 3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Revision: 620254 $ 4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Date: 2008-02-10 02:18:48 -0800 (Sun, 10 Feb 2008) $ 5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ==================================================================== 7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one 8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * or more contributor license agreements. See the NOTICE file 9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * distributed with this work for additional information 10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * regarding copyright ownership. The ASF licenses this file 11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to you under the Apache License, Version 2.0 (the 12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * "License"); you may not use this file except in compliance 13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * with the License. You may obtain a copy of the License at 14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Unless required by applicable law or agreed to in writing, 18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * software distributed under the License is distributed on an 19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * KIND, either express or implied. See the License for the 21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * specific language governing permissions and limitations 22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * under the License. 23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ==================================================================== 24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This software consists of voluntary contributions made by many 26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * individuals on behalf of the Apache Software Foundation. For more 27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * information on the Apache Software Foundation, please see 28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <http://www.apache.org/>. 29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpackage org.apache.http.conn.routing; 33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.net.InetAddress; 35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.HttpHost; 37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/** 40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Helps tracking the steps in establishing a route. 41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author <a href="mailto:rolandw at apache.org">Roland Weber</a> 43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <!-- empty lines to avoid svn diff problems --> 46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @version $Revision: 620254 $ 47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 4.0 49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic final class RouteTracker implements RouteInfo, Cloneable { 51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** The target host to connect to. */ 53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private final HttpHost targetHost; 54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The local address to connect from. 57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>null</code> indicates that the default should be used. 58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private final InetAddress localAddress; 60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // the attributes above are fixed at construction time 62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // now follow attributes that indicate the established route 63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** Whether the first hop of the route is established. */ 65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private boolean connected; 66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** The proxy chain, if any. */ 68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private HttpHost[] proxyChain; 69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** Whether the the route is tunnelled end-to-end through proxies. */ 71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private TunnelType tunnelled; 72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** Whether the route is layered over a tunnel. */ 74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private LayerType layered; 75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** Whether the route is secure. */ 77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private boolean secure; 78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Creates a new route tracker. 82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The target and origin need to be specified at creation time. 83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param target the host to which to route 85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param local the local address to route from, or 86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>null</code> for the default 87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public RouteTracker(HttpHost target, InetAddress local) { 89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (target == null) { 90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalArgumentException("Target host may not be null."); 91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.targetHost = target; 93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.localAddress = local; 94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.tunnelled = TunnelType.PLAIN; 95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.layered = LayerType.PLAIN; 96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Creates a new tracker for the given route. 101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Only target and origin are taken from the route, 102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * everything else remains to be tracked. 103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param route the route to track 105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public RouteTracker(HttpRoute route) { 107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this(route.getTargetHost(), route.getLocalAddress()); 108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Tracks connecting to the target. 113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param secure <code>true</code> if the route is secure, 115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>false</code> otherwise 116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final void connectTarget(boolean secure) { 118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.connected) { 119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalStateException("Already connected."); 120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.connected = true; 122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.secure = secure; 123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Tracks connecting to the first proxy. 128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param proxy the proxy connected to 130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param secure <code>true</code> if the route is secure, 131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>false</code> otherwise 132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final void connectProxy(HttpHost proxy, boolean secure) { 134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (proxy == null) { 135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalArgumentException("Proxy host may not be null."); 136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.connected) { 138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalStateException("Already connected."); 139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.connected = true; 141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.proxyChain = new HttpHost[]{ proxy }; 142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.secure = secure; 143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Tracks tunnelling to the target. 148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param secure <code>true</code> if the route is secure, 150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>false</code> otherwise 151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final void tunnelTarget(boolean secure) { 153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!this.connected) { 154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalStateException("No tunnel unless connected."); 155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.proxyChain == null) { 157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalStateException("No tunnel without proxy."); 158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.tunnelled = TunnelType.TUNNELLED; 160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.secure = secure; 161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Tracks tunnelling to a proxy in a proxy chain. 166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This will extend the tracked proxy chain, but it does not mark 167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the route as tunnelled. Only end-to-end tunnels are considered there. 168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param proxy the proxy tunnelled to 170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param secure <code>true</code> if the route is secure, 171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>false</code> otherwise 172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final void tunnelProxy(HttpHost proxy, boolean secure) { 174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (proxy == null) { 175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalArgumentException("Proxy host may not be null."); 176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!this.connected) { 178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalStateException("No tunnel unless connected."); 179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.proxyChain == null) { 181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalStateException("No proxy tunnel without proxy."); 182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // prepare an extended proxy chain 185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project HttpHost[] proxies = new HttpHost[this.proxyChain.length+1]; 186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project System.arraycopy(this.proxyChain, 0, 187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project proxies, 0, this.proxyChain.length); 188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project proxies[proxies.length-1] = proxy; 189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.proxyChain = proxies; 191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.secure = secure; 192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Tracks layering a protocol. 197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param secure <code>true</code> if the route is secure, 199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>false</code> otherwise 200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final void layerProtocol(boolean secure) { 202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // it is possible to layer a protocol over a direct connection, 203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // although this case is probably not considered elsewhere 204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!this.connected) { 205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalStateException 206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ("No layered protocol unless connected."); 207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.layered = LayerType.LAYERED; 209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.secure = secure; 210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final HttpHost getTargetHost() { 216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return this.targetHost; 217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final InetAddress getLocalAddress() { 222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return this.localAddress; 223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final int getHopCount() { 228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project int hops = 0; 229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.connected) { 230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (proxyChain == null) 231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project hops = 1; 232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project else 233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project hops = proxyChain.length + 1; 234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return hops; 236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final HttpHost getHopTarget(int hop) { 241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (hop < 0) 242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalArgumentException 243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ("Hop index must not be negative: " + hop); 244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final int hopcount = getHopCount(); 245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (hop >= hopcount) { 246069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalArgumentException 247069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ("Hop index " + hop + 248069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project " exceeds tracked route length " + hopcount +"."); 249069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project HttpHost result = null; 252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (hop < hopcount-1) 253069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project result = this.proxyChain[hop]; 254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project else 255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project result = this.targetHost; 256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return result; 258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final HttpHost getProxyHost() { 263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (this.proxyChain == null) ? null : this.proxyChain[0]; 264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final boolean isConnected() { 269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return this.connected; 270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final TunnelType getTunnelType() { 275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return this.tunnelled; 276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final boolean isTunnelled() { 281069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (this.tunnelled == TunnelType.TUNNELLED); 282069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 283069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 284069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 285069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 286069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final LayerType getLayerType() { 287069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return this.layered; 288069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 289069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 290069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 291069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 292069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final boolean isLayered() { 293069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (this.layered == LayerType.LAYERED); 294069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 295069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 296069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 297069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-JavaDoc, see interface RouteInfo 298069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final boolean isSecure() { 299069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return this.secure; 300069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 301069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 302069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 303069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 304069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Obtains the tracked route. 305069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * If a route has been tracked, it is {@link #isConnected connected}. 306069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * If not connected, nothing has been tracked so far. 307069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 308069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return the tracked route, or 309069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>null</code> if nothing has been tracked so far 310069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 311069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final HttpRoute toRoute() { 312069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return !this.connected ? 313069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project null : new HttpRoute(this.targetHost, this.localAddress, 314069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.proxyChain, this.secure, 315069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.tunnelled, this.layered); 316069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 317069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 318069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 319069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 320069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Compares this tracked route to another. 321069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 322069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param o the object to compare with 323069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 324069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return <code>true</code> if the argument is the same tracked route, 325069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>false</code> 326069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 327069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project @Override 328069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final boolean equals(Object o) { 329069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (o == this) 330069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return true; 331069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!(o instanceof RouteTracker)) 332069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return false; 333069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 334069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project RouteTracker that = (RouteTracker) o; 335069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project boolean equal = this.targetHost.equals(that.targetHost); 336069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project equal &= 337069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ( this.localAddress == that.localAddress) || 338069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ((this.localAddress != null) && 339069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.localAddress.equals(that.localAddress)); 340069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project equal &= 341069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ( this.proxyChain == that.proxyChain) || 342069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ((this.proxyChain != null) && 343069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project (that.proxyChain != null) && 344069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project (this.proxyChain.length == that.proxyChain.length)); 345069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // comparison of actual proxies follows below 346069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project equal &= 347069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project (this.connected == that.connected) && 348069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project (this.secure == that.secure) && 349069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project (this.tunnelled == that.tunnelled) && 350069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project (this.layered == that.layered); 351069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 352069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // chain length has been compared above, now check the proxies 353069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (equal && (this.proxyChain != null)) { 354069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i=0; equal && (i<this.proxyChain.length); i++) 355069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project equal = this.proxyChain[i].equals(that.proxyChain[i]); 356069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 357069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 358069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return equal; 359069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 360069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 361069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 362069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 363069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Generates a hash code for this tracked route. 364069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Route trackers are modifiable and should therefore not be used 365069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * as lookup keys. Use {@link #toRoute toRoute} to obtain an 366069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * unmodifiable representation of the tracked route. 367069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 368069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return the hash code 369069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 370069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project @Override 371069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final int hashCode() { 372069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 373069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project int hc = this.targetHost.hashCode(); 374069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 375069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.localAddress != null) 376069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project hc ^= localAddress.hashCode(); 377069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.proxyChain != null) { 378069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project hc ^= proxyChain.length; 379069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i=0; i<proxyChain.length; i++) 380069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project hc ^= proxyChain[i].hashCode(); 381069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 382069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 383069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.connected) 384069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project hc ^= 0x11111111; 385069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.secure) 386069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project hc ^= 0x22222222; 387069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 388069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project hc ^= this.tunnelled.hashCode(); 389069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project hc ^= this.layered.hashCode(); 390069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 391069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return hc; 392069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 393069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 394069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 395069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 396069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Obtains a description of the tracked route. 397069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 398069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return a human-readable representation of the tracked route 399069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 400069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project @Override 401069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final String toString() { 402069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project StringBuilder cab = new StringBuilder(50 + getHopCount()*30); 403069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 404069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append("RouteTracker["); 405069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.localAddress != null) { 406069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append(this.localAddress); 407069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append("->"); 408069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 409069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append('{'); 410069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.connected) 411069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append('c'); 412069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.tunnelled == TunnelType.TUNNELLED) 413069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append('t'); 414069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.layered == LayerType.LAYERED) 415069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append('l'); 416069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.secure) 417069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append('s'); 418069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append("}->"); 419069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (this.proxyChain != null) { 420069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i=0; i<this.proxyChain.length; i++) { 421069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append(this.proxyChain[i]); 422069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append("->"); 423069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 424069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 425069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append(this.targetHost); 426069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cab.append(']'); 427069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 428069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return cab.toString(); 429069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 430069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 431069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 432069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // default implementation of clone() is sufficient 433069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project @Override 434069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object clone() throws CloneNotSupportedException { 435069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return super.clone(); 436069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 437069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 438069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 439069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} // class RouteTracker 440