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 191368ccf..579da94a0 100644 --- a/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java +++ b/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java @@ -684,4 +684,11 @@ public class HttpEngine { protected TunnelRequest getTunnelConfig() { return null; } + + public void receiveHeaders(RawHeaders headers) throws IOException { + CookieHandler cookieHandler = policy.cookieHandler; + if (cookieHandler != null) { + cookieHandler.put(uri, headers.toMultimap(true)); + } + } } diff --git a/src/main/java/com/squareup/okhttp/internal/http/HttpTransport.java b/src/main/java/com/squareup/okhttp/internal/http/HttpTransport.java index adeb0c2b3..eb72a25e8 100644 --- a/src/main/java/com/squareup/okhttp/internal/http/HttpTransport.java +++ b/src/main/java/com/squareup/okhttp/internal/http/HttpTransport.java @@ -25,7 +25,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.CacheRequest; -import java.net.CookieHandler; import java.net.ProtocolException; import java.net.Socket; @@ -144,17 +143,10 @@ public final class HttpTransport implements Transport { @Override public ResponseHeaders readResponseHeaders() throws IOException { RawHeaders headers = RawHeaders.fromBytes(socketIn); httpEngine.connection.setHttpMinorVersion(headers.getHttpMinorVersion()); - receiveHeaders(headers); + httpEngine.receiveHeaders(headers); return new ResponseHeaders(httpEngine.uri, headers); } - private void receiveHeaders(RawHeaders headers) throws IOException { - CookieHandler cookieHandler = httpEngine.policy.cookieHandler; - if (cookieHandler != null) { - cookieHandler.put(httpEngine.uri, headers.toMultimap(true)); - } - } - public boolean makeReusable(boolean streamCancelled, OutputStream requestBodyOut, InputStream responseBodyIn) { if (streamCancelled) { @@ -491,7 +483,7 @@ public final class HttpTransport implements Transport { hasMoreChunks = false; RawHeaders rawResponseHeaders = httpEngine.responseHeaders.getHeaders(); RawHeaders.readHeaders(transport.socketIn, rawResponseHeaders); - transport.receiveHeaders(rawResponseHeaders); + httpEngine.receiveHeaders(rawResponseHeaders); endOfInput(false); } } diff --git a/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java b/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java index 7ff1dfe93..d96e9298c 100644 --- a/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java +++ b/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java @@ -30,8 +30,6 @@ public final class SpdyTransport implements Transport { private final SpdyConnection spdyConnection; private SpdyStream stream; - // TODO: set cookie stuff - public SpdyTransport(HttpEngine httpEngine, SpdyConnection spdyConnection) { this.httpEngine = httpEngine; this.spdyConnection = spdyConnection; @@ -72,6 +70,7 @@ public final class SpdyTransport implements Transport { List nameValueBlock = stream.getResponseHeaders(); RawHeaders rawHeaders = RawHeaders.fromNameValueBlock(nameValueBlock); rawHeaders.computeResponseStatusLineFromSpdyHeaders(); + httpEngine.receiveHeaders(rawHeaders); return new ResponseHeaders(httpEngine.uri, rawHeaders); } diff --git a/src/test/java/com/squareup/okhttp/internal/mockspdyserver/MockSpdyServer.java b/src/test/java/com/squareup/okhttp/internal/mockspdyserver/MockSpdyServer.java index 39a774f86..5380c56b8 100644 --- a/src/test/java/com/squareup/okhttp/internal/mockspdyserver/MockSpdyServer.java +++ b/src/test/java/com/squareup/okhttp/internal/mockspdyserver/MockSpdyServer.java @@ -92,6 +92,16 @@ public final class MockSpdyServer { } } + /** + * Returns a cookie domain for this server. This returns the server's + * non-loopback host name if it is known. Otherwise this returns ".local" + * for this server's loopback name. + */ + public String getCookieDomain() { + String hostName = getHostName(); + return hostName.contains(".") ? hostName : ".local"; + } + /** * Awaits the next HTTP request, removes it, and returns it. Callers should * use this to verify the request sent was as intended. diff --git a/src/test/java/com/squareup/okhttp/internal/spdy/HttpOverSpdyTest.java b/src/test/java/com/squareup/okhttp/internal/spdy/HttpOverSpdyTest.java index acbdb9845..ced89c8d7 100644 --- a/src/test/java/com/squareup/okhttp/internal/spdy/HttpOverSpdyTest.java +++ b/src/test/java/com/squareup/okhttp/internal/spdy/HttpOverSpdyTest.java @@ -29,13 +29,18 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Authenticator; +import java.net.CookieManager; import java.net.HttpURLConnection; import java.net.InetAddress; +import java.net.URL; import java.net.URLConnection; import java.net.UnknownHostException; import java.security.GeneralSecurityException; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.zip.GZIPOutputStream; import javax.net.ssl.HostnameVerifier; @@ -99,6 +104,29 @@ public final class HttpOverSpdyTest { assertContains(request.getHeaders(), ":host: " + hostName + ":" + server.getPort()); } + @Test public void emptyResponse() throws IOException { + server.enqueue(new MockResponse()); + server.play(); + + HttpURLConnection connection = client.open(server.getUrl("/foo")); + assertEquals(-1, connection.getInputStream().read()); + } + + @Test public void post() throws Exception { + MockResponse response = new MockResponse().setBody("ABCDE"); + server.enqueue(response); + server.play(); + + HttpURLConnection connection = client.open(server.getUrl("/foo")); + connection.setDoOutput(true); + connection.getOutputStream().write("FGHIJ".getBytes(Util.UTF_8)); + assertContent("ABCDE", connection, Integer.MAX_VALUE); + + RecordedRequest request = server.takeRequest(); + assertEquals("POST /foo HTTP/1.1", request.getRequestLine()); + assertEquals("FGHIJ", request.getUtf8Body()); + } + @Test public void spdyConnectionReuse() throws Exception { server.enqueue(new MockResponse().setBody("ABCDEF")); server.enqueue(new MockResponse().setBody("GHIJKL")); @@ -189,6 +217,28 @@ public final class HttpOverSpdyTest { assertEquals(2, cache.getHitCount()); } + @Test public void acceptAndTransmitCookies() throws Exception { + CookieManager cookieManager = new CookieManager(); + client.setCookieHandler(cookieManager); + server.enqueue(new MockResponse() + .addHeader("set-cookie: c=oreo; domain=" + server.getCookieDomain()) + .setBody("A")); + server.enqueue(new MockResponse().setBody("B")); + server.play(); + + URL url = server.getUrl("/"); + assertContent("A", client.open(url), Integer.MAX_VALUE); + Map> requestHeaders = Collections.emptyMap(); + assertEquals(Collections.singletonMap("Cookie", Arrays.asList("c=oreo")), + cookieManager.get(url.toURI(), requestHeaders)); + + assertContent("B", client.open(url), Integer.MAX_VALUE); + RecordedRequest requestA = server.takeRequest(); + assertContainsNoneMatching(requestA.getHeaders(), "Cookie.*"); + RecordedRequest requestB = server.takeRequest(); + assertContains(requestB.getHeaders(), "cookie: c=oreo"); + } + private void assertContains(Collection collection, T value) { assertTrue(collection.toString(), collection.contains(value)); }