Author: kkolinko Date: Fri Nov 4 01:29:44 2011 New Revision: 1197382 URL: http://svn.apache.org/viewvc?rev=1197382&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=52121 FlushableGZIPOutputStream produces corrupted output on some input sequences The fix is to do not restore compression level right before the end of the stream. Restore it only before writing the next portion of data.
Modified: tomcat/trunk/java/org/apache/coyote/http11/filters/FlushableGZIPOutputStream.java Modified: tomcat/trunk/java/org/apache/coyote/http11/filters/FlushableGZIPOutputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/filters/FlushableGZIPOutputStream.java?rev=1197382&r1=1197381&r2=1197382&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/filters/FlushableGZIPOutputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/filters/FlushableGZIPOutputStream.java Fri Nov 4 01:29:44 2011 @@ -37,28 +37,39 @@ public class FlushableGZIPOutputStream e private static final byte[] EMPTYBYTEARRAY = new byte[0]; private boolean hasData = false; + private boolean needReenableCompression = false; /** * Here we make sure we have received data, so that the header has been for * sure written to the output stream already. */ @Override - public synchronized void write(byte[] bytes, int i, int i1) + public synchronized void write(byte[] bytes, int offset, int length) throws IOException { - super.write(bytes, i, i1); - hasData = true; + if (length > 0) { + prepareForOutput(); + super.write(bytes, offset, length); + } } @Override public synchronized void write(int i) throws IOException { + prepareForOutput(); super.write(i); - hasData = true; } @Override public synchronized void write(byte[] bytes) throws IOException { - super.write(bytes); + write(bytes, 0, bytes.length); + } + + private void prepareForOutput() throws IOException { hasData = true; + if (needReenableCompression) { + def.setLevel(Deflater.DEFAULT_COMPRESSION); + deflate(); + needReenableCompression = false; + } } @Override @@ -80,8 +91,8 @@ public class FlushableGZIPOutputStream e def.setLevel(Deflater.NO_COMPRESSION); deflate(); - def.setLevel(Deflater.DEFAULT_COMPRESSION); - deflate(); + // Cannot reenable compression now. Must wait for data. + needReenableCompression = true; out.flush(); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org