parent
56abb626a4
commit
9a6644ec7b
|
@ -299,6 +299,8 @@ public class WebSocketPolicy
|
|||
*/
|
||||
public void setIdleTimeout(long ms)
|
||||
{
|
||||
if(ms < -1) return; // no change (likely came from annotation)
|
||||
|
||||
boolean dirty = (this.idleTimeout != ms);
|
||||
assertGreaterThan("IdleTimeout",ms,0);
|
||||
this.idleTimeout = ms;
|
||||
|
@ -314,6 +316,8 @@ public class WebSocketPolicy
|
|||
*/
|
||||
public void setInputBufferSize(int size)
|
||||
{
|
||||
if(size < 0) return; // no change (likely came from annotation)
|
||||
|
||||
boolean dirty = (this.inputBufferSize != size);
|
||||
assertGreaterThan("InputBufferSize",size,1);
|
||||
this.inputBufferSize = size;
|
||||
|
@ -349,6 +353,8 @@ public class WebSocketPolicy
|
|||
*/
|
||||
public void setMaxBinaryMessageSize(int size)
|
||||
{
|
||||
if(size < 0) return; // no change (likely came from annotation)
|
||||
|
||||
boolean dirty = (this.maxBinaryMessageSize != size);
|
||||
assertGreaterThan("MaxBinaryMessageSize",size,1);
|
||||
|
||||
|
@ -385,6 +391,8 @@ public class WebSocketPolicy
|
|||
*/
|
||||
public void setMaxTextMessageSize(int size)
|
||||
{
|
||||
if(size < 0) return; // no change (likely came from annotation)
|
||||
|
||||
boolean dirty = (this.maxTextMessageSize != size);
|
||||
assertGreaterThan("MaxTextMessageSize",size,1);
|
||||
|
||||
|
|
|
@ -36,42 +36,29 @@ import org.eclipse.jetty.websocket.api.StatusCode;
|
|||
{ ElementType.TYPE })
|
||||
public @interface WebSocket
|
||||
{
|
||||
/* NOTE TO OTHER DEVELOPERS:
|
||||
* If you change any of these default values,
|
||||
* make sure you sync the values with WebSocketPolicy
|
||||
*/
|
||||
|
||||
/**
|
||||
* The size of the buffer used to read from the network layer.
|
||||
* <p>
|
||||
* Default: 4096 (4 K)
|
||||
* The size of the buffer (in bytes) used to read from the network layer.
|
||||
*/
|
||||
int inputBufferSize() default 4 * 1024;
|
||||
int inputBufferSize() default -2;
|
||||
|
||||
/**
|
||||
* The maximum size of a binary message during parsing/generating.
|
||||
* The maximum size of a binary message (in bytes) during parsing/generating.
|
||||
* <p>
|
||||
* Binary messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
|
||||
* <p>
|
||||
* Default: 65536 (64 K)
|
||||
*/
|
||||
int maxBinaryMessageSize() default 64 * 1024;
|
||||
int maxBinaryMessageSize() default -2;
|
||||
|
||||
/**
|
||||
* The time in ms (milliseconds) that a websocket may be idle before closing.
|
||||
* <p>
|
||||
* Default: 300000 (ms)
|
||||
*/
|
||||
int maxIdleTime() default 300_000;
|
||||
int maxIdleTime() default -2;
|
||||
|
||||
/**
|
||||
* The maximum size of a text message during parsing/generating.
|
||||
* <p>
|
||||
* Text messages over this maximum will result in a close code 1009 {@link StatusCode#MESSAGE_TOO_LARGE}
|
||||
* <p>
|
||||
* Default: 65536 (64 K)
|
||||
*/
|
||||
int maxTextMessageSize() default 64 * 1024;
|
||||
int maxTextMessageSize() default -2;
|
||||
|
||||
/**
|
||||
* The output frame buffering mode.
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.common;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
|
||||
public class FunctionCallException extends WebSocketException
|
||||
{
|
||||
public FunctionCallException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public FunctionCallException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public Throwable getInvokedCause()
|
||||
{
|
||||
Throwable cause = getCause();
|
||||
if (cause instanceof InvocationTargetException)
|
||||
{
|
||||
return cause.getCause();
|
||||
}
|
||||
return cause;
|
||||
}
|
||||
}
|
|
@ -367,6 +367,11 @@ public class Generator
|
|||
}
|
||||
}
|
||||
|
||||
public WebSocketBehavior getBehavior()
|
||||
{
|
||||
return behavior;
|
||||
}
|
||||
|
||||
public ByteBufferPool getBufferPool()
|
||||
{
|
||||
return bufferPool;
|
||||
|
|
|
@ -616,8 +616,9 @@ public class Parser
|
|||
buffer.limit(limit);
|
||||
buffer.position(buffer.position() + window.remaining());
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("{} Window: {}",policy.getBehavior(),BufferUtil.toDetailString(window));
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("{} Raw Payload: {}",policy.getBehavior(),BufferUtil.toDetailString(window));
|
||||
}
|
||||
|
||||
maskProcessor.process(window);
|
||||
|
|
|
@ -95,6 +95,7 @@ import org.eclipse.jetty.websocket.common.message.ReaderMessageSink;
|
|||
import org.eclipse.jetty.websocket.common.message.StringMessageSink;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketSessionScope;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgsException;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
@ManagedObject("A Jetty WebSocket Session")
|
||||
|
@ -255,7 +256,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
|||
policy.setMaxBinaryMessageSize(websocket.maxBinaryMessageSize());
|
||||
policy.setMaxTextMessageSize(websocket.maxTextMessageSize());
|
||||
policy.setIdleTimeout(websocket.maxIdleTime());
|
||||
|
||||
|
||||
this.batchmode = websocket.batchMode();
|
||||
|
||||
Method onmethod = null;
|
||||
|
@ -511,6 +512,22 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
|||
return connection.getMaxIdleTimeout();
|
||||
}
|
||||
|
||||
private Throwable getInvokedCause(Throwable t)
|
||||
{
|
||||
if (t instanceof FunctionCallException)
|
||||
{
|
||||
return ((FunctionCallException) t).getInvokedCause();
|
||||
}
|
||||
else if (t instanceof DynamicArgsException)
|
||||
{
|
||||
Throwable cause = ((DynamicArgsException) t).getInvokedCause();
|
||||
if (cause != null)
|
||||
return cause;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getLocalAddress()
|
||||
{
|
||||
|
@ -692,6 +709,11 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Discarding post EOF frame - {}", frame);
|
||||
}
|
||||
}
|
||||
catch (NotUtf8Exception e)
|
||||
{
|
||||
|
@ -704,25 +726,27 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
|||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.warn("Unhandled Error (closing connection)",t);
|
||||
Throwable cause = getInvokedCause(t);
|
||||
|
||||
notifyError(t);
|
||||
LOG.warn("Unhandled Error (closing connection)",cause);
|
||||
|
||||
notifyError(cause);
|
||||
|
||||
// Unhandled Error, close the connection.
|
||||
switch (policy.getBehavior())
|
||||
{
|
||||
case SERVER:
|
||||
close(StatusCode.SERVER_ERROR,t.getClass().getSimpleName());
|
||||
close(StatusCode.SERVER_ERROR,cause.getClass().getSimpleName());
|
||||
break;
|
||||
case CLIENT:
|
||||
close(StatusCode.POLICY_VIOLATION,t.getClass().getSimpleName());
|
||||
close(StatusCode.POLICY_VIOLATION,cause.getClass().getSimpleName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Unset active MessageSink if this was a fin frame
|
||||
if (frame.isFin() && activeMessageSink != null)
|
||||
if (frame.getType().isData() && frame.isFin() && activeMessageSink != null)
|
||||
activeMessageSink = null;
|
||||
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
|
@ -826,7 +850,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
|||
public void open()
|
||||
{
|
||||
if (LOG_OPEN.isDebugEnabled())
|
||||
LOG_OPEN.debug("[{}] {}.open()",policy.getBehavior(),this.getClass().getSimpleName());
|
||||
LOG_OPEN.debug("[{}] {}.open()", policy.getBehavior(), this.getClass().getSimpleName());
|
||||
|
||||
if (remote != null)
|
||||
{
|
||||
|
@ -840,9 +864,9 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
|||
connection.getIOState().onConnected();
|
||||
|
||||
// Connect remote
|
||||
remote = new WebSocketRemoteEndpoint(connection,outgoingHandler,getBatchMode());
|
||||
remote = new WebSocketRemoteEndpoint(connection, outgoingHandler, getBatchMode());
|
||||
if (LOG_OPEN.isDebugEnabled())
|
||||
LOG_OPEN.debug("[{}] {}.open() remote={}",policy.getBehavior(),this.getClass().getSimpleName(),remote);
|
||||
LOG_OPEN.debug("[{}] {}.open() remote={}", policy.getBehavior(), this.getClass().getSimpleName(), remote);
|
||||
|
||||
// Open WebSocket
|
||||
if (onOpenFunction != null)
|
||||
|
@ -853,7 +877,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
|||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("open -> {}",dump());
|
||||
LOG.debug("open -> {}", dump());
|
||||
}
|
||||
|
||||
if(openFuture != null)
|
||||
|
@ -864,11 +888,15 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
|||
catch (CloseException ce)
|
||||
{
|
||||
LOG.warn(ce);
|
||||
close(ce.getStatusCode(),ce.getMessage());
|
||||
notifyError(ce.getCause());
|
||||
close(ce.getStatusCode(), ce.getMessage());
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.warn(t);
|
||||
Throwable cause = getInvokedCause(t);
|
||||
|
||||
LOG.warn(cause);
|
||||
notifyError(cause);
|
||||
// Exception on end-user WS-Endpoint.
|
||||
// Fast-fail & close connection with reason.
|
||||
int statusCode = StatusCode.SERVER_ERROR;
|
||||
|
@ -876,7 +904,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
|||
{
|
||||
statusCode = StatusCode.POLICY_VIOLATION;
|
||||
}
|
||||
close(statusCode,t.getMessage());
|
||||
close(statusCode,cause.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,9 +23,9 @@ import java.lang.reflect.Method;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.FunctionCallException;
|
||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs.Arg;
|
||||
|
@ -93,7 +93,7 @@ public class OnByteArrayFunction implements Function<byte[], Void>
|
|||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
throw new WebSocketException("Unable to call text message method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
throw new FunctionCallException("Unable to call text message method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ import java.nio.ByteBuffer;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.FunctionCallException;
|
||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs.Arg;
|
||||
|
@ -90,7 +90,7 @@ public class OnByteBufferFunction implements Function<ByteBuffer, Void>
|
|||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
throw new WebSocketException("Unable to call text message method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
throw new FunctionCallException("Unable to call text message method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,10 @@ import java.lang.reflect.Method;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.FunctionCallException;
|
||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs.Arg;
|
||||
|
@ -83,7 +83,7 @@ public class OnCloseFunction implements Function<CloseInfo, Void>
|
|||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
throw new WebSocketException("Unable to call close method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
throw new FunctionCallException("Unable to call close method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ import java.lang.reflect.Method;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.FunctionCallException;
|
||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs.Arg;
|
||||
|
@ -79,7 +79,7 @@ public class OnErrorFunction implements Function<Throwable, Void>
|
|||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
throw new WebSocketException("Unable to call error method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
throw new FunctionCallException("Unable to call error method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,10 @@ import java.lang.reflect.Method;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
import org.eclipse.jetty.websocket.common.FunctionCallException;
|
||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs;
|
||||
|
@ -82,7 +82,7 @@ public class OnFrameFunction implements Function<Frame, Void>
|
|||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
throw new WebSocketException("Unable to call frame method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
throw new FunctionCallException("Unable to call frame method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ import java.lang.reflect.Method;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.FunctionCallException;
|
||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs.Arg;
|
||||
|
@ -91,7 +91,7 @@ public class OnInputStreamFunction implements Function<InputStream, Void>
|
|||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
throw new WebSocketException("Unable to call text message method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
throw new FunctionCallException("Unable to call text message method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ import java.lang.reflect.Method;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.FunctionCallException;
|
||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs.Arg;
|
||||
|
@ -76,7 +76,7 @@ public class OnOpenFunction implements Function<Session, Void>
|
|||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
throw new WebSocketException("Unable to call method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
throw new FunctionCallException("Unable to call method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ import java.lang.reflect.Method;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.FunctionCallException;
|
||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs.Arg;
|
||||
|
@ -90,7 +90,7 @@ public class OnReaderFunction implements Function<Reader, Void>
|
|||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
throw new WebSocketException("Unable to call text message method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
throw new FunctionCallException("Unable to call text message method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ import java.lang.reflect.Method;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.FunctionCallException;
|
||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.util.DynamicArgs.Arg;
|
||||
|
@ -89,7 +89,7 @@ public class OnTextFunction implements Function<String, Void>
|
|||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
throw new WebSocketException("Unable to call text message method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
throw new FunctionCallException("Unable to call text message method " + ReflectUtils.toString(endpoint.getClass(), method), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -423,7 +423,7 @@ public class FrameFlusher
|
|||
public String toString()
|
||||
{
|
||||
ByteBuffer aggregate = flusher.aggregate;
|
||||
return String.format("%s[queueSize=%d,aggregateSize=%d,failure=%s]",getClass().getSimpleName(),queue.size(),aggregate == null?0:aggregate.position(),
|
||||
return String.format("%s[%s,queueSize=%d,aggregateSize=%d,failure=%s]",getClass().getSimpleName(),generator.getBehavior(),queue.size(),aggregate == null?0:aggregate.position(),
|
||||
failure);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,15 @@ package org.eclipse.jetty.websocket.common.message;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
|
||||
public class StringMessageSink implements MessageSink
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(StringMessageSink.class);
|
||||
private final WebSocketPolicy policy;
|
||||
private final Function<String, Void> onMessageFunction;
|
||||
private Utf8StringBuilder utf;
|
||||
|
@ -42,33 +46,31 @@ public class StringMessageSink implements MessageSink
|
|||
@Override
|
||||
public void accept(ByteBuffer payload, Boolean fin)
|
||||
{
|
||||
try
|
||||
if (payload != null)
|
||||
{
|
||||
if (payload != null)
|
||||
{
|
||||
policy.assertValidTextMessageSize(size + payload.remaining());
|
||||
size += payload.remaining();
|
||||
policy.assertValidTextMessageSize(size + payload.remaining());
|
||||
size += payload.remaining();
|
||||
|
||||
if (utf == null)
|
||||
utf = new Utf8StringBuilder(1024);
|
||||
if (utf == null)
|
||||
utf = new Utf8StringBuilder(1024);
|
||||
|
||||
// allow for fast fail of BAD utf (incomplete utf will trigger on messageComplete)
|
||||
utf.append(payload);
|
||||
}
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Raw Payload {}", BufferUtil.toDetailString(payload));
|
||||
|
||||
// allow for fast fail of BAD utf (incomplete utf will trigger on messageComplete)
|
||||
utf.append(payload);
|
||||
}
|
||||
finally
|
||||
|
||||
if (fin)
|
||||
{
|
||||
if (fin)
|
||||
{
|
||||
// notify event
|
||||
if (utf != null)
|
||||
onMessageFunction.apply(utf.toString());
|
||||
else
|
||||
onMessageFunction.apply("");
|
||||
// reset
|
||||
size = 0;
|
||||
utf = null;
|
||||
}
|
||||
// notify event
|
||||
if (utf != null)
|
||||
onMessageFunction.apply(utf.toString());
|
||||
else
|
||||
onMessageFunction.apply("");
|
||||
// reset
|
||||
size = 0;
|
||||
utf = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,31 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.common.util;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class DynamicArgsException extends RuntimeException
|
||||
{
|
||||
public DynamicArgsException(String message, Throwable cause)
|
||||
{
|
||||
super(message,cause);
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public DynamicArgsException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
public Throwable getInvokedCause()
|
||||
{
|
||||
Throwable cause = getCause();
|
||||
if (cause == null)
|
||||
return null;
|
||||
|
||||
if (cause instanceof InvocationTargetException)
|
||||
{
|
||||
return cause.getCause();
|
||||
}
|
||||
return cause;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
|
@ -40,14 +41,18 @@ import org.junit.Test;
|
|||
|
||||
public class IdleTimeoutTest
|
||||
{
|
||||
@WebSocket(maxIdleTime = 500)
|
||||
public static class FastTimeoutRFCSocket extends RFCSocket
|
||||
{
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class TimeoutServlet extends WebSocketServlet
|
||||
{
|
||||
@Override
|
||||
public void configure(WebSocketServletFactory factory)
|
||||
{
|
||||
factory.getPolicy().setIdleTimeout(500);
|
||||
factory.register(RFCSocket.class);
|
||||
factory.register(FastTimeoutRFCSocket.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -557,7 +557,7 @@ public class TestABCase5 extends AbstractABCase
|
|||
}
|
||||
|
||||
/**
|
||||
* Send text fragmented in 2 packets, with ping between them (framewise)
|
||||
* Send text fragmented in 2 packets, with ping between them (frame wise)
|
||||
* @throws Exception on test failure
|
||||
*/
|
||||
@Test
|
||||
|
|
|
@ -46,7 +46,7 @@ public class TestABCase6_BadUTF extends AbstractABCase
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(TestABCase6_BadUTF.class);
|
||||
|
||||
@Parameters
|
||||
@Parameters(name = "{0} - {1}")
|
||||
public static Collection<String[]> data()
|
||||
{
|
||||
// The various Good UTF8 sequences as a String (hex form)
|
||||
|
@ -163,15 +163,13 @@ public class TestABCase6_BadUTF extends AbstractABCase
|
|||
List<WebSocketFrame> expect = new ArrayList<>();
|
||||
expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame());
|
||||
|
||||
try (Fuzzer fuzzer = new Fuzzer(this))
|
||||
try (Fuzzer fuzzer = new Fuzzer(this);
|
||||
StacklessLogging ignored = new StacklessLogging(Parser.class) )
|
||||
{
|
||||
try (StacklessLogging supress = new StacklessLogging(Parser.class))
|
||||
{
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
fuzzer.connect();
|
||||
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
|
||||
fuzzer.send(send);
|
||||
fuzzer.expect(expect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue