/** * Returns the retry action to take for the current response headers. The headers, proxy and * target URL for this connection may be adjusted to prepare for a follow up request. */ private Retry processResponseHeaders() throws IOException { Proxy selectedProxy = httpEngine.connection != null ? httpEngine.connection.getRoute().getProxy() : client.getProxy(); final int responseCode = getResponseCode(); switch (responseCode) { case HTTP_PROXY_AUTH: if (selectedProxy.type() != Proxy.Type.HTTP) { throw new ProtocolException("Received HTTP_PROXY_AUTH (407) code while not using proxy"); } // fall-through case HTTP_UNAUTHORIZED: Request successorRequest = HttpAuthenticator.processAuthHeader( client.getAuthenticator(), httpEngine.getResponse(), selectedProxy); if (successorRequest == null) return Retry.NONE; requestHeaders = successorRequest.getHeaders().newBuilder(); return Retry.SAME_CONNECTION; case HTTP_MULT_CHOICE: case HTTP_MOVED_PERM: case HTTP_MOVED_TEMP: case HTTP_SEE_OTHER: case HTTP_TEMP_REDIRECT: if (!getInstanceFollowRedirects()) { return Retry.NONE; } if (++redirectionCount > MAX_REDIRECTS) { throw new ProtocolException("Too many redirects: " + redirectionCount); } if (responseCode == HTTP_TEMP_REDIRECT && !method.equals("GET") && !method.equals("HEAD")) { // "If the 307 status code is received in response to a request other than GET or HEAD, // the user agent MUST NOT automatically redirect the request" return Retry.NONE; } String location = getHeaderField("Location"); if (location == null) { return Retry.NONE; } URL previousUrl = url; url = new URL(previousUrl, location); if (!url.getProtocol().equals("https") && !url.getProtocol().equals("http")) { return Retry.NONE; // Don't follow redirects to unsupported protocols. } boolean sameProtocol = previousUrl.getProtocol().equals(url.getProtocol()); if (!sameProtocol && !client.getFollowProtocolRedirects()) { return Retry.NONE; // This client doesn't follow redirects across protocols. } boolean sameHost = previousUrl.getHost().equals(url.getHost()); boolean samePort = getEffectivePort(previousUrl) == getEffectivePort(url); if (sameHost && samePort && sameProtocol) { return Retry.SAME_CONNECTION; } else { return Retry.DIFFERENT_CONNECTION; } default: return Retry.NONE; } }