From af5e60af84da628125b6fa832bdb45093c4bba71 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sat, 7 Dec 2013 12:16:34 -0800 Subject: [PATCH] issue #364: spdy should set content-length when it is known. --- .../okhttp/internal/http/SpdyTransport.java | 4 ++ .../internal/http/HttpOverSpdyTest.java | 46 +++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java index fce58f474..471539a46 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java @@ -37,6 +37,10 @@ public final class SpdyTransport implements Transport { } @Override public OutputStream createRequestBody() throws IOException { + long fixedContentLength = httpEngine.policy.getFixedContentLength(); + if (fixedContentLength != -1) { + httpEngine.requestHeaders.setContentLength(fixedContentLength); + } // TODO: if we aren't streaming up to the server, we should buffer the whole request writeRequestHeaders(); return stream.getOutputStream(); diff --git a/okhttp/src/test/java/com/squareup/okhttp/internal/http/HttpOverSpdyTest.java b/okhttp/src/test/java/com/squareup/okhttp/internal/http/HttpOverSpdyTest.java index 7720c5b61..822412a06 100644 --- a/okhttp/src/test/java/com/squareup/okhttp/internal/http/HttpOverSpdyTest.java +++ b/okhttp/src/test/java/com/squareup/okhttp/internal/http/HttpOverSpdyTest.java @@ -50,7 +50,9 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -115,19 +117,57 @@ public final class HttpOverSpdyTest { assertEquals(-1, connection.getInputStream().read()); } - @Test public void post() throws Exception { + byte[] postBytes = "FGHIJ".getBytes(Util.UTF_8); + + /** An output stream can be written to more than once, so we can't guess content length. */ + @Test public void noDefaultContentLengthOnPost() 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)); + connection.getOutputStream().write(postBytes); assertContent("ABCDE", connection, Integer.MAX_VALUE); RecordedRequest request = server.takeRequest(); assertEquals("POST /foo HTTP/1.1", request.getRequestLine()); - assertEquals("FGHIJ", request.getUtf8Body()); + assertArrayEquals(postBytes, request.getBody()); + assertNull(request.getHeader("Content-Length")); + } + + @Test public void userSuppliedContentLengthHeader() throws Exception { + MockResponse response = new MockResponse().setBody("ABCDE"); + server.enqueue(response); + server.play(); + + HttpURLConnection connection = client.open(server.getUrl("/foo")); + connection.setRequestProperty("Content-Length", String.valueOf(postBytes.length)); + connection.setDoOutput(true); + connection.getOutputStream().write(postBytes); + assertContent("ABCDE", connection, Integer.MAX_VALUE); + + RecordedRequest request = server.takeRequest(); + assertEquals("POST /foo HTTP/1.1", request.getRequestLine()); + assertArrayEquals(postBytes, request.getBody()); + assertEquals(postBytes.length, Integer.parseInt(request.getHeader("Content-Length"))); + } + + @Test public void setFixedLengthStreamingModeSetsContentLength() throws Exception { + MockResponse response = new MockResponse().setBody("ABCDE"); + server.enqueue(response); + server.play(); + + HttpURLConnection connection = client.open(server.getUrl("/foo")); + connection.setFixedLengthStreamingMode(postBytes.length); + connection.setDoOutput(true); + connection.getOutputStream().write(postBytes); + assertContent("ABCDE", connection, Integer.MAX_VALUE); + + RecordedRequest request = server.takeRequest(); + assertEquals("POST /foo HTTP/1.1", request.getRequestLine()); + assertArrayEquals(postBytes, request.getBody()); + assertEquals(postBytes.length, Integer.parseInt(request.getHeader("Content-Length"))); } @Test public void spdyConnectionReuse() throws Exception {