diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java index 214f25add..c615a87cc 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java @@ -331,6 +331,11 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy { httpEngine = newHttpEngine(retryMethod, rawRequestHeaders, httpEngine.getConnection(), (RetryableOutputStream) requestBody); + + if (requestBody == null) { + // Drop the Content-Length header when redirected from POST to GET. + httpEngine.getRequestHeaders().removeContentLength(); + } } } diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/RequestHeaders.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/RequestHeaders.java index d5e3bd86d..69311537a 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/RequestHeaders.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/RequestHeaders.java @@ -213,6 +213,18 @@ public final class RequestHeaders { this.contentLength = contentLength; } + /** + * Remove the Content-Length headers. Call this when dropping the body on a + * request or response, such as when a redirect changes the method from POST + * to GET. + */ + public void removeContentLength() { + if (contentLength != -1) { + headers.removeAll("Content-Length"); + contentLength = -1; + } + } + public void setUserAgent(String userAgent) { if (this.userAgent != null) { headers.removeAll("User-Agent"); diff --git a/okhttp/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java b/okhttp/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java index f59df39c3..06918bdb6 100644 --- a/okhttp/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java +++ b/okhttp/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java @@ -1722,6 +1722,32 @@ public final class URLConnectionTest { assertEquals("GET /page2 HTTP/1.1", page2.getRequestLine()); } + @Test public void redirectedPostStripsRequestBodyHeaders() throws Exception { + server.enqueue(new MockResponse() + .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP) + .addHeader("Location: /page2")); + server.enqueue(new MockResponse().setBody("Page 2")); + server.play(); + + HttpURLConnection connection = client.open(server.getUrl("/page1")); + connection.setDoOutput(true); + connection.addRequestProperty("Content-Length", "4"); + connection.addRequestProperty("Content-Type", "text/plain; charset=utf-8"); + connection.addRequestProperty("Transfer-Encoding", "identity"); + OutputStream outputStream = connection.getOutputStream(); + outputStream.write("ABCD".getBytes("UTF-8")); + outputStream.close(); + assertEquals("Page 2", readAscii(connection.getInputStream(), Integer.MAX_VALUE)); + + assertEquals("POST /page1 HTTP/1.1", server.takeRequest().getRequestLine()); + + RecordedRequest page2 = server.takeRequest(); + assertEquals("GET /page2 HTTP/1.1", page2.getRequestLine()); + assertContainsNoneMatching(page2.getHeaders(), "Content-Length"); + assertContains(page2.getHeaders(), "Content-Type: text/plain; charset=utf-8"); + assertContains(page2.getHeaders(), "Transfer-Encoding: identity"); + } + @Test public void response305UseProxy() throws Exception { server.play(); server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_USE_PROXY)