/** * Report and attempt to recover from {@code e}. Returns true if the HTTP engine was replaced and * the request should be retried. Otherwise the failure is permanent. */ private boolean handleFailure(IOException e) throws IOException { RouteSelector routeSelector = httpEngine.routeSelector; if (routeSelector != null && httpEngine.connection != null) { routeSelector.connectFailed(httpEngine.connection, e); } OutputStream requestBody = httpEngine.getRequestBody(); boolean canRetryRequestBody = requestBody == null || requestBody instanceof RetryableOutputStream || (faultRecoveringRequestBody != null && faultRecoveringRequestBody.isRecoverable()); if (routeSelector == null && httpEngine.connection == null // No connection. || routeSelector != null && !routeSelector.hasNext() // No more routes to attempt. || !isRecoverable(e) || !canRetryRequestBody) { httpEngineFailure = e; return false; } httpEngine.release(true); RetryableOutputStream retryableOutputStream = requestBody instanceof RetryableOutputStream ? (RetryableOutputStream) requestBody : null; httpEngine = newHttpEngine(method, rawRequestHeaders, null, retryableOutputStream); httpEngine.routeSelector = routeSelector; // Keep the same routeSelector. if (faultRecoveringRequestBody != null && faultRecoveringRequestBody.isRecoverable()) { httpEngine.sendRequest(); faultRecoveringRequestBody.replaceStream(httpEngine.getRequestBody()); } return true; }
private void connectFailed(RouteSelector routeselector, IOException ioexception) { if (Internal.instance.recycleCount(connection) > 0) { return; } else { routeselector.connectFailed(connection.getRoute(), ioexception); return; } }