Android Open Source - wototoplayer Route Selector






From Project

Back to project page wototoplayer.

License

The source code is released under:

Copyright (c) 2015, Chris Greenhalgh All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met...

If you think the Android project wototoplayer listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2012 Square, Inc.//  www. j  a v a2s  .  co  m
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.okhttp.internal.http;

import com.squareup.okhttp.Address;
import com.squareup.okhttp.Connection;
import com.squareup.okhttp.ConnectionPool;
import com.squareup.okhttp.Route;
import com.squareup.okhttp.RouteDatabase;
import com.squareup.okhttp.internal.Dns;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;

import static com.squareup.okhttp.internal.Util.getEffectivePort;

/**
 * Selects routes to connect to an origin server. Each connection requires a
 * choice of proxy server, IP address, and TLS mode. Connections may also be
 * recycled.
 */
public final class RouteSelector {
  /** Uses {@link com.squareup.okhttp.internal.Platform#enableTlsExtensions}. */
  private static final int TLS_MODE_MODERN = 1;
  /** Uses {@link com.squareup.okhttp.internal.Platform#supportTlsIntolerantServer}. */
  private static final int TLS_MODE_COMPATIBLE = 0;
  /** No TLS mode. */
  private static final int TLS_MODE_NULL = -1;

  private final Address address;
  private final URI uri;
  private final ProxySelector proxySelector;
  private final ConnectionPool pool;
  private final Dns dns;
  private final RouteDatabase routeDatabase;

  /* The most recently attempted route. */
  private Proxy lastProxy;
  private InetSocketAddress lastInetSocketAddress;

  /* State for negotiating the next proxy to use. */
  private boolean hasNextProxy;
  private Proxy userSpecifiedProxy;
  private Iterator<Proxy> proxySelectorProxies;

  /* State for negotiating the next InetSocketAddress to use. */
  private InetAddress[] socketAddresses;
  private int nextSocketAddressIndex;
  private int socketPort;

  /* State for negotiating the next TLS configuration */
  private int nextTlsMode = TLS_MODE_NULL;

  /* State for negotiating failed routes */
  private final List<Route> postponedRoutes;

  public RouteSelector(Address address, URI uri, ProxySelector proxySelector, ConnectionPool pool,
      Dns dns, RouteDatabase routeDatabase) {
    this.address = address;
    this.uri = uri;
    this.proxySelector = proxySelector;
    this.pool = pool;
    this.dns = dns;
    this.routeDatabase = routeDatabase;
    this.postponedRoutes = new LinkedList<Route>();

    resetNextProxy(uri, address.getProxy());
  }

  /**
   * Returns true if there's another route to attempt. Every address has at
   * least one route.
   */
  public boolean hasNext() {
    return hasNextTlsMode() || hasNextInetSocketAddress() || hasNextProxy() || hasNextPostponed();
  }

  /**
   * Returns the next route address to attempt.
   *
   * @throws NoSuchElementException if there are no more routes to attempt.
   */
  public Connection next(String method) throws IOException {
    // Always prefer pooled connections over new connections.
    for (Connection pooled; (pooled = pool.get(address)) != null; ) {
      if (method.equals("GET") || pooled.isReadable()) return pooled;
      pooled.close();
    }

    // Compute the next route to attempt.
    if (!hasNextTlsMode()) {
      if (!hasNextInetSocketAddress()) {
        if (!hasNextProxy()) {
          if (!hasNextPostponed()) {
            throw new NoSuchElementException();
          }
          return new Connection(nextPostponed());
        }
        lastProxy = nextProxy();
        resetNextInetSocketAddress(lastProxy);
      }
      lastInetSocketAddress = nextInetSocketAddress();
      resetNextTlsMode();
    }

    boolean modernTls = nextTlsMode() == TLS_MODE_MODERN;
    Route route = new Route(address, lastProxy, lastInetSocketAddress, modernTls);
    if (routeDatabase.shouldPostpone(route)) {
      postponedRoutes.add(route);
      // We will only recurse in order to skip previously failed routes. They will be
      // tried last.
      return next(method);
    }

    return new Connection(route);
  }

  /**
   * Clients should invoke this method when they encounter a connectivity
   * failure on a connection returned by this route selector.
   */
  public void connectFailed(Connection connection, IOException failure) {
    Route failedRoute = connection.getRoute();
    if (failedRoute.getProxy().type() != Proxy.Type.DIRECT && proxySelector != null) {
      // Tell the proxy selector when we fail to connect on a fresh connection.
      proxySelector.connectFailed(uri, failedRoute.getProxy().address(), failure);
    }

    routeDatabase.failed(failedRoute, failure);
  }

