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 2017/09/08 08:50:30 UTC
svn commit: r1807686 - in /tomcat/trunk:
java/org/apache/tomcat/websocket/PerMessageDeflate.java
test/org/apache/tomcat/websocket/TestPerMessageDeflate.java
webapps/docs/changelog.xml
Author: markt
Date: Fri Sep 8 08:50:30 2017
New Revision: 1807686
URL: http://svn.apache.org/viewvc?rev=1807686&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=61491
When using the permessage-deflate extension, correctly handle the sending of empty messages after non-empty messages to avoid the IllegalArgumentException
Added:
tomcat/trunk/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java (with props)
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java
tomcat/trunk/webapps/docs/changelog.xml
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=1807686&r1=1807685&r2=1807686&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java Fri Sep 8 08:50:30 2017
@@ -315,16 +315,20 @@ public class PerMessageDeflate implement
public List<MessagePart> sendMessagePart(List<MessagePart> uncompressedParts) {
List<MessagePart> allCompressedParts = new ArrayList<>();
+ // Flag to track if a message is completely empty
+ boolean emptyMessage = true;
+
for (MessagePart uncompressedPart : uncompressedParts) {
byte opCode = uncompressedPart.getOpCode();
+ boolean emptyPart = uncompressedPart.getPayload().limit() == 0;
+ emptyMessage = emptyMessage && emptyPart;
if (Util.isControl(opCode)) {
// Control messages can appear in the middle of other messages
// and must not be compressed. Pass it straight through
allCompressedParts.add(uncompressedPart);
- } else if (uncompressedPart.getPayload().limit() == 0 && uncompressedPart.isFin() &&
- deflater.getBytesRead() == 0) {
- // Zero length messages can't be compressed so pass them
- // straight through.
+ } else if (emptyMessage && uncompressedPart.isFin()) {
+ // Zero length messages can't be compressed so pass the
+ // final (empty) part straight through.
allCompressedParts.add(uncompressedPart);
} else {
List<MessagePart> compressedParts = new ArrayList<>();
Added: tomcat/trunk/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java?rev=1807686&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java (added)
+++ tomcat/trunk/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java Fri Sep 8 08:50:30 2017
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.websocket;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.websocket.Extension;
+import javax.websocket.Extension.Parameter;
+
+import org.junit.Test;
+
+public class TestPerMessageDeflate {
+
+ /*
+ * https://bz.apache.org/bugzilla/show_bug.cgi?id=61491
+ */
+ @Test
+ public void testSendEmptyMessagePartWithContextTakeover() {
+
+ // Set up the extension using defaults
+ List<Parameter> parameters = Collections.emptyList();
+ List<List<Parameter>> preferences = new ArrayList<>();
+ preferences.add(parameters);
+
+ PerMessageDeflate perMessageDeflate = PerMessageDeflate.negotiate(preferences, true);
+ perMessageDeflate.setNext(new TesterTransformation());
+
+ ByteBuffer bb1 = ByteBuffer.wrap("A".getBytes(StandardCharsets.UTF_8));
+ MessagePart mp1 = new MessagePart(true, 0, Constants.OPCODE_TEXT, bb1, null, null, -1);
+
+ List<MessagePart> uncompressedParts1 = new ArrayList<>();
+ uncompressedParts1.add(mp1);
+ perMessageDeflate.sendMessagePart(uncompressedParts1);
+
+ ByteBuffer bb2 = ByteBuffer.wrap("".getBytes(StandardCharsets.UTF_8));
+ MessagePart mp2 = new MessagePart(true, 0, Constants.OPCODE_TEXT, bb2, null, null, -1);
+
+ List<MessagePart> uncompressedParts2 = new ArrayList<>();
+ uncompressedParts2.add(mp2);
+ perMessageDeflate.sendMessagePart(uncompressedParts2);
+ }
+
+
+ /*
+ * Minimal implementation to enable other transformations to be tested.
+ */
+ private static class TesterTransformation implements Transformation {
+ @Override
+ public boolean validateRsvBits(int i) {
+ return false;
+ }
+ @Override
+ public boolean validateRsv(int rsv, byte opCode) {
+ return false;
+ }
+ @Override
+ public void setNext(Transformation t) {
+ }
+ @Override
+ public List<MessagePart> sendMessagePart(List<MessagePart> messageParts) {
+ return messageParts;
+ }
+ @Override
+ public TransformationResult getMoreData(byte opCode, boolean fin, int rsv, ByteBuffer dest)
+ throws IOException {
+ return null;
+ }
+ @Override
+ public Extension getExtensionResponse() {
+ return null;
+ }
+ @Override
+ public void close() {
+ }
+ }
+}
Propchange: tomcat/trunk/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1807686&r1=1807685&r2=1807686&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Fri Sep 8 08:50:30 2017
@@ -174,6 +174,12 @@
messages by not flushing between the header and the payload when the
two are written together. (markt)
</fix>
+ <fix>
+ <bug>61491</bug>: When using the <code>permessage-deflate</code>
+ extension, correctly handle the sending of empty messages after
+ non-empty messages to avoid the <code>IllegalArgumentException</code>.
+ (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Web applications">
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org