示例#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
  public Route next() throws IOException {
    // Compute the next route to attempt.
    if (!hasNextConnectionSpec()) {
      if (!hasNextInetSocketAddress()) {
        if (!hasNextProxy()) {
          if (!hasNextPostponed()) {
            throw new NoSuchElementException();
          }
          return nextPostponed();
        }
        lastProxy = nextProxy();
      }
      lastInetSocketAddress = nextInetSocketAddress();
    }
    lastSpec = nextConnectionSpec();

    final boolean shouldSendTlsFallbackIndicator = shouldSendTlsFallbackIndicator(lastSpec);
    Route route =
        new Route(
            address, lastProxy, lastInetSocketAddress, lastSpec, shouldSendTlsFallbackIndicator);
    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();
    }

    return route;
  }
示例#3
0
  /**
   * Returns the next connection to attempt.
   *
   * @throws NoSuchElementException if there are no more routes to attempt.
   */
  Connection nextUnconnected() throws IOException {
    // Always prefer pooled connections over new connections.
    for (Connection pooled; (pooled = pool.get(address)) != null; ) {
      if (request.method().equals("GET") || Internal.instance.isReadable(pooled)) return pooled;
      pooled.getSocket().close();
    }

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

    String tlsVersion = nextTlsVersion();
    Route route = new Route(address, lastProxy, lastInetSocketAddress, tlsVersion);
    if (routeDatabase.shouldPostpone(route)) {
      postponedRoutes.add(route);
      // We will only recurse in order to skip previously failed routes. They will be
      // tried last.
      return nextUnconnected();
    }

    return new Connection(pool, route);
  }
示例#4
0
  /**
   * 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) {
    // If this is a recycled connection, don't count its failure against the route.
    if (Internal.instance.recycleCount(connection) > 0) return;

    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);

    // If the previously returned route's problem was not related to TLS, and
    // the next route only changes the TLS mode, 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 (hasNextTlsVersion()) {
        Route toSuppress = new Route(address, lastProxy, lastInetSocketAddress, nextTlsVersion());
        routeDatabase.failed(toSuppress);
      }
    }
  }