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