From 92fcceedf58e191d8e9decb53302491a942f56e9 Mon Sep 17 00:00:00 2001 From: jwilson Date: Fri, 1 Feb 2013 10:06:59 -0500 Subject: [PATCH] Merge: Strip content length in requests with "transparent" gzip handling Original AOSP/libcore commit from Brian Carlstrom: We need to strip both the Content-Length and the Content-Encoding for such requests. In such requests, it will be the length of the compressed response. We hide the fact that compression is taking place from clients, so we shouldn't give them the content length either. Change-Id: I80713ab33143945c5e2656f478d83cc9e60226a8 --- .../squareup/okhttp/internal/http/HttpEngine.java | 14 ++++++++++---- .../okhttp/internal/http/ResponseHeaders.java | 5 +++++ .../okhttp/internal/http/URLConnectionTest.java | 6 +++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java b/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java index 0b1deb66b..e93a350d9 100644 --- a/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java +++ b/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java @@ -447,11 +447,17 @@ public class HttpEngine { private void initContentStream(InputStream transferStream) throws IOException { responseTransferIn = transferStream; if (transparentGzip && responseHeaders.isContentEncodingGzip()) { - /* - * If the response was transparently gzipped, remove the gzip header field - * so clients don't double decompress. http://b/3009828 - */ + /* + * If the response was transparently gzipped, remove the gzip header field + * so clients don't double decompress. http://b/3009828 + * + * Also remove the Content-Length in this case because it contains the + * length 528 of the gzipped response. This isn't terribly useful and is + * dangerous because 529 clients can query the content length, but not + * the content encoding. + */ responseHeaders.stripContentEncoding(); + responseHeaders.stripContentLength(); responseBodyIn = new GZIPInputStream(transferStream); } else { responseBodyIn = transferStream; diff --git a/src/main/java/com/squareup/okhttp/internal/http/ResponseHeaders.java b/src/main/java/com/squareup/okhttp/internal/http/ResponseHeaders.java index 25288995c..4558fa97f 100644 --- a/src/main/java/com/squareup/okhttp/internal/http/ResponseHeaders.java +++ b/src/main/java/com/squareup/okhttp/internal/http/ResponseHeaders.java @@ -187,6 +187,11 @@ final class ResponseHeaders { headers.removeAll("Content-Encoding"); } + public void stripContentLength() { + contentLength = -1; + headers.removeAll("Content-Length"); + } + public boolean isChunked() { return "chunked".equalsIgnoreCase(transferEncoding); } 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 ee702f3b9..8be5edb06 100644 --- a/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java +++ b/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java @@ -1016,13 +1016,16 @@ public final class URLConnectionTest { URLConnection connection = client.open(server.getUrl("/")); assertEquals("ABCABCABC", readAscii(connection.getInputStream(), Integer.MAX_VALUE)); assertNull(connection.getContentEncoding()); + assertEquals(-1, connection.getContentLength()); RecordedRequest request = server.takeRequest(); assertContains(request.getHeaders(), "Accept-Encoding: gzip"); } @Test public void clientConfiguredGzipContentEncoding() throws Exception { - server.enqueue(new MockResponse().setBody(gzip("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes("UTF-8"))) + byte[] bodyBytes = gzip("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes("UTF-8")); + server.enqueue(new MockResponse() + .setBody(bodyBytes) .addHeader("Content-Encoding: gzip")); server.play(); @@ -1030,6 +1033,7 @@ public final class URLConnectionTest { connection.addRequestProperty("Accept-Encoding", "gzip"); InputStream gunzippedIn = new GZIPInputStream(connection.getInputStream()); assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZ", readAscii(gunzippedIn, Integer.MAX_VALUE)); + assertEquals(bodyBytes.length, connection.getContentLength()); RecordedRequest request = server.takeRequest(); assertContains(request.getHeaders(), "Accept-Encoding: gzip");