diff options
author | Jesse Wilson <jessewilson@google.com> | 2010-09-30 15:13:08 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-09-30 15:13:08 -0700 |
commit | e8c1e814814d5a97b0ded2de31d350928182dec5 (patch) | |
tree | 5028a0885645895b25c86231e11d111e5ef87a85 | |
parent | 16bba11e69ea61cf6127ee837eb05c8ac50a7128 (diff) | |
parent | f29ad8a60254345d1943d1b3836482395a7c916f (diff) | |
download | libcore-e8c1e814814d5a97b0ded2de31d350928182dec5.zip libcore-e8c1e814814d5a97b0ded2de31d350928182dec5.tar.gz libcore-e8c1e814814d5a97b0ded2de31d350928182dec5.tar.bz2 |
Merge "Don't explode if flush() is called when an HTTP upload stream is closed." into gingerbread
4 files changed, 49 insertions, 6 deletions
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/ChunkedOutputStream.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/ChunkedOutputStream.java index a43fb7d..cf6fc4c 100644 --- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/ChunkedOutputStream.java +++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/ChunkedOutputStream.java @@ -102,7 +102,9 @@ final class ChunkedOutputStream extends AbstractHttpOutputStream { } @Override public synchronized void flush() throws IOException { - checkNotClosed(); + if (closed) { + return; // don't throw; this stream might have been closed on the caller's behalf + } writeBufferedChunkToSocket(); socketOut.flush(); } diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/FixedLengthOutputStream.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/FixedLengthOutputStream.java index 2143a40..6bdab60 100644 --- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/FixedLengthOutputStream.java +++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/FixedLengthOutputStream.java @@ -42,7 +42,9 @@ final class FixedLengthOutputStream extends AbstractHttpOutputStream { } @Override public void flush() throws IOException { - checkNotClosed(); + if (closed) { + return; // don't throw; this stream might have been closed on the caller's behalf + } socketOut.flush(); } diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/RetryableOutputStream.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/RetryableOutputStream.java index d07833e..d02f5a4 100644 --- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/RetryableOutputStream.java +++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/RetryableOutputStream.java @@ -39,10 +39,6 @@ final class RetryableOutputStream extends AbstractHttpOutputStream { this.content = new ByteArrayOutputStream(); } - @Override public synchronized void flush() throws IOException { - checkNotClosed(); - } - @Override public synchronized void close() throws IOException { if (closed) { return; diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java index 32d0385..521ab78 100644 --- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java +++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java @@ -1342,6 +1342,49 @@ public class URLConnectionTest extends junit.framework.TestCase { assertEquals(-1, in.read()); } + public void testFlushAfterStreamTransmittedWithChunkedEncoding() throws IOException { + testFlushAfterStreamTransmitted(TransferKind.CHUNKED); + } + + public void testFlushAfterStreamTransmittedWithFixedLength() throws IOException { + testFlushAfterStreamTransmitted(TransferKind.FIXED_LENGTH); + } + + public void testFlushAfterStreamTransmittedWithNoLengthHeaders() throws IOException { + testFlushAfterStreamTransmitted(TransferKind.END_OF_STREAM); + } + + /** + * We explicitly permit apps to close the upload stream even after it has + * been transmitted. We also permit flush so that buffered streams can + * do a no-op flush when they are closed. http://b/3038470 + */ + private void testFlushAfterStreamTransmitted(TransferKind transferKind) throws IOException { + server.enqueue(new MockResponse().setBody("abc")); + server.play(); + + HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection(); + connection.setDoOutput(true); + byte[] upload = "def".getBytes("UTF-8"); + + if (transferKind == TransferKind.CHUNKED) { + connection.setChunkedStreamingMode(0); + } else if (transferKind == TransferKind.FIXED_LENGTH) { + connection.setFixedLengthStreamingMode(upload.length); + } + + OutputStream out = connection.getOutputStream(); + out.write(upload); + assertEquals("abc", readAscii(connection.getInputStream(), Integer.MAX_VALUE)); + + out.flush(); // dubious but permitted + try { + out.write("ghi".getBytes("UTF-8")); + fail(); + } catch (IOException expected) { + } + } + /** * Encodes the response body using GZIP and adds the corresponding header. */ |