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

Reply via email to