  /** Resets {@link #nextProxy} to the first option. */
  private void resetNextProxy(URI uri, Proxy proxy) {
    this.hasNextProxy = true; // This includes NO_PROXY!
    if (proxy != null) {
      this.userSpecifiedProxy = proxy;
    } else {
      List<Proxy> proxyList = proxySelector.select(uri);
      if (proxyList != null) {
        this.proxySelectorProxies = proxyList.iterator();
      }
    }
  }

  /** Returns true if there's another proxy to try. */
  private boolean hasNextProxy() {
    return hasNextProxy;
  }

  /** Returns the next proxy to try. May be PROXY.NO_PROXY but never null. */
  private Proxy nextProxy() {
    // If the user specifies a proxy, try that and only that.
    if (userSpecifiedProxy != null) {
      hasNextProxy = false;
      return userSpecifiedProxy;
    }

    // Try each of the ProxySelector choices until one connection succeeds. If none succeed
    // then we'll try a direct connection below.
    if (proxySelectorProxies != null) {
      while (proxySelectorProxies.hasNext()) {
        Proxy candidate = proxySelectorProxies.next();
        if (candidate.type() != Proxy.Type.DIRECT) {
          return candidate;
        }
      }
    }

    // Finally try a direct connection.
    hasNextProxy = false;
    return Proxy.NO_PROXY;
  }

  /** Resets {@link #nextInetSocketAddress} to the first option. */
  private void resetNextInetSocketAddress(Proxy proxy) throws UnknownHostException {
    socketAddresses = null; // Clear the addresses. Necessary if getAllByName() below throws!

    String socketHost;
    if (proxy.type() == Proxy.Type.DIRECT) {
      socketHost = uri.getHost();
      socketPort = getEffectivePort(uri);
    } else {
      SocketAddress proxyAddress = proxy.address();
      if (!(proxyAddress instanceof InetSocketAddress)) {
        throw new IllegalArgumentException(
            "Proxy.address() is not an " + "InetSocketAddress: " + proxyAddress.getClass());
      }
      InetSocketAddress proxySocketAddress = (InetSocketAddress) proxyAddress;
      socketHost = proxySocketAddress.getHostName();
      socketPort = proxySocketAddress.getPort();
    }

    // Try each address for best behavior in mixed IPv4/IPv6 environments.
    socketAddresses = dns.getAllByName(socketHost);
    nextSocketAddressIndex = 0;
  }

  /** Returns true if there's another socket address to try. */
  private boolean hasNextInetSocketAddress() {
    return socketAddresses != null;
  }

  /** Returns the next socket address to try. */
  private InetSocketAddress nextInetSocketAddress() throws UnknownHostException {
    InetSocketAddress result =
        new InetSocketAddress(socketAddresses[nextSocketAddressIndex++], socketPort);
    if (nextSocketAddressIndex == socketAddresses.length) {
      socketAddresses = null; // So that hasNextInetSocketAddress() returns false.
      nextSocketAddressIndex = 0;
    }

    return result;
  }

  /** Resets {@link #nextTlsMode} to the first option. */
  private void resetNextTlsMode() {
    nextTlsMode = (address.getSslSocketFactory() != null) ? TLS_MODE_MODERN : TLS_MODE_COMPATIBLE;
  }

  /** Returns true if there's another TLS mode to try. */
  private boolean hasNextTlsMode() {
    return nextTlsMode != TLS_MODE_NULL;
  }

  /** Returns the next TLS mode to try. */
  private int nextTlsMode() {
    if (nextTlsMode == TLS_MODE_MODERN) {
      nextTlsMode = TLS_MODE_COMPATIBLE;
      return TLS_MODE_MODERN;
    } else if (nextTlsMode == TLS_MODE_COMPATIBLE) {
      nextTlsMode = TLS_MODE_NULL;  // So that hasNextTlsMode() returns false.
      return TLS_MODE_COMPATIBLE;
    } else {
      throw new AssertionError();
    }
  }

  /** Returns true if there is another postponed route to try. */
  private boolean hasNextPostponed() {
    return !postponedRoutes.isEmpty();
  }

  /** Returns the next postponed route to try. */
  private Route nextPostponed() {
    return postponedRoutes.remove(0);
  }
}




Java Source Code List

