diff options
author | Neil Fuller <nfuller@google.com> | 2015-08-12 10:02:58 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-08-12 10:02:58 +0000 |
commit | b60e2bef2393eefa097d3d57fddcbb44e82fbafa (patch) | |
tree | cf6b0abccb56ce7c2e1324c12f9e27e70c35d49d | |
parent | 6e8291186b056301ecb1ce0d17bc116fd77ad769 (diff) | |
parent | 99189120cb4444cc196251961234ed8642534644 (diff) | |
download | okhttp-lollipop-mr1-cts-release.tar.gz |
am 99189120: Merge "Revert "Revert "Add further handling for when a CONNECT incorrectly returns a body.""" into lollipop-mr1-cts-devandroid-cts-5.1_r9android-cts-5.1_r8android-cts-5.1_r7android-cts-5.1_r6android-cts-5.1_r5android-cts-5.1_r4android-cts-5.1_r3android-cts-5.1_r28android-cts-5.1_r27android-cts-5.1_r26android-cts-5.1_r25android-cts-5.1_r24android-cts-5.1_r23android-cts-5.1_r22android-cts-5.1_r21android-cts-5.1_r20android-cts-5.1_r19android-cts-5.1_r18android-cts-5.1_r17android-cts-5.1_r16android-cts-5.1_r15android-cts-5.1_r14android-cts-5.1_r13android-cts-5.1_r10lollipop-mr1-cts-releaselollipop-mr1-cts-dev
* commit '99189120cb4444cc196251961234ed8642534644':
Revert "Revert "Add further handling for when a CONNECT incorrectly returns a body.""
-rw-r--r-- | okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java | 33 | ||||
-rw-r--r-- | okhttp/src/main/java/com/squareup/okhttp/Connection.java | 16 |
2 files changed, 48 insertions, 1 deletions
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java index 0961c3d..0fcc4bd 100644 --- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java +++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java @@ -2961,6 +2961,39 @@ public final class URLConnectionTest { } /** + * Tolerate bad https proxy response when using HttpResponseCache. Android bug 6754912. + */ + @Test + public void testConnectViaHttpProxyToHttpsUsingBadProxyAndHttpResponseCache() throws Exception { + initResponseCache(); + + server.useHttps(sslContext.getSocketFactory(), true); + // The inclusion of a body in the response to a CONNECT is key to reproducing b/6754912. + MockResponse + badProxyResponse = new MockResponse() + .setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END) + .clearHeaders() + .setBody("bogus proxy connect response content"); + + server.enqueue(badProxyResponse); + server.enqueue(new MockResponse().setBody("response")); + + server.play(); + + URL url = new URL("https://android.com/foo"); + client.setSslSocketFactory(sslContext.getSocketFactory()); + client.setHostnameVerifier(new RecordingHostnameVerifier()); + + ProxyConfig proxyConfig = ProxyConfig.PROXY_SYSTEM_PROPERTY; + HttpsURLConnection connection = (HttpsURLConnection) proxyConfig.connect(server, client, url); + assertContent("response", connection); + + RecordedRequest connect = server.takeRequest(); + assertEquals("CONNECT android.com:443 HTTP/1.1", connect.getRequestLine()); + assertContains(connect.getHeaders(), "Host: android.com"); + } + + /** * The RFC is unclear in this regard as it only specifies that this should * invalidate the cache entry (if any). */ diff --git a/okhttp/src/main/java/com/squareup/okhttp/Connection.java b/okhttp/src/main/java/com/squareup/okhttp/Connection.java index 94527af..743c33b 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/Connection.java +++ b/okhttp/src/main/java/com/squareup/okhttp/Connection.java @@ -17,10 +17,12 @@ package com.squareup.okhttp; import com.squareup.okhttp.internal.Platform; +import com.squareup.okhttp.internal.Util; import com.squareup.okhttp.internal.http.HttpAuthenticator; import com.squareup.okhttp.internal.http.HttpConnection; import com.squareup.okhttp.internal.http.HttpEngine; import com.squareup.okhttp.internal.http.HttpTransport; +import com.squareup.okhttp.internal.http.OkHeaders; import com.squareup.okhttp.internal.http.SpdyTransport; import com.squareup.okhttp.internal.spdy.SpdyConnection; import java.io.Closeable; @@ -29,6 +31,8 @@ import java.net.Proxy; import java.net.Socket; import javax.net.ssl.SSLSocket; import okio.ByteString; +import okio.OkBuffer; +import okio.Source; import static java.net.HttpURLConnection.HTTP_OK; import static java.net.HttpURLConnection.HTTP_PROXY_AUTH; @@ -353,12 +357,22 @@ public final class Connection implements Closeable { tunnelConnection.writeRequest(request.headers(), requestLine); tunnelConnection.flush(); Response response = tunnelConnection.readResponse().request(request).build(); - tunnelConnection.emptyResponseBody(); + // The response body from a CONNECT should be empty, but if it is not then we should consume + // it before proceeding. + long contentLength = OkHeaders.contentLength(response); + if (contentLength != -1) { + Source body = tunnelConnection.newFixedLengthSource(null, contentLength); + Util.skipAll(body, Integer.MAX_VALUE); + } else { + tunnelConnection.emptyResponseBody(); + } switch (response.code()) { case HTTP_OK: // Assume the server won't send a TLS ServerHello until we send a TLS ClientHello. If that // happens, then we will have buffered bytes that are needed by the SSLSocket! + // This check is imperfect: it doesn't tell us whether a handshake will succeed, just that + // it will almost certainly fail because the proxy has sent unexpected data. if (tunnelConnection.bufferSize() > 0) { throw new IOException("TLS tunnel buffered too many bytes!"); } |