You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2014/06/24 14:31:33 UTC
svn commit: r1605066 - in /tomcat/trunk/java/org/apache/tomcat/websocket:
PerMessageDeflate.java Transformation.java WsFrameBase.java
Author: markt
Date: Tue Jun 24 12:31:32 2014
New Revision: 1605066
URL: http://svn.apache.org/r1605066
Log:
Handle decompression for messages split across multiple frames.
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java
tomcat/trunk/java/org/apache/tomcat/websocket/Transformation.java
tomcat/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java?rev=1605066&r1=1605065&r2=1605066&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java Tue Jun 24 12:31:32 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/trunk/java/org/apache/tomcat/websocket/Transformation.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/Transformation.java?rev=1605066&r1=1605065&r2=1605066&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/Transformation.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/Transformation.java Tue Jun 24 12:31:32 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/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java?rev=1605066&r1=1605065&r2=1605066&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java Tue Jun 24 12:31:32 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, messageBufferBinary);
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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org