com.phonegap.plugins.barcodescanner.BarcodeScanner.java
com.squareup.okhttp.Address.java
com.squareup.okhttp.ConnectionPool.java
com.squareup.okhttp.Connection.java
com.squareup.okhttp.Dispatcher.java
com.squareup.okhttp.Failure.java
com.squareup.okhttp.HttpResponseCache.java
com.squareup.okhttp.Job.java
com.squareup.okhttp.MediaType.java
com.squareup.okhttp.OkAuthenticator.java
com.squareup.okhttp.OkHttpClient.java
com.squareup.okhttp.OkResponseCache.java
com.squareup.okhttp.Request.java
com.squareup.okhttp.ResponseSource.java
com.squareup.okhttp.Response.java
com.squareup.okhttp.RouteDatabase.java
com.squareup.okhttp.Route.java
com.squareup.okhttp.TunnelRequest.java
com.squareup.okhttp.internal.AbstractOutputStream.java
com.squareup.okhttp.internal.Base64.java
com.squareup.okhttp.internal.DiskLruCache.java
com.squareup.okhttp.internal.Dns.java
com.squareup.okhttp.internal.FaultRecoveringOutputStream.java
com.squareup.okhttp.internal.NamedRunnable.java
com.squareup.okhttp.internal.Platform.java
com.squareup.okhttp.internal.StrictLineReader.java
com.squareup.okhttp.internal.Util.java
com.squareup.okhttp.internal.http.AbstractHttpInputStream.java
com.squareup.okhttp.internal.http.HeaderParser.java
com.squareup.okhttp.internal.http.HttpAuthenticator.java
com.squareup.okhttp.internal.http.HttpDate.java
com.squareup.okhttp.internal.http.HttpEngine.java
com.squareup.okhttp.internal.http.HttpTransport.java
com.squareup.okhttp.internal.http.HttpURLConnectionImpl.java
com.squareup.okhttp.internal.http.HttpsEngine.java
com.squareup.okhttp.internal.http.HttpsURLConnectionImpl.java
com.squareup.okhttp.internal.http.OkResponseCacheAdapter.java
com.squareup.okhttp.internal.http.Policy.java
com.squareup.okhttp.internal.http.RawHeaders.java
com.squareup.okhttp.internal.http.RequestHeaders.java
com.squareup.okhttp.internal.http.ResponseHeaders.java
com.squareup.okhttp.internal.http.RetryableOutputStream.java
com.squareup.okhttp.internal.http.RouteSelector.java
com.squareup.okhttp.internal.http.SpdyTransport.java
com.squareup.okhttp.internal.http.Transport.java
com.squareup.okhttp.internal.http.UnknownLengthHttpInputStream.java
com.squareup.okhttp.internal.spdy.ErrorCode.java
com.squareup.okhttp.internal.spdy.FrameReader.java
com.squareup.okhttp.internal.spdy.FrameWriter.java
com.squareup.okhttp.internal.spdy.HeadersMode.java
com.squareup.okhttp.internal.spdy.Hpack.java
com.squareup.okhttp.internal.spdy.Http20Draft06.java
com.squareup.okhttp.internal.spdy.IncomingStreamHandler.java
com.squareup.okhttp.internal.spdy.NameValueBlockReader.java
com.squareup.okhttp.internal.spdy.Ping.java
com.squareup.okhttp.internal.spdy.Settings.java
com.squareup.okhttp.internal.spdy.Spdy3.java
com.squareup.okhttp.internal.spdy.SpdyConnection.java
com.squareup.okhttp.internal.spdy.SpdyStream.java
com.squareup.okhttp.internal.spdy.Variant.java
com.squareup.okhttp.internal.tls.DistinguishedNameParser.java
com.squareup.okhttp.internal.tls.OkHostnameVerifier.java
org.apache.cordova.App.java
org.apache.cordova.AuthenticationToken.java
org.apache.cordova.CallbackContext.java
org.apache.cordova.ConfigXmlParser.java
org.apache.cordova.Config.java
org.apache.cordova.CordovaActivity.java
org.apache.cordova.CordovaArgs.java
org.apache.cordova.CordovaBridge.java
org.apache.cordova.CordovaChromeClient.java
org.apache.cordova.CordovaInterface.java
org.apache.cordova.CordovaPlugin.java
org.apache.cordova.CordovaPreferences.java
org.apache.cordova.CordovaResourceApi.java
org.apache.cordova.CordovaUriHelper.java
org.apache.cordova.CordovaWebViewClient.java
org.apache.cordova.CordovaWebView.java
org.apache.cordova.DirectoryManager.java
org.apache.cordova.DroidGap.java
org.apache.cordova.ExifHelper.java
org.apache.cordova.ExposedJsApi.java
org.apache.cordova.FileHelper.java
org.apache.cordova.IceCreamCordovaWebViewClient.java
org.apache.cordova.JSONUtils.java
org.apache.cordova.LOG.java
org.apache.cordova.LinearLayoutSoftKeyboardDetect.java
org.apache.cordova.NativeToJsMessageQueue.java
org.apache.cordova.PluginEntry.java
org.apache.cordova.PluginManager.java
org.apache.cordova.PluginResult.java
org.apache.cordova.ScrollEvent.java
org.apache.cordova.Whitelist.java
org.opensharingtoolkit.cordova.aestheticodes.Scan.java
org.opensharingtoolkit.cordova.aestheticodes.Scan.java
org.opensharingtoolkit.player.CordovaApp.java