Exemplo n.º 1
0
        /// <summary>Establishes the target route.</summary>
        /// <remarks>Establishes the target route.</remarks>
        /// <exception cref="Apache.Http.HttpException"></exception>
        /// <exception cref="System.IO.IOException"></exception>
        internal virtual void EstablishRoute(AuthState proxyAuthState, HttpClientConnection
                                             managedConn, HttpRoute route, IHttpRequest request, HttpClientContext context)
        {
            RequestConfig config  = context.GetRequestConfig();
            int           timeout = config.GetConnectTimeout();
            RouteTracker  tracker = new RouteTracker(route);
            int           step;

            do
            {
                HttpRoute fact = tracker.ToRoute();
                step = this.routeDirector.NextStep(route, fact);
                switch (step)
                {
                case HttpRouteDirector.ConnectTarget:
                {
                    this.connManager.Connect(managedConn, route, timeout > 0 ? timeout : 0, context);
                    tracker.ConnectTarget(route.IsSecure());
                    break;
                }

                case HttpRouteDirector.ConnectProxy:
                {
                    this.connManager.Connect(managedConn, route, timeout > 0 ? timeout : 0, context);
                    HttpHost proxy = route.GetProxyHost();
                    tracker.ConnectProxy(proxy, false);
                    break;
                }

                case HttpRouteDirector.TunnelTarget:
                {
                    bool secure = CreateTunnelToTarget(proxyAuthState, managedConn, route, request, context
                                                       );
                    this.log.Debug("Tunnel to target created.");
                    tracker.TunnelTarget(secure);
                    break;
                }

                case HttpRouteDirector.TunnelProxy:
                {
                    // The most simple example for this case is a proxy chain
                    // of two proxies, where P1 must be tunnelled to P2.
                    // route: Source -> P1 -> P2 -> Target (3 hops)
                    // fact:  Source -> P1 -> Target       (2 hops)
                    int hop = fact.GetHopCount() - 1;
                    // the hop to establish
                    bool secure = CreateTunnelToProxy(route, hop, context);
                    this.log.Debug("Tunnel to proxy created.");
                    tracker.TunnelProxy(route.GetHopTarget(hop), secure);
                    break;
                }

                case HttpRouteDirector.LayerProtocol:
                {
                    this.connManager.Upgrade(managedConn, route, context);
                    tracker.LayerProtocol(route.IsSecure());
                    break;
                }

                case HttpRouteDirector.Unreachable:
                {
                    throw new HttpException("Unable to establish route: " + "planned = " + route + "; current = "
                                            + fact);
                }

                case HttpRouteDirector.Complete:
                {
                    this.connManager.RouteComplete(managedConn, route, context);
                    break;
                }

                default:
                {
                    throw new InvalidOperationException("Unknown step indicator " + step + " from RouteDirector."
                                                        );
                }
                }
            }while (step > HttpRouteDirector.Complete);
        }