From 637783ce8ae3ffb9805c2f78b436703c29b2220a Mon Sep 17 00:00:00 2001 From: jwilson Date: Thu, 31 Jan 2013 00:05:20 -0500 Subject: [PATCH] Retry if a request fails after a redirect. https://code.google.com/p/android/issues/detail?id=41576 --- .../internal/http/HttpURLConnectionImpl.java | 11 +++++++---- .../internal/http/URLConnectionTest.java | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java b/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java index a03ef6965..48ca592fb 100644 --- a/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java +++ b/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java @@ -326,6 +326,8 @@ public class HttpURLConnectionImpl extends HttpURLConnection { if (retry == Retry.DIFFERENT_CONNECTION) { httpEngine.automaticallyReleaseConnectionToPool(); + } else if (retry == Retry.SAME_CONNECTION && httpEngine.getConnection() != null) { + httpEngine.getConnection().setRecycled(); } httpEngine.release(false); @@ -349,15 +351,16 @@ public class HttpURLConnectionImpl extends HttpURLConnection { return true; } catch (IOException e) { RouteSelector routeSelector = httpEngine.routeSelector; - if (routeSelector == null) { - throw e; // Without a route selector, we can't retry. - } else if (httpEngine.connection != null) { + if (routeSelector != null && httpEngine.connection != null) { routeSelector.connectFailed(httpEngine.connection, e); } + if (routeSelector == null && httpEngine.connection == null) { + throw e; // If we failed before finding a route or a connection, give up. + } // The connection failure isn't fatal if there's another route to attempt. OutputStream requestBody = httpEngine.getRequestBody(); - if (routeSelector.hasNext() && isRecoverable(e) + if ((routeSelector == null || routeSelector.hasNext()) && isRecoverable(e) && (requestBody == null || requestBody instanceof RetryableOutputStream)) { httpEngine.release(true); httpEngine = newHttpEngine(method, rawRequestHeaders, null, diff --git a/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java b/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java index d91a2432e..71008e213 100644 --- a/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java +++ b/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java @@ -1794,6 +1794,24 @@ public final class URLConnectionTest { 0, server.takeRequest().getSequenceNumber()); } + /** + * Retry redirects if the socket is closed. + * https://code.google.com/p/android/issues/detail?id=41576 + */ + @Test public void sameConnectionRedirectAndReuse() throws Exception { + server.enqueue(new MockResponse() + .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP) + .setSocketPolicy(SHUTDOWN_INPUT_AT_END) + .addHeader("Location: /foo")); + server.enqueue(new MockResponse().setBody("This is the new page!")); + server.play(); + + assertContent("This is the new page!", client.open(server.getUrl("/"))); + + assertEquals(0, server.takeRequest().getSequenceNumber()); + assertEquals(0, server.takeRequest().getSequenceNumber()); + } + @Test public void responseCodeDisagreesWithHeaders() throws IOException, InterruptedException { server.enqueue(new MockResponse() .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)