WebSocket core cleanup (#3783)
* cleanups of WebSocket core Signed-off-by: Lachlan Roberts <lachlan@webtide.com> * WebSocket ConfigurationCustomizer now extends ConfigurationHolder Signed-off-by: Lachlan Roberts <lachlan@webtide.com> * adding isDebugEnabled checks Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
93b6619f8f
commit
3ae6d41a18
|
@ -519,16 +519,16 @@ public interface FrameHandler extends IncomingFrames
|
|||
void customize(Configuration configurable);
|
||||
}
|
||||
|
||||
class ConfigurationCustomizer implements Customizer, Configuration
|
||||
class ConfigurationHolder implements Configuration
|
||||
{
|
||||
private Duration idleTimeout;
|
||||
private Duration writeTimeout;
|
||||
private Boolean autoFragment;
|
||||
private Long maxFrameSize;
|
||||
private Integer outputBufferSize;
|
||||
private Integer inputBufferSize;
|
||||
private Long maxBinaryMessageSize;
|
||||
private Long maxTextMessageSize;
|
||||
protected Duration idleTimeout;
|
||||
protected Duration writeTimeout;
|
||||
protected Boolean autoFragment;
|
||||
protected Long maxFrameSize;
|
||||
protected Integer outputBufferSize;
|
||||
protected Integer inputBufferSize;
|
||||
protected Long maxBinaryMessageSize;
|
||||
protected Long maxTextMessageSize;
|
||||
|
||||
@Override
|
||||
public Duration getIdleTimeout()
|
||||
|
@ -625,7 +625,10 @@ public interface FrameHandler extends IncomingFrames
|
|||
{
|
||||
this.maxTextMessageSize = maxTextMessageSize;
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigurationCustomizer extends ConfigurationHolder implements Customizer
|
||||
{
|
||||
@Override
|
||||
public void customize(Configuration configurable)
|
||||
{
|
||||
|
|
|
@ -56,6 +56,7 @@ public class ExtensionStack implements IncomingFrames, OutgoingFrames, Dumpable
|
|||
private List<Extension> extensions;
|
||||
private IncomingFrames incoming;
|
||||
private OutgoingFrames outgoing;
|
||||
private String[] rsvClaims = new String[3];
|
||||
|
||||
public ExtensionStack(WebSocketExtensionRegistry factory, Behavior behavior)
|
||||
{
|
||||
|
@ -122,8 +123,6 @@ public class ExtensionStack implements IncomingFrames, OutgoingFrames, Dumpable
|
|||
|
||||
this.extensions = new ArrayList<>();
|
||||
|
||||
String rsvClaims[] = new String[3];
|
||||
|
||||
for (ExtensionConfig config : negotiatedConfigs)
|
||||
{
|
||||
Extension ext;
|
||||
|
@ -175,17 +174,20 @@ public class ExtensionStack implements IncomingFrames, OutgoingFrames, Dumpable
|
|||
// Check RSV
|
||||
if (ext.isRsv1User() && (rsvClaims[0] != null))
|
||||
{
|
||||
LOG.debug("Not adding extension {}. Extension {} already claimed RSV1", config, rsvClaims[0]);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Not adding extension {}. Extension {} already claimed RSV1", config, rsvClaims[0]);
|
||||
continue;
|
||||
}
|
||||
if (ext.isRsv2User() && (rsvClaims[1] != null))
|
||||
{
|
||||
LOG.debug("Not adding extension {}. Extension {} already claimed RSV2", config, rsvClaims[1]);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Not adding extension {}. Extension {} already claimed RSV2", config, rsvClaims[1]);
|
||||
continue;
|
||||
}
|
||||
if (ext.isRsv3User() && (rsvClaims[2] != null))
|
||||
{
|
||||
LOG.debug("Not adding extension {}. Extension {} already claimed RSV3", config, rsvClaims[2]);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Not adding extension {}. Extension {} already claimed RSV3", config, rsvClaims[2]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -197,17 +199,11 @@ public class ExtensionStack implements IncomingFrames, OutgoingFrames, Dumpable
|
|||
|
||||
// Record RSV Claims
|
||||
if (ext.isRsv1User())
|
||||
{
|
||||
rsvClaims[0] = ext.getName();
|
||||
}
|
||||
if (ext.isRsv2User())
|
||||
{
|
||||
rsvClaims[1] = ext.getName();
|
||||
}
|
||||
if (ext.isRsv3User())
|
||||
{
|
||||
rsvClaims[2] = ext.getName();
|
||||
}
|
||||
}
|
||||
|
||||
// Wire up Extensions
|
||||
|
@ -262,6 +258,21 @@ public class ExtensionStack implements IncomingFrames, OutgoingFrames, Dumpable
|
|||
extension.setWebSocketCoreSession(coreSession);
|
||||
}
|
||||
|
||||
public boolean isRsv1Used()
|
||||
{
|
||||
return (rsvClaims[0] != null);
|
||||
}
|
||||
|
||||
public boolean isRsv2Used()
|
||||
{
|
||||
return (rsvClaims[1] != null);
|
||||
}
|
||||
|
||||
public boolean isRsv3Used()
|
||||
{
|
||||
return (rsvClaims[2] != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dump()
|
||||
{
|
||||
|
|
|
@ -28,6 +28,8 @@ import org.eclipse.jetty.util.log.Log;
|
|||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.core.CloseStatus;
|
||||
import org.eclipse.jetty.websocket.core.Frame;
|
||||
import org.eclipse.jetty.websocket.core.FrameHandler.Configuration;
|
||||
import org.eclipse.jetty.websocket.core.FrameHandler.ConfigurationHolder;
|
||||
import org.eclipse.jetty.websocket.core.MessageTooLargeException;
|
||||
import org.eclipse.jetty.websocket.core.OpCode;
|
||||
import org.eclipse.jetty.websocket.core.ProtocolException;
|
||||
|
@ -51,7 +53,7 @@ public class Parser
|
|||
|
||||
private static final Logger LOG = Log.getLogger(Parser.class);
|
||||
private final ByteBufferPool bufferPool;
|
||||
private final boolean autoFragment;
|
||||
private final Configuration configuration;
|
||||
|
||||
// State specific
|
||||
private State state = State.START;
|
||||
|
@ -63,13 +65,13 @@ public class Parser
|
|||
|
||||
public Parser(ByteBufferPool bufferPool)
|
||||
{
|
||||
this(bufferPool, true);
|
||||
this(bufferPool, new ConfigurationHolder());
|
||||
}
|
||||
|
||||
public Parser(ByteBufferPool bufferPool, boolean autoFragment)
|
||||
public Parser(ByteBufferPool bufferPool, Configuration configuration)
|
||||
{
|
||||
this.bufferPool = bufferPool;
|
||||
this.autoFragment = autoFragment;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public void reset()
|
||||
|
@ -253,6 +255,10 @@ public class Parser
|
|||
{
|
||||
if (OpCode.isControlFrame(opcode) && payloadLength > Frame.MAX_CONTROL_PAYLOAD)
|
||||
throw new ProtocolException("Invalid control frame payload length, [" + payloadLength + "] cannot exceed [" + Frame.MAX_CONTROL_PAYLOAD + "]");
|
||||
|
||||
long maxFrameSize = configuration.getMaxFrameSize();
|
||||
if (!configuration.isAutoFragment() && maxFrameSize > 0 && payloadLength > maxFrameSize)
|
||||
throw new MessageTooLargeException("Cannot handle payload lengths larger than " + maxFrameSize);
|
||||
}
|
||||
|
||||
protected ParsedFrame newFrame(byte firstByte, byte[] mask, ByteBuffer payload, boolean releaseable)
|
||||
|
@ -287,7 +293,7 @@ public class Parser
|
|||
// not enough to complete this frame
|
||||
|
||||
// Can we auto-fragment
|
||||
if (autoFragment && OpCode.isDataFrame(OpCode.getOpCode(firstByte)))
|
||||
if (configuration.isAutoFragment() && OpCode.isDataFrame(OpCode.getOpCode(firstByte)))
|
||||
{
|
||||
payloadLength -= available;
|
||||
|
||||
|
|
|
@ -39,8 +39,6 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.websocket.core.Behavior;
|
||||
import org.eclipse.jetty.websocket.core.Frame;
|
||||
import org.eclipse.jetty.websocket.core.MessageTooLargeException;
|
||||
import org.eclipse.jetty.websocket.core.ProtocolException;
|
||||
import org.eclipse.jetty.websocket.core.WebSocketTimeoutException;
|
||||
|
||||
/**
|
||||
|
@ -83,23 +81,6 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
|||
Scheduler scheduler,
|
||||
ByteBufferPool bufferPool,
|
||||
WebSocketCoreSession coreSession)
|
||||
{
|
||||
this(endp, executor, scheduler, bufferPool, coreSession, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WSConnection.
|
||||
* <p>
|
||||
* It is assumed that the WebSocket Upgrade Handshake has already
|
||||
* completed successfully before creating this connection.
|
||||
* </p>
|
||||
*/
|
||||
public WebSocketConnection(EndPoint endp,
|
||||
Executor executor,
|
||||
Scheduler scheduler,
|
||||
ByteBufferPool bufferPool,
|
||||
WebSocketCoreSession coreSession,
|
||||
boolean validating)
|
||||
{
|
||||
super(endp, executor);
|
||||
|
||||
|
@ -113,18 +94,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
|||
this.coreSession = coreSession;
|
||||
|
||||
this.generator = new Generator(bufferPool);
|
||||
this.parser = new Parser(bufferPool, coreSession.isAutoFragment())
|
||||
{
|
||||
@Override
|
||||
protected void checkFrameSize(byte opcode, int payloadLength) throws MessageTooLargeException, ProtocolException
|
||||
{
|
||||
super.checkFrameSize(opcode, payloadLength);
|
||||
if (!coreSession.isAutoFragment() && coreSession.getMaxFrameSize() > 0 && payloadLength > coreSession.getMaxFrameSize())
|
||||
throw new MessageTooLargeException("Cannot handle payload lengths larger than " + coreSession.getMaxFrameSize());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.parser = new Parser(bufferPool, coreSession);
|
||||
this.flusher = new Flusher(scheduler, coreSession.getOutputBufferSize(), generator, endp);
|
||||
this.setInputBufferSize(coreSession.getInputBufferSize());
|
||||
|
||||
|
@ -179,7 +149,6 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
|||
super.onClose(cause);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onIdleExpired()
|
||||
{
|
||||
|
|
|
@ -41,7 +41,6 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.websocket.core.Behavior;
|
||||
import org.eclipse.jetty.websocket.core.CloseException;
|
||||
import org.eclipse.jetty.websocket.core.CloseStatus;
|
||||
import org.eclipse.jetty.websocket.core.Extension;
|
||||
import org.eclipse.jetty.websocket.core.ExtensionConfig;
|
||||
import org.eclipse.jetty.websocket.core.Frame;
|
||||
import org.eclipse.jetty.websocket.core.FrameHandler;
|
||||
|
@ -81,9 +80,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe
|
|||
private Duration idleTimeout = WebSocketConstants.DEFAULT_IDLE_TIMEOUT;
|
||||
private Duration writeTimeout = WebSocketConstants.DEFAULT_WRITE_TIMEOUT;
|
||||
|
||||
public WebSocketCoreSession(FrameHandler handler,
|
||||
Behavior behavior,
|
||||
Negotiated negotiated)
|
||||
public WebSocketCoreSession(FrameHandler handler, Behavior behavior, Negotiated negotiated)
|
||||
{
|
||||
this.handler = handler;
|
||||
this.behavior = behavior;
|
||||
|
@ -102,9 +99,9 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe
|
|||
|
||||
public void assertValidIncoming(Frame frame)
|
||||
{
|
||||
assertValid(frame);
|
||||
assertValidFrame(frame);
|
||||
|
||||
// Assert Behavior Required by RFC-6455 / Section 5.1
|
||||
// Assert Incoming Frame Behavior Required by RFC-6455 / Section 5.1
|
||||
switch (behavior)
|
||||
{
|
||||
case SERVER:
|
||||
|
@ -121,15 +118,15 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe
|
|||
|
||||
public void assertValidOutgoing(Frame frame) throws CloseException
|
||||
{
|
||||
// TODO check that it is not masked, since masking is done later
|
||||
assertValidFrame(frame);
|
||||
}
|
||||
|
||||
public void assertValidFrame(Frame frame)
|
||||
{
|
||||
if (!OpCode.isKnown(frame.getOpCode()))
|
||||
throw new ProtocolException("Unknown opcode: " + frame.getOpCode());
|
||||
|
||||
assertValid(frame);
|
||||
|
||||
int payloadLength = (frame.getPayload() == null)?0:frame.getPayload().remaining();
|
||||
|
||||
if (frame.isControlFrame())
|
||||
{
|
||||
if (!frame.isFin())
|
||||
|
@ -137,25 +134,14 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe
|
|||
|
||||
if (payloadLength > Frame.MAX_CONTROL_PAYLOAD)
|
||||
throw new ProtocolException("Invalid control frame payload length, [" + payloadLength + "] cannot exceed [" + Frame.MAX_CONTROL_PAYLOAD + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private void assertValid(Frame frame)
|
||||
{
|
||||
|
||||
// Control Frame Validation
|
||||
if (frame.isControlFrame())
|
||||
{
|
||||
if (frame.isRsv1())
|
||||
throw new ProtocolException("Cannot have RSV1==true on Control frames");
|
||||
|
||||
if (frame.isRsv2())
|
||||
throw new ProtocolException("Cannot have RSV2==true on Control frames");
|
||||
|
||||
if (frame.isRsv3())
|
||||
throw new ProtocolException("Cannot have RSV3==true on Control frames");
|
||||
|
||||
|
||||
/*
|
||||
* RFC 6455 Section 5.5.1
|
||||
* close frame payload is specially formatted which is checked in CloseStatus
|
||||
|
@ -168,42 +154,20 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe
|
|||
}
|
||||
else
|
||||
{
|
||||
// TODO should we validate UTF-8 for text frames
|
||||
if (frame.getOpCode() == OpCode.TEXT)
|
||||
{
|
||||
}
|
||||
/*
|
||||
* RFC 6455 Section 5.2
|
||||
*
|
||||
* MUST be 0 unless an extension is negotiated that defines meanings for non-zero values. If a nonzero value is received and none of the negotiated
|
||||
* extensions defines the meaning of such a nonzero value, the receiving endpoint MUST _Fail the WebSocket Connection_.
|
||||
*/
|
||||
ExtensionStack extensionStack = negotiated.getExtensions();
|
||||
if (frame.isRsv1() && !extensionStack.isRsv1Used())
|
||||
throw new ProtocolException("RSV1 not allowed to be set");
|
||||
if (frame.isRsv2() && !extensionStack.isRsv2Used())
|
||||
throw new ProtocolException("RSV2 not allowed to be set");
|
||||
if (frame.isRsv3() && !extensionStack.isRsv3Used())
|
||||
throw new ProtocolException("RSV3 not allowed to be set");
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 6455 Section 5.2
|
||||
*
|
||||
* MUST be 0 unless an extension is negotiated that defines meanings for non-zero values. If a nonzero value is received and none of the negotiated
|
||||
* extensions defines the meaning of such a nonzero value, the receiving endpoint MUST _Fail the WebSocket Connection_.
|
||||
*/
|
||||
//TODO save these values to not iterate through extensions every frame
|
||||
List<? extends Extension> exts = getExtensionStack().getExtensions();
|
||||
|
||||
boolean isRsv1InUse = false;
|
||||
boolean isRsv2InUse = false;
|
||||
boolean isRsv3InUse = false;
|
||||
for (Extension ext : exts)
|
||||
{
|
||||
if (ext.isRsv1User())
|
||||
isRsv1InUse = true;
|
||||
if (ext.isRsv2User())
|
||||
isRsv2InUse = true;
|
||||
if (ext.isRsv3User())
|
||||
isRsv3InUse = true;
|
||||
}
|
||||
|
||||
if (frame.isRsv1() && !isRsv1InUse)
|
||||
throw new ProtocolException("RSV1 not allowed to be set");
|
||||
|
||||
if (frame.isRsv2() && !isRsv2InUse)
|
||||
throw new ProtocolException("RSV2 not allowed to be set");
|
||||
|
||||
if (frame.isRsv3() && !isRsv3InUse)
|
||||
throw new ProtocolException("RSV3 not allowed to be set");
|
||||
}
|
||||
|
||||
public ExtensionStack getExtensionStack()
|
||||
|
@ -491,12 +455,12 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe
|
|||
|
||||
public WebSocketConnection getConnection()
|
||||
{
|
||||
return this.connection;
|
||||
return connection;
|
||||
}
|
||||
|
||||
public Executor getExecutor()
|
||||
{
|
||||
return this.connection.getExecutor();
|
||||
return connection.getExecutor();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -799,7 +763,7 @@ public class WebSocketCoreSession implements IncomingFrames, FrameHandler.CoreSe
|
|||
return String.format("WSCoreSession@%x{%s,%s,%s,af=%b,i/o=%d/%d,fs=%d}->%s",
|
||||
hashCode(),
|
||||
behavior,
|
||||
sessionState,
|
||||
sessionState,
|
||||
negotiated,
|
||||
autoFragment,
|
||||
inputBufferSize,
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.eclipse.jetty.io.ByteBufferPool;
|
|||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.websocket.core.internal.Generator;
|
||||
import org.eclipse.jetty.websocket.core.internal.Parser;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
@ -41,7 +40,7 @@ public class GeneratorParserRoundtripTest
|
|||
public void testParserAndGenerator() throws Exception
|
||||
{
|
||||
Generator gen = new Generator(bufferPool);
|
||||
ParserCapture capture = new ParserCapture(new Parser(bufferPool));
|
||||
ParserCapture capture = new ParserCapture();
|
||||
|
||||
String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
|
||||
|
||||
|
@ -74,7 +73,7 @@ public class GeneratorParserRoundtripTest
|
|||
public void testParserAndGeneratorMasked() throws Exception
|
||||
{
|
||||
Generator gen = new Generator(bufferPool);
|
||||
ParserCapture capture = new ParserCapture(new Parser(bufferPool), true, Behavior.SERVER);
|
||||
ParserCapture capture = new ParserCapture(true, Behavior.SERVER);
|
||||
|
||||
String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.websocket.core.internal.ExtensionStack;
|
||||
import org.eclipse.jetty.websocket.core.internal.Generator;
|
||||
import org.eclipse.jetty.websocket.core.internal.Negotiated;
|
||||
import org.eclipse.jetty.websocket.core.internal.Parser;
|
||||
import org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -1230,7 +1229,7 @@ public class GeneratorTest
|
|||
assertThat("Generated Buffer", completeBuffer.remaining(), is(expectedSize));
|
||||
|
||||
// Parse complete buffer.
|
||||
ParserCapture capture = new ParserCapture(new Parser(new MappedByteBufferPool()), true, Behavior.SERVER);
|
||||
ParserCapture capture = new ParserCapture(true, Behavior.SERVER);
|
||||
|
||||
capture.parse(completeBuffer);
|
||||
|
||||
|
|
|
@ -18,20 +18,17 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.core;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.websocket.core.internal.Generator;
|
||||
import org.eclipse.jetty.websocket.core.internal.Parser;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.websocket.core.internal.Generator;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
@ -60,14 +57,11 @@ public class ParsePayloadLengthTest
|
|||
);
|
||||
}
|
||||
|
||||
private ByteBufferPool bufferPool = new MappedByteBufferPool();
|
||||
|
||||
@ParameterizedTest(name = "size={0} {1}")
|
||||
@MethodSource("data")
|
||||
public void testPayloadLength(int size, String description) throws InterruptedException
|
||||
{
|
||||
Parser parser = new Parser(bufferPool);
|
||||
ParserCapture capture = new ParserCapture(parser);
|
||||
ParserCapture capture = new ParserCapture();
|
||||
|
||||
ByteBuffer raw = BufferUtil.allocate(size + Generator.MAX_HEADER_LENGTH);
|
||||
BufferUtil.clearToFill(raw);
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.core;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
@ -27,9 +30,6 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
@ -70,7 +70,7 @@ public class ParserBadCloseStatusCodesTest
|
|||
@MethodSource("data")
|
||||
public void testBadStatusCode(int closeCode, String description)
|
||||
{
|
||||
ParserCapture capture = new ParserCapture(new Parser(bufferPool));
|
||||
ParserCapture capture = new ParserCapture();
|
||||
|
||||
ByteBuffer raw = BufferUtil.allocate(256);
|
||||
BufferUtil.clearToFill(raw);
|
||||
|
@ -93,7 +93,7 @@ public class ParserBadCloseStatusCodesTest
|
|||
@MethodSource("data")
|
||||
public void testBadStatusCode_WithReasonPhrase(int closeCode, String description)
|
||||
{
|
||||
ParserCapture capture = new ParserCapture(new Parser(bufferPool));
|
||||
ParserCapture capture = new ParserCapture();
|
||||
|
||||
ByteBuffer raw = BufferUtil.allocate(256);
|
||||
BufferUtil.clearToFill(raw);
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.core;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
@ -27,9 +30,6 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
@ -62,7 +62,7 @@ public class ParserBadOpCodesTest
|
|||
@MethodSource("data")
|
||||
public void testBadOpCode(byte opcode, String description)
|
||||
{
|
||||
ParserCapture capture = new ParserCapture(new Parser(bufferPool));
|
||||
ParserCapture capture = new ParserCapture();
|
||||
|
||||
ByteBuffer raw = BufferUtil.allocate(256);
|
||||
BufferUtil.flipToFill(raw);
|
||||
|
@ -84,7 +84,7 @@ public class ParserBadOpCodesTest
|
|||
@MethodSource("data")
|
||||
public void testText_BadOpCode_Ping(byte opcode, String description)
|
||||
{
|
||||
ParserCapture capture = new ParserCapture(new Parser(bufferPool));
|
||||
ParserCapture capture = new ParserCapture();
|
||||
|
||||
ByteBuffer raw = BufferUtil.allocate(256);
|
||||
BufferUtil.flipToFill(raw);
|
||||
|
|
|
@ -42,25 +42,25 @@ public class ParserCapture
|
|||
public boolean closed = false;
|
||||
public boolean copy;
|
||||
|
||||
public ParserCapture(Parser parser)
|
||||
public ParserCapture()
|
||||
{
|
||||
this(parser, true);
|
||||
this(true);
|
||||
}
|
||||
|
||||
public ParserCapture(Parser parser, boolean copy)
|
||||
public ParserCapture(boolean copy)
|
||||
{
|
||||
this(parser, copy, Behavior.CLIENT);
|
||||
this(copy, Behavior.CLIENT);
|
||||
}
|
||||
|
||||
public ParserCapture(Parser parser, boolean copy, Behavior behavior)
|
||||
public ParserCapture(boolean copy, Behavior behavior)
|
||||
{
|
||||
this.parser = parser;
|
||||
this.copy = copy;
|
||||
|
||||
ByteBufferPool bufferPool = new MappedByteBufferPool();
|
||||
ExtensionStack exStack = new ExtensionStack(new WebSocketExtensionRegistry(), Behavior.SERVER);
|
||||
exStack.negotiate(new DecoratedObjectFactory(), bufferPool, new LinkedList<>(), new LinkedList<>());
|
||||
this.coreSession = new WebSocketCoreSession(new AbstractTestFrameHandler(), behavior, Negotiated.from(exStack));
|
||||
this.parser = new Parser(bufferPool, coreSession);
|
||||
}
|
||||
|
||||
public void parse(ByteBuffer buffer)
|
||||
|
@ -96,4 +96,14 @@ public class ParserCapture
|
|||
closed = true;
|
||||
return true; // it is consumed
|
||||
}
|
||||
|
||||
public Parser getParser()
|
||||
{
|
||||
return parser;
|
||||
}
|
||||
|
||||
public WebSocketCoreSession getCoreSession()
|
||||
{
|
||||
return coreSession;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,18 +18,15 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.core;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.websocket.core.internal.Parser;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
@ -63,13 +60,11 @@ public class ParserGoodCloseStatusCodesTest
|
|||
);
|
||||
}
|
||||
|
||||
private ByteBufferPool bufferPool = new MappedByteBufferPool();
|
||||
|
||||
@ParameterizedTest(name = "closeCode={0} {1}")
|
||||
@MethodSource("data")
|
||||
public void testGoodCloseCode(int closeCode, String description) throws InterruptedException
|
||||
{
|
||||
ParserCapture capture = new ParserCapture(new Parser(bufferPool));
|
||||
ParserCapture capture = new ParserCapture();
|
||||
|
||||
ByteBuffer raw = BufferUtil.allocate(256);
|
||||
BufferUtil.clearToFill(raw);
|
||||
|
@ -93,7 +88,7 @@ public class ParserGoodCloseStatusCodesTest
|
|||
@MethodSource("data")
|
||||
public void testGoodCloseCode_WithReasonPhrase(int closeCode, String description) throws InterruptedException
|
||||
{
|
||||
ParserCapture capture = new ParserCapture(new Parser(bufferPool));
|
||||
ParserCapture capture = new ParserCapture();
|
||||
|
||||
ByteBuffer raw = BufferUtil.allocate(256);
|
||||
BufferUtil.clearToFill(raw);
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.core;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
@ -26,11 +31,6 @@ import org.eclipse.jetty.websocket.core.internal.Generator;
|
|||
import org.eclipse.jetty.websocket.core.internal.Parser;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
@ -44,7 +44,7 @@ public class ParserReservedBitTest
|
|||
|
||||
private void expectProtocolException(List<Frame> frames)
|
||||
{
|
||||
ParserCapture parserCapture = new ParserCapture(new Parser(bufferPool));
|
||||
ParserCapture parserCapture = new ParserCapture();
|
||||
|
||||
// generate raw bytebuffer of provided frames
|
||||
int size = frames.stream().mapToInt(frame -> frame.getPayloadLength() + Generator.MAX_HEADER_LENGTH).sum();
|
||||
|
|
|
@ -58,17 +58,8 @@ public class ParserTest
|
|||
|
||||
private ParserCapture parse(Behavior behavior, int maxAllowedFrameSize, ByteBuffer buffer, boolean copy)
|
||||
{
|
||||
Parser parser = new Parser(new MappedByteBufferPool())
|
||||
{
|
||||
@Override
|
||||
protected void checkFrameSize(byte opcode, int payloadLength) throws MessageTooLargeException, ProtocolException
|
||||
{
|
||||
super.checkFrameSize(opcode, payloadLength);
|
||||
if (payloadLength > maxAllowedFrameSize)
|
||||
throw new MessageTooLargeException("Cannot handle payload lengths larger than " + maxAllowedFrameSize);
|
||||
}
|
||||
};
|
||||
ParserCapture capture = new ParserCapture(parser, copy, behavior);
|
||||
ParserCapture capture = new ParserCapture(copy, behavior);
|
||||
capture.getCoreSession().setMaxFrameSize(maxAllowedFrameSize);
|
||||
capture.parse(buffer);
|
||||
return capture;
|
||||
}
|
||||
|
@ -860,7 +851,7 @@ public class ParserTest
|
|||
@Test
|
||||
public void testParse_RFC6455_FragmentedUnmaskedTextMessage() throws InterruptedException
|
||||
{
|
||||
ParserCapture capture = new ParserCapture(new Parser(new MappedByteBufferPool()));
|
||||
ParserCapture capture = new ParserCapture();
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(16);
|
||||
BufferUtil.clearToFill(buf);
|
||||
|
@ -1007,7 +998,7 @@ public class ParserTest
|
|||
}
|
||||
buf.flip();
|
||||
|
||||
ParserCapture capture = new ParserCapture(new Parser(new MappedByteBufferPool()));
|
||||
ParserCapture capture = new ParserCapture();
|
||||
capture.parse(buf);
|
||||
|
||||
capture.assertHasFrame(OpCode.BINARY, 1);
|
||||
|
@ -1310,7 +1301,10 @@ public class ParserTest
|
|||
Generator.putPayload(buf, utf);
|
||||
buf.flip();
|
||||
|
||||
assertThrows(MessageTooLargeException.class, () -> parse(Behavior.SERVER, maxAllowedFrameSize, buf, true));
|
||||
ParserCapture capture = new ParserCapture(true, Behavior.SERVER);
|
||||
capture.getCoreSession().setMaxFrameSize(maxAllowedFrameSize);
|
||||
capture.getCoreSession().setAutoFragment(false);
|
||||
assertThrows(MessageTooLargeException.class, () -> capture.parse(buf));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1361,7 +1355,8 @@ public class ParserTest
|
|||
ByteBuffer networkBytes = generate(Behavior.CLIENT, frames);
|
||||
|
||||
// Parse, in 4096 sized windows
|
||||
ParserCapture capture = new ParserCapture(new Parser(new MappedByteBufferPool(), false), true, Behavior.SERVER);
|
||||
ParserCapture capture = new ParserCapture(true, Behavior.SERVER);
|
||||
capture.getCoreSession().setAutoFragment(false);
|
||||
|
||||
while (networkBytes.remaining() > 0)
|
||||
{
|
||||
|
@ -1548,7 +1543,7 @@ public class ParserTest
|
|||
int limit = data.limit();
|
||||
ByteBuffer buffer = BufferUtil.allocate(32);
|
||||
|
||||
ParserCapture capture = new ParserCapture(new Parser(new MappedByteBufferPool()), false, Behavior.SERVER);
|
||||
ParserCapture capture = new ParserCapture(false, Behavior.SERVER);
|
||||
|
||||
data.limit(6 + 5);
|
||||
BufferUtil.append(buffer, data);
|
||||
|
@ -1592,7 +1587,8 @@ public class ParserTest
|
|||
int limit = data.limit();
|
||||
ByteBuffer buffer = BufferUtil.allocate(32);
|
||||
|
||||
ParserCapture capture = new ParserCapture(new Parser(new MappedByteBufferPool(), false), false);
|
||||
ParserCapture capture = new ParserCapture(false);
|
||||
capture.getCoreSession().setAutoFragment(false);
|
||||
|
||||
data.limit(5);
|
||||
BufferUtil.append(buffer, data);
|
||||
|
@ -1626,7 +1622,7 @@ public class ParserTest
|
|||
int limit = data.limit();
|
||||
ByteBuffer buffer = BufferUtil.allocate(32);
|
||||
|
||||
ParserCapture capture = new ParserCapture(new Parser(new MappedByteBufferPool(), true), false);
|
||||
ParserCapture capture = new ParserCapture(false);
|
||||
|
||||
data.limit(5);
|
||||
BufferUtil.append(buffer, data);
|
||||
|
|
Loading…
Reference in New Issue