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

    routeDatabase.failed(failedRoute);

    // If the previously returned route's problem was not related to the connection's spec, and the
    // next route only changes that, we shouldn't even attempt it. This suppresses it in both this
    // selector and also in the route database.
    if (!(failure instanceof SSLHandshakeException) && !(failure instanceof SSLProtocolException)) {
      while (nextSpecIndex < connectionSpecs.size()) {
        ConnectionSpec connectionSpec = connectionSpecs.get(nextSpecIndex++);
        final boolean shouldSendTlsFallbackIndicator =
            shouldSendTlsFallbackIndicator(connectionSpec);
        Route toSuppress =
            new Route(
                address,
                lastProxy,
                lastInetSocketAddress,
                connectionSpec,
                shouldSendTlsFallbackIndicator);
        routeDatabase.failed(toSuppress);
      }
    }
  }
예제 #2
0
  /** Prepares the socket addresses to attempt for the current proxy or host. */
  private void resetNextInetSocketAddress(Proxy proxy) throws UnknownHostException {
    // Clear the addresses. Necessary if getAllByName() below throws!
    inetSocketAddresses = new ArrayList<>();

    String socketHost;
    int socketPort;
    if (proxy.type() == Proxy.Type.DIRECT || proxy.type() == Proxy.Type.SOCKS) {
      socketHost = address.getUriHost();
      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 = getHostString(proxySocketAddress);
      socketPort = proxySocketAddress.getPort();
    }

    // Try each address for best behavior in mixed IPv4/IPv6 environments.
    for (InetAddress inetAddress : network.resolveInetAddresses(socketHost)) {
      inetSocketAddresses.add(new InetSocketAddress(inetAddress, socketPort));
    }
    nextInetSocketAddressIndex = 0;
  }
예제 #3
0
 /** Returns the next proxy to try. May be PROXY.NO_PROXY but never null. */
 private Proxy nextProxy() throws IOException {
   if (!hasNextProxy()) {
     throw new SocketException(
         "No route to " + address.getUriHost() + "; exhausted proxy configurations: " + proxies);
   }
   Proxy result = proxies.get(nextProxyIndex++);
   resetNextInetSocketAddress(result);
   return result;
 }
예제 #4
0
  private RouteSelector(Address address, URI uri, OkHttpClient client, Request request) {
    this.address = address;
    this.uri = uri;
    this.client = client;
    this.routeDatabase = Internal.instance.routeDatabase(client);
    this.network = Internal.instance.network(client);
    this.request = request;

    resetNextProxy(uri, address.getProxy());
  }
예제 #5
0
 /** Returns the next connection spec to try. */
 private ConnectionSpec nextConnectionSpec() throws IOException {
   if (!hasNextConnectionSpec()) {
     throw new SocketException(
         "No route to "
             + address.getUriHost()
             + "; exhausted connection specs: "
             + connectionSpecs);
   }
   return connectionSpecs.get(nextSpecIndex++);
 }
예제 #6
0
 /** Prepares the connection specs to attempt. */
 private void resetConnectionSpecs() {
   connectionSpecs = new ArrayList<>();
   List<ConnectionSpec> specs = address.getConnectionSpecs();
   for (int i = 0, size = specs.size(); i < size; i++) {
     ConnectionSpec spec = specs.get(i);
     if (request.isHttps() == spec.isTls()) {
       connectionSpecs.add(spec);
     }
   }
   nextSpecIndex = 0;
 }
예제 #7
0
 /** Returns the next socket address to try. */
 private InetSocketAddress nextInetSocketAddress() throws IOException {
   if (!hasNextInetSocketAddress()) {
     throw new SocketException(
         "No route to "
             + address.getUriHost()
             + "; exhausted inet socket addresses: "
             + inetSocketAddresses);
   }
   InetSocketAddress result = inetSocketAddresses.get(nextInetSocketAddressIndex++);
   resetConnectionSpecs();
   return result;
 }