mobile/android/thirdparty/ch/boye/httpclientandroidlib/conn/routing/BasicRouteDirector.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/conn/routing/BasicRouteDirector.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,168 @@
     1.4 +/*
     1.5 + * ====================================================================
     1.6 + * Licensed to the Apache Software Foundation (ASF) under one
     1.7 + * or more contributor license agreements.  See the NOTICE file
     1.8 + * distributed with this work for additional information
     1.9 + * regarding copyright ownership.  The ASF licenses this file
    1.10 + * to you under the Apache License, Version 2.0 (the
    1.11 + * "License"); you may not use this file except in compliance
    1.12 + * with the License.  You may obtain a copy of the License at
    1.13 + *
    1.14 + *   http://www.apache.org/licenses/LICENSE-2.0
    1.15 + *
    1.16 + * Unless required by applicable law or agreed to in writing,
    1.17 + * software distributed under the License is distributed on an
    1.18 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    1.19 + * KIND, either express or implied.  See the License for the
    1.20 + * specific language governing permissions and limitations
    1.21 + * under the License.
    1.22 + * ====================================================================
    1.23 + *
    1.24 + * This software consists of voluntary contributions made by many
    1.25 + * individuals on behalf of the Apache Software Foundation.  For more
    1.26 + * information on the Apache Software Foundation, please see
    1.27 + * <http://www.apache.org/>.
    1.28 + *
    1.29 + */
    1.30 +
    1.31 +package ch.boye.httpclientandroidlib.conn.routing;
    1.32 +
    1.33 +import ch.boye.httpclientandroidlib.annotation.Immutable;
    1.34 +
    1.35 +/**
    1.36 + * Basic implementation of an {@link HttpRouteDirector HttpRouteDirector}.
    1.37 + * This implementation is stateless and therefore thread-safe.
    1.38 + *
    1.39 + * @since 4.0
    1.40 + */
    1.41 +@Immutable
    1.42 +public class BasicRouteDirector implements HttpRouteDirector {
    1.43 +
    1.44 +    /**
    1.45 +     * Provides the next step.
    1.46 +     *
    1.47 +     * @param plan      the planned route
    1.48 +     * @param fact      the currently established route, or
    1.49 +     *                  <code>null</code> if nothing is established
    1.50 +     *
    1.51 +     * @return  one of the constants defined in this class, indicating
    1.52 +     *          either the next step to perform, or success, or failure.
    1.53 +     *          0 is for success, a negative value for failure.
    1.54 +     */
    1.55 +    public int nextStep(RouteInfo plan, RouteInfo fact) {
    1.56 +        if (plan == null) {
    1.57 +            throw new IllegalArgumentException
    1.58 +                ("Planned route may not be null.");
    1.59 +        }
    1.60 +
    1.61 +        int step = UNREACHABLE;
    1.62 +
    1.63 +        if ((fact == null) || (fact.getHopCount() < 1))
    1.64 +            step = firstStep(plan);
    1.65 +        else if (plan.getHopCount() > 1)
    1.66 +            step = proxiedStep(plan, fact);
    1.67 +        else
    1.68 +            step = directStep(plan, fact);
    1.69 +
    1.70 +        return step;
    1.71 +
    1.72 +    } // nextStep
    1.73 +
    1.74 +
    1.75 +    /**
    1.76 +     * Determines the first step to establish a route.
    1.77 +     *
    1.78 +     * @param plan      the planned route
    1.79 +     *
    1.80 +     * @return  the first step
    1.81 +     */
    1.82 +    protected int firstStep(RouteInfo plan) {
    1.83 +
    1.84 +        return (plan.getHopCount() > 1) ?
    1.85 +            CONNECT_PROXY : CONNECT_TARGET;
    1.86 +    }
    1.87 +
    1.88 +
    1.89 +    /**
    1.90 +     * Determines the next step to establish a direct connection.
    1.91 +     *
    1.92 +     * @param plan      the planned route
    1.93 +     * @param fact      the currently established route
    1.94 +     *
    1.95 +     * @return  one of the constants defined in this class, indicating
    1.96 +     *          either the next step to perform, or success, or failure
    1.97 +     */
    1.98 +    protected int directStep(RouteInfo plan, RouteInfo fact) {
    1.99 +
   1.100 +        if (fact.getHopCount() > 1)
   1.101 +            return UNREACHABLE;
   1.102 +        if (!plan.getTargetHost().equals(fact.getTargetHost()))
   1.103 +            return UNREACHABLE;
   1.104 +        // If the security is too low, we could now suggest to layer
   1.105 +        // a secure protocol on the direct connection. Layering on direct
   1.106 +        // connections has not been supported in HttpClient 3.x, we don't
   1.107 +        // consider it here until there is a real-life use case for it.
   1.108 +
   1.109 +        // Should we tolerate if security is better than planned?
   1.110 +        // (plan.isSecure() && !fact.isSecure())
   1.111 +        if (plan.isSecure() != fact.isSecure())
   1.112 +            return UNREACHABLE;
   1.113 +
   1.114 +        // Local address has to match only if the plan specifies one.
   1.115 +        if ((plan.getLocalAddress() != null) &&
   1.116 +            !plan.getLocalAddress().equals(fact.getLocalAddress())
   1.117 +            )
   1.118 +            return UNREACHABLE;
   1.119 +
   1.120 +        return COMPLETE;
   1.121 +    }
   1.122 +
   1.123 +
   1.124 +    /**
   1.125 +     * Determines the next step to establish a connection via proxy.
   1.126 +     *
   1.127 +     * @param plan      the planned route
   1.128 +     * @param fact      the currently established route
   1.129 +     *
   1.130 +     * @return  one of the constants defined in this class, indicating
   1.131 +     *          either the next step to perform, or success, or failure
   1.132 +     */
   1.133 +    protected int proxiedStep(RouteInfo plan, RouteInfo fact) {
   1.134 +
   1.135 +        if (fact.getHopCount() <= 1)
   1.136 +            return UNREACHABLE;
   1.137 +        if (!plan.getTargetHost().equals(fact.getTargetHost()))
   1.138 +            return UNREACHABLE;
   1.139 +        final int phc = plan.getHopCount();
   1.140 +        final int fhc = fact.getHopCount();
   1.141 +        if (phc < fhc)
   1.142 +            return UNREACHABLE;
   1.143 +
   1.144 +        for (int i=0; i<fhc-1; i++) {
   1.145 +            if (!plan.getHopTarget(i).equals(fact.getHopTarget(i)))
   1.146 +                return UNREACHABLE;
   1.147 +        }
   1.148 +        // now we know that the target matches and proxies so far are the same
   1.149 +        if (phc > fhc)
   1.150 +            return TUNNEL_PROXY; // need to extend the proxy chain
   1.151 +
   1.152 +        // proxy chain and target are the same, check tunnelling and layering
   1.153 +        if ((fact.isTunnelled() && !plan.isTunnelled()) ||
   1.154 +            (fact.isLayered()   && !plan.isLayered()))
   1.155 +            return UNREACHABLE;
   1.156 +
   1.157 +        if (plan.isTunnelled() && !fact.isTunnelled())
   1.158 +            return TUNNEL_TARGET;
   1.159 +        if (plan.isLayered() && !fact.isLayered())
   1.160 +            return LAYER_PROTOCOL;
   1.161 +
   1.162 +        // tunnel and layering are the same, remains to check the security
   1.163 +        // Should we tolerate if security is better than planned?
   1.164 +        // (plan.isSecure() && !fact.isSecure())
   1.165 +        if (plan.isSecure() != fact.isSecure())
   1.166 +            return UNREACHABLE;
   1.167 +
   1.168 +        return COMPLETE;
   1.169 +    }
   1.170 +
   1.171 +}

mercurial