Author: violetagg
Date: Tue Sep 16 20:27:49 2014
New Revision: 1625382

URL: http://svn.apache.org/r1625382
Log:
Merged revisions 1605066,1605417 from tomcat/trunk:
- Handle decompression for messages split across multiple frames.
- Fix copy/paste error in r1605054
Control messages should be read into the control message buffer

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/Transformation.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1605066,1605417

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java?rev=1625382&r1=1625381&r2=1625382&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java 
(original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java 
Tue Sep 16 20:27:49 2014
@@ -48,6 +48,7 @@ public class PerMessageDeflate implement
     private final ByteBuffer readBuffer = ByteBuffer.allocate(8192);
 
     private Transformation next;
+    private boolean skipDecompression = false;
 
     PerMessageDeflate(List<Parameter> params) {
 
@@ -89,12 +90,23 @@ public class PerMessageDeflate implement
     }
 
     @Override
-    public TransformationResult getMoreData(byte opCode, int rsv, ByteBuffer 
dest) throws IOException {
+    public TransformationResult getMoreData(byte opCode, boolean fin, int rsv, 
ByteBuffer dest)
+            throws IOException {
 
-        // Control frames are never compressed. Pass control frames and
-        // uncompressed frames straight through.
-        if (Util.isControl(opCode) || (rsv & RSV_BITMASK) == 0) {
-            return next.getMoreData(opCode, rsv, dest);
+        // Control frames are never compressed and may appear in the middle of
+        // a WebSocket method. Pass them straight through.
+        if (Util.isControl(opCode)) {
+            return next.getMoreData(opCode, fin, rsv, dest);
+        }
+
+        if (!Util.isContinuation(opCode)) {
+            // First frame in new message
+            skipDecompression = (rsv & RSV_BITMASK) == 0;
+        }
+
+        // Pass uncompressed frames straight through.
+        if (skipDecompression) {
+            return next.getMoreData(opCode, fin, rsv, dest);
         }
 
         int written;
@@ -114,15 +126,19 @@ public class PerMessageDeflate implement
                 if (dest.hasRemaining()) {
                     readBuffer.clear();
                     TransformationResult nextResult =
-                            next.getMoreData(opCode, (rsv ^ RSV_BITMASK), 
readBuffer);
+                            next.getMoreData(opCode, fin, (rsv ^ RSV_BITMASK), 
readBuffer);
                     inflator.setInput(
                             readBuffer.array(), readBuffer.arrayOffset(), 
readBuffer.position());
                     if (TransformationResult.UNDERFLOW.equals(nextResult)) {
                         return nextResult;
                     } else if 
(TransformationResult.END_OF_FRAME.equals(nextResult) &&
                             readBuffer.position() == 0) {
-                        inflator.setInput(EOM_BYTES);
-                        usedEomBytes = true;
+                        if (fin) {
+                            inflator.setInput(EOM_BYTES);
+                            usedEomBytes = true;
+                        } else {
+                            return TransformationResult.END_OF_FRAME;
+                        }
                     }
                 }
             } else if (written == 0) {

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/Transformation.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/Transformation.java?rev=1625382&r1=1625381&r2=1625382&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/Transformation.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/Transformation.java 
Tue Sep 16 20:27:49 2014
@@ -33,11 +33,12 @@ public interface Transformation {
      * Obtain more input data.
      *
      * @param opCode    The opcode for the frame currently being processed
+     * @param fin       Is this the final frame in this WebSocket message?
      * @param rsv       The reserved bits for the frame currently being
      *                      processed
      * @param dest      The buffer in which the data is to be written
      */
-    TransformationResult getMoreData(byte opCode, int rsv, ByteBuffer dest) 
throws IOException;
+    TransformationResult getMoreData(byte opCode, boolean fin, int rsv, 
ByteBuffer dest) throws IOException;
 
     /**
      * Validates the RSV and opcode combination (assumed to have been extracted

Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java?rev=1625382&r1=1625381&r2=1625382&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java Tue 
Sep 16 20:27:49 2014
@@ -300,7 +300,7 @@ public abstract class WsFrameBase {
 
 
     private boolean processDataControl() throws IOException {
-        TransformationResult tr = transformation.getMoreData(opCode, rsv, 
messageBufferBinary);
+        TransformationResult tr = transformation.getMoreData(opCode, fin, rsv, 
controlBufferBinary);
         if (TransformationResult.UNDERFLOW.equals(tr)) {
             return false;
         }
@@ -402,7 +402,7 @@ public abstract class WsFrameBase {
 
     private boolean processDataText() throws IOException {
         // Copy the available data to the buffer
-        TransformationResult tr = transformation.getMoreData(opCode, rsv, 
messageBufferBinary);
+        TransformationResult tr = transformation.getMoreData(opCode, fin, rsv, 
messageBufferBinary);
         while (!TransformationResult.END_OF_FRAME.equals(tr)) {
             // Frame not complete - we ran out of something
             // Convert bytes to UTF-8
@@ -443,7 +443,7 @@ public abstract class WsFrameBase {
                 }
             }
             // Read more input data
-            tr = transformation.getMoreData(opCode, rsv, messageBufferBinary);
+            tr = transformation.getMoreData(opCode, fin, rsv, 
messageBufferBinary);
         }
 
         messageBufferBinary.flip();
@@ -501,7 +501,7 @@ public abstract class WsFrameBase {
 
     private boolean processDataBinary() throws IOException {
         // Copy the available data to the buffer
-        TransformationResult tr = transformation.getMoreData(opCode, rsv, 
messageBufferBinary);
+        TransformationResult tr = transformation.getMoreData(opCode, fin, rsv, 
messageBufferBinary);
         while (!TransformationResult.END_OF_FRAME.equals(tr)) {
             // Frame not complete - what did we run out of?
             if (TransformationResult.UNDERFLOW.equals(tr)) {
@@ -526,7 +526,7 @@ public abstract class WsFrameBase {
             sendMessageBinary(copy, false);
             messageBufferBinary.clear();
             // Read more data
-            tr = transformation.getMoreData(opCode, rsv, messageBufferBinary);
+            tr = transformation.getMoreData(opCode, fin, rsv, 
messageBufferBinary);
         }
 
         // Frame is fully received
@@ -735,7 +735,8 @@ public abstract class WsFrameBase {
     private final class NoopTransformation extends TerminalTransformation {
 
         @Override
-        public TransformationResult getMoreData(byte opCode, int rsv, 
ByteBuffer dest) {
+        public TransformationResult getMoreData(byte opCode, boolean fin, int 
rsv,
+                ByteBuffer dest) {
             // opCode is ignored as the transformation is the same for all
             // opCodes
             // rsv is ignored as it known to be zero at this point
@@ -766,7 +767,8 @@ public abstract class WsFrameBase {
     private final class UnmaskTransformation extends TerminalTransformation {
 
         @Override
-        public TransformationResult getMoreData(byte opCode, int rsv, 
ByteBuffer dest) {
+        public TransformationResult getMoreData(byte opCode, boolean fin, int 
rsv,
+                ByteBuffer dest) {
             // opCode is ignored as the transformation is the same for all
             // opCodes
             // rsv is ignored as it known to be zero at this point



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to