/** * 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); } } }
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; }
/** * 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); }
/** * 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); } } }