mirror of
https://github.com/jetty/jetty.project.git
synced 2025-03-04 12:59:30 +00:00
Merge branch jetty-9.4.x
into jetty-10.0.x
Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com> # Conflicts: # jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootWithAnnotations.java # jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java # jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageBinaryCallable.java # jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageTextCallable.java # jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/messages/BinaryWholeMessage.java # jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/messages/TextWholeMessage.java # jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java # jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/PerMessageDeflateExtension.java # jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/FragmentExtensionTest.java # jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/extensions/compress/PerMessageDeflateExtensionTest.java # jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/OutgoingFramesCapture.java
This commit is contained in:
commit
715bac2660
@ -31,6 +31,7 @@ import org.eclipse.jetty.websocket.core.BadPayloadException;
|
||||
import org.eclipse.jetty.websocket.core.ExtensionConfig;
|
||||
import org.eclipse.jetty.websocket.core.Frame;
|
||||
import org.eclipse.jetty.websocket.core.OpCode;
|
||||
import org.eclipse.jetty.websocket.core.ProtocolException;
|
||||
|
||||
/**
|
||||
* Per Message Deflate Compression extension for WebSocket.
|
||||
@ -73,9 +74,16 @@ public class PerMessageDeflateExtension extends CompressExtension
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame.getOpCode() == OpCode.CONTINUATION && frame.isRsv1())
|
||||
{
|
||||
// Per RFC7692 we MUST Fail the websocket connection
|
||||
throw new ProtocolException("Invalid RSV1 set on permessage-deflate CONTINUATION frame");
|
||||
}
|
||||
|
||||
//TODO fix this to use long instead of int
|
||||
if (getWebSocketChannel().getMaxFrameSize() > Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException("maxFrameSize too large for ByteAccumulator");
|
||||
|
||||
ByteAccumulator accumulator = new ByteAccumulator((int)getWebSocketChannel().getMaxFrameSize());
|
||||
|
||||
try
|
||||
|
@ -18,6 +18,12 @@
|
||||
|
||||
package org.eclipse.jetty.websocket.core.extensions;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.ByteBufferAssert;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
@ -27,18 +33,14 @@ import org.eclipse.jetty.websocket.core.Frame;
|
||||
import org.eclipse.jetty.websocket.core.IncomingFramesCapture;
|
||||
import org.eclipse.jetty.websocket.core.OpCode;
|
||||
import org.eclipse.jetty.websocket.core.OutgoingFramesCapture;
|
||||
import org.eclipse.jetty.websocket.core.ProtocolException;
|
||||
import org.eclipse.jetty.websocket.core.internal.compress.CompressExtension;
|
||||
import org.eclipse.jetty.websocket.core.internal.compress.PerMessageDeflateExtension;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
/**
|
||||
* Client side behavioral tests for permessage-deflate extension.
|
||||
@ -219,6 +221,56 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest
|
||||
tester.assertHasFrames("Hello");
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode fragmented message (3 parts: TEXT, CONTINUATION, CONTINUATION)
|
||||
*/
|
||||
@Test
|
||||
public void testParseFragmentedMessage_Good()
|
||||
{
|
||||
ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate");
|
||||
|
||||
tester.assertNegotiated("permessage-deflate");
|
||||
|
||||
tester.parseIncomingHex(// 1 message, 3 frame
|
||||
"410C", // HEADER TEXT / fin=false / rsv1=true
|
||||
"F248CDC9C95700000000FFFF",
|
||||
"000B", // HEADER CONTINUATION / fin=false / rsv1=false
|
||||
"0ACF2FCA4901000000FFFF",
|
||||
"8003", // HEADER CONTINUATION / fin=true / rsv1=false
|
||||
"520400"
|
||||
);
|
||||
|
||||
Frame txtFrame = new Frame(OpCode.TEXT).setPayload("Hello ").setFin(false);
|
||||
Frame con1Frame = new Frame(OpCode.CONTINUATION).setPayload("World").setFin(false);
|
||||
Frame con2Frame = new Frame(OpCode.CONTINUATION).setPayload("!").setFin(true);
|
||||
|
||||
tester.assertHasFrames(txtFrame, con1Frame, con2Frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode fragmented message (3 parts: TEXT, CONTINUATION, CONTINUATION)
|
||||
* <p>
|
||||
* Continuation frames have RSV1 set, which MUST result in Failure
|
||||
* </p>
|
||||
*/
|
||||
@Test
|
||||
public void testParseFragmentedMessage_BadRsv1()
|
||||
{
|
||||
ExtensionTool.Tester tester = clientExtensions.newTester("permessage-deflate");
|
||||
|
||||
tester.assertNegotiated("permessage-deflate");
|
||||
|
||||
assertThrows(ProtocolException.class, () ->
|
||||
tester.parseIncomingHex(// 1 message, 3 frame
|
||||
"410C", // Header TEXT / fin=false / rsv1=true
|
||||
"F248CDC9C95700000000FFFF", // Payload
|
||||
"400B", // Header CONTINUATION / fin=false / rsv1=true
|
||||
"0ACF2FCA4901000000FFFF", // Payload
|
||||
"C003", // Header CONTINUATION / fin=true / rsv1=true
|
||||
"520400" // Payload
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Incoming PING (Control Frame) should pass through extension unmodified
|
||||
*/
|
||||
@ -255,6 +307,43 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest
|
||||
}
|
||||
|
||||
/**
|
||||
* Incoming Text Message fragmented into 3 pieces.
|
||||
*/
|
||||
@Test
|
||||
public void testIncomingFragmented()
|
||||
{
|
||||
PerMessageDeflateExtension ext = new PerMessageDeflateExtension();
|
||||
ExtensionConfig config = ExtensionConfig.parse("permessage-deflate");
|
||||
ext.init(config, bufferPool);
|
||||
|
||||
// Setup capture of incoming frames
|
||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||
|
||||
// Wire up stack
|
||||
ext.setNextIncomingFrames(capture);
|
||||
|
||||
String payload = "Are you there?";
|
||||
Frame ping = new Frame(OpCode.PING).setPayload(payload);
|
||||
ext.onFrame(ping, Callback.NOOP);
|
||||
|
||||
capture.assertFrameCount(1);
|
||||
capture.assertHasOpCount(OpCode.PING, 1);
|
||||
Frame actual = capture.frames.poll();
|
||||
|
||||
assertThat("Frame.opcode", actual.getOpCode(), is(OpCode.PING));
|
||||
assertThat("Frame.fin", actual.isFin(), is(true));
|
||||
assertThat("Frame.rsv1", actual.isRsv1(), is(false));
|
||||
assertThat("Frame.rsv2", actual.isRsv2(), is(false));
|
||||
assertThat("Frame.rsv3", actual.isRsv3(), is(false));
|
||||
|
||||
ByteBuffer expected = BufferUtil.toBuffer(payload, StandardCharsets.UTF_8);
|
||||
assertThat("Frame.payloadLength", actual.getPayloadLength(), is(expected.remaining()));
|
||||
ByteBufferAssert.assertEquals("Frame.payload", expected, actual.getPayload().slice());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Verify that incoming uncompressed frames are properly passed through
|
||||
*/
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user