Issue #207 - initial pass through for Stream backpressure
This commit is contained in:
parent
c3bb6ae535
commit
fa10576bc6
|
@ -29,7 +29,6 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.thread.Invocable.InvocationType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a reusable {@link Callback} that can block the thread
|
* Provides a reusable {@link Callback} that can block the thread
|
||||||
|
@ -168,6 +167,7 @@ public class SharedBlockingCallback
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
cause.printStackTrace(System.err);
|
||||||
throw new IllegalStateException(_state);
|
throw new IllegalStateException(_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,9 +49,11 @@ import javax.websocket.Session;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||||
import org.eclipse.jetty.websocket.common.function.CommonEndpointFunctions;
|
import org.eclipse.jetty.websocket.common.function.CommonEndpointFunctions;
|
||||||
import org.eclipse.jetty.websocket.common.message.MessageSink;
|
import org.eclipse.jetty.websocket.common.message.MessageSink;
|
||||||
|
@ -105,11 +107,11 @@ public class JsrEndpointFunctions extends CommonEndpointFunctions<JsrSession>
|
||||||
this.messageHandler = messageHandler;
|
this.messageHandler = messageHandler;
|
||||||
this.delegateSink = messageSink;
|
this.delegateSink = messageSink;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ByteBuffer payload, Boolean fin)
|
public void accept(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
this.delegateSink.accept(payload, fin);
|
this.delegateSink.accept(frame, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -31,7 +31,9 @@ import javax.websocket.DeploymentException;
|
||||||
import javax.websocket.MessageHandler;
|
import javax.websocket.MessageHandler;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
|
import org.eclipse.jetty.websocket.common.FrameCallbackAdapter;
|
||||||
import org.eclipse.jetty.websocket.common.frames.BinaryFrame;
|
import org.eclipse.jetty.websocket.common.frames.BinaryFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.ContinuationFrame;
|
import org.eclipse.jetty.websocket.common.frames.ContinuationFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
|
@ -125,9 +127,11 @@ public class JsrSessionTest
|
||||||
session.addMessageHandler(String.class, (msg) -> received.add(msg));
|
session.addMessageHandler(String.class, (msg) -> received.add(msg));
|
||||||
|
|
||||||
session.open();
|
session.open();
|
||||||
|
|
||||||
|
FrameCallback callback = new FrameCallbackAdapter();
|
||||||
|
|
||||||
session.incomingFrame(new TextFrame().setPayload("G'day").setFin(true));
|
session.incomingFrame(new TextFrame().setPayload("G'day").setFin(true), callback);
|
||||||
session.incomingFrame(new TextFrame().setPayload("Hello World").setFin(true));
|
session.incomingFrame(new TextFrame().setPayload("Hello World").setFin(true), callback);
|
||||||
|
|
||||||
assertThat("Received msgs", received.size(), is(2));
|
assertThat("Received msgs", received.size(), is(2));
|
||||||
assertThat("Received Message[0]", received.get(0), is("G'day"));
|
assertThat("Received Message[0]", received.get(0), is("G'day"));
|
||||||
|
@ -155,8 +159,10 @@ public class JsrSessionTest
|
||||||
|
|
||||||
session.open();
|
session.open();
|
||||||
|
|
||||||
session.incomingFrame(new BinaryFrame().setPayload("G'day").setFin(false));
|
FrameCallback callback = new FrameCallbackAdapter();
|
||||||
session.incomingFrame(new ContinuationFrame().setPayload(" World").setFin(true));
|
|
||||||
|
session.incomingFrame(new BinaryFrame().setPayload("G'day").setFin(false), callback);
|
||||||
|
session.incomingFrame(new ContinuationFrame().setPayload(" World").setFin(true), callback);
|
||||||
|
|
||||||
assertThat("Received partial", received.size(), is(2));
|
assertThat("Received partial", received.size(), is(2));
|
||||||
assertThat("Received Message[0].buffer", BufferUtil.toUTF8String((ByteBuffer) received.get(0)[0]), is("G'day"));
|
assertThat("Received Message[0].buffer", BufferUtil.toUTF8String((ByteBuffer) received.get(0)[0]), is("G'day"));
|
||||||
|
|
|
@ -31,9 +31,10 @@ import javax.websocket.ClientEndpointConfig;
|
||||||
import javax.websocket.EndpointConfig;
|
import javax.websocket.EndpointConfig;
|
||||||
import javax.websocket.OnMessage;
|
import javax.websocket.OnMessage;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.BinaryFrame;
|
||||||
import org.eclipse.jetty.websocket.common.function.EndpointFunctions;
|
import org.eclipse.jetty.websocket.common.function.EndpointFunctions;
|
||||||
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
||||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||||
|
@ -130,7 +131,7 @@ public class JsrEndpointFunctions_OnMessage_BinaryStreamTest
|
||||||
{
|
{
|
||||||
TrackingSocket socket = performOnMessageInvocation(new MessageStreamSocket(), (endpoint) ->
|
TrackingSocket socket = performOnMessageInvocation(new MessageStreamSocket(), (endpoint) ->
|
||||||
{
|
{
|
||||||
endpoint.onBinary(BufferUtil.toBuffer("Hello World", StandardCharsets.UTF_8), true);
|
endpoint.onBinary(new BinaryFrame().setPayload("Hello World").setFin(true), new FrameCallback.Adapter());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
socket.assertEvent("onMessage(MessageInputStream) = \"Hello World\"");
|
socket.assertEvent("onMessage(MessageInputStream) = \"Hello World\"");
|
||||||
|
|
|
@ -34,8 +34,10 @@ import javax.websocket.OnMessage;
|
||||||
import javax.websocket.Session;
|
import javax.websocket.Session;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.BinaryFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
||||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||||
import org.eclipse.jetty.websocket.jsr356.ConfiguredEndpoint;
|
import org.eclipse.jetty.websocket.jsr356.ConfiguredEndpoint;
|
||||||
|
@ -107,7 +109,7 @@ public class JsrEndpointFunctions_OnMessage_BinaryTest
|
||||||
// This invocation is the same for all tests
|
// This invocation is the same for all tests
|
||||||
ByteBuffer byteBuffer = ByteBuffer.wrap("Hello World".getBytes(StandardCharsets.UTF_8));
|
ByteBuffer byteBuffer = ByteBuffer.wrap("Hello World".getBytes(StandardCharsets.UTF_8));
|
||||||
expectedBuffer = BufferUtil.toDetailString(byteBuffer);
|
expectedBuffer = BufferUtil.toDetailString(byteBuffer);
|
||||||
endpointFunctions.onBinary(byteBuffer, true);
|
endpointFunctions.onBinary(new BinaryFrame().setPayload(byteBuffer).setFin(true), new FrameCallback.Adapter());
|
||||||
socket.assertEvent(String.format(expectedEventFormat, args));
|
socket.assertEvent(String.format(expectedEventFormat, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.jsr356.function;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -31,9 +30,10 @@ import javax.websocket.ClientEndpointConfig;
|
||||||
import javax.websocket.EndpointConfig;
|
import javax.websocket.EndpointConfig;
|
||||||
import javax.websocket.OnMessage;
|
import javax.websocket.OnMessage;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.function.EndpointFunctions;
|
import org.eclipse.jetty.websocket.common.function.EndpointFunctions;
|
||||||
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
||||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||||
|
@ -130,7 +130,7 @@ public class JsrEndpointFunctions_OnMessage_TextStreamTest
|
||||||
{
|
{
|
||||||
TrackingSocket socket = performOnMessageInvocation(new MessageStreamSocket(), (endpoint) ->
|
TrackingSocket socket = performOnMessageInvocation(new MessageStreamSocket(), (endpoint) ->
|
||||||
{
|
{
|
||||||
endpoint.onText(BufferUtil.toBuffer("Hello World", StandardCharsets.UTF_8), true);
|
endpoint.onText(new TextFrame().setPayload("Hello World").setFin(true), new FrameCallback.Adapter());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
socket.assertEvent("onMessage(MessageReader) = \"Hello World\"");
|
socket.assertEvent("onMessage(MessageReader) = \"Hello World\"");
|
||||||
|
|
|
@ -33,8 +33,10 @@ import javax.websocket.OnMessage;
|
||||||
import javax.websocket.Session;
|
import javax.websocket.Session;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
||||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||||
import org.eclipse.jetty.websocket.jsr356.ConfiguredEndpoint;
|
import org.eclipse.jetty.websocket.jsr356.ConfiguredEndpoint;
|
||||||
|
@ -101,7 +103,7 @@ public class JsrEndpointFunctions_OnMessage_TextTest
|
||||||
endpointFunctions.onOpen(newSession(socket));
|
endpointFunctions.onOpen(newSession(socket));
|
||||||
|
|
||||||
ByteBuffer payload = BufferUtil.toBuffer(msg, StandardCharsets.UTF_8);
|
ByteBuffer payload = BufferUtil.toBuffer(msg, StandardCharsets.UTF_8);
|
||||||
endpointFunctions.onText(payload, true);
|
endpointFunctions.onText(new TextFrame().setPayload(payload).setFin(true), new FrameCallback.Adapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertOnMessageInvocation(TrackingSocket socket, String expectedEventFormat, Object... args) throws Exception
|
private void assertOnMessageInvocation(TrackingSocket socket, String expectedEventFormat, Object... args) throws Exception
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.jsr356.server;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -32,9 +31,10 @@ import javax.websocket.OnMessage;
|
||||||
import javax.websocket.server.PathParam;
|
import javax.websocket.server.PathParam;
|
||||||
import javax.websocket.server.ServerEndpoint;
|
import javax.websocket.server.ServerEndpoint;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.function.EndpointFunctions;
|
import org.eclipse.jetty.websocket.common.function.EndpointFunctions;
|
||||||
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
import org.eclipse.jetty.websocket.common.test.DummyConnection;
|
||||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||||
|
@ -131,7 +131,7 @@ public class JsrServerEndpointFunctions_OnMessage_TextStreamTest
|
||||||
{
|
{
|
||||||
TrackingSocket socket = performOnMessageInvocation(new MessageStreamSocket(), (endpoint) ->
|
TrackingSocket socket = performOnMessageInvocation(new MessageStreamSocket(), (endpoint) ->
|
||||||
{
|
{
|
||||||
endpoint.onText(BufferUtil.toBuffer("Hello World", StandardCharsets.UTF_8), true);
|
endpoint.onText(new TextFrame().setPayload("Hello World").setFin(true), new FrameCallback.Adapter());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
socket.assertEvent("onMessage(MessageReader) = \"Hello World\"");
|
socket.assertEvent("onMessage(MessageReader) = \"Hello World\"");
|
||||||
|
@ -161,7 +161,7 @@ public class JsrServerEndpointFunctions_OnMessage_TextStreamTest
|
||||||
{
|
{
|
||||||
TrackingSocket socket = performOnMessageInvocation(new MessageStreamParamSocket(), (endpoint) ->
|
TrackingSocket socket = performOnMessageInvocation(new MessageStreamParamSocket(), (endpoint) ->
|
||||||
{
|
{
|
||||||
endpoint.onText(BufferUtil.toBuffer("Hello World", StandardCharsets.UTF_8), true);
|
endpoint.onText(new TextFrame().setPayload("Hello World").setFin(true), new FrameCallback.Adapter());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
socket.assertEvent("onMessage(MessageReader,foo) = \"Hello World\"");
|
socket.assertEvent("onMessage(MessageReader,foo) = \"Hello World\"");
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2017 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.api;
|
||||||
|
|
||||||
|
public interface FrameCallback
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Callback invoked when the frame fails.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param cause the reason for the frame failure
|
||||||
|
*/
|
||||||
|
void fail(Throwable cause);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Callback invoked when the frame read/write completes.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see #fail(Throwable)
|
||||||
|
*/
|
||||||
|
void succeed();
|
||||||
|
|
||||||
|
class Adapter implements FrameCallback
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void fail(Throwable cause)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void succeed()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -107,7 +107,7 @@ public interface Session extends Closeable
|
||||||
*
|
*
|
||||||
* @return the local side address
|
* @return the local side address
|
||||||
*/
|
*/
|
||||||
public InetSocketAddress getLocalAddress();
|
InetSocketAddress getLocalAddress();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access the (now read-only) {@link WebSocketPolicy} in use for this connection.
|
* Access the (now read-only) {@link WebSocketPolicy} in use for this connection.
|
||||||
|
@ -136,7 +136,7 @@ public interface Session extends Closeable
|
||||||
*
|
*
|
||||||
* @return the remote side address
|
* @return the remote side address
|
||||||
*/
|
*/
|
||||||
public InetSocketAddress getRemoteAddress();
|
InetSocketAddress getRemoteAddress();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the UpgradeRequest used to create this session
|
* Get the UpgradeRequest used to create this session
|
||||||
|
@ -157,7 +157,7 @@ public interface Session extends Closeable
|
||||||
*
|
*
|
||||||
* @return whether the session is open
|
* @return whether the session is open
|
||||||
*/
|
*/
|
||||||
abstract boolean isOpen();
|
boolean isOpen();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if and only if the underlying socket is using a secure transport.
|
* Return true if and only if the underlying socket is using a secure transport.
|
||||||
|
|
|
@ -59,6 +59,9 @@ public class WebSocketPolicy
|
||||||
* Default: 32768 (32 K)
|
* Default: 32768 (32 K)
|
||||||
*/
|
*/
|
||||||
private int maxTextMessageBufferSize = 32 * KB;
|
private int maxTextMessageBufferSize = 32 * KB;
|
||||||
|
|
||||||
|
private int maxTextFramePayloadSize; // TODO
|
||||||
|
private int maxBinaryFramePayloadSize; // TODO
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum size of a binary message during parsing/generating.
|
* The maximum size of a binary message during parsing/generating.
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.eclipse.jetty.websocket.api;
|
||||||
/**
|
/**
|
||||||
* Callback for Write events.
|
* Callback for Write events.
|
||||||
*/
|
*/
|
||||||
public interface WriteCallback
|
public interface WriteCallback extends FrameCallback
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* NOTE: We don't expose org.eclipse.jetty.util.Callback here as that would complicate matters with the WebAppContext's classloader isolation.
|
* NOTE: We don't expose org.eclipse.jetty.util.Callback here as that would complicate matters with the WebAppContext's classloader isolation.
|
||||||
|
@ -35,7 +35,7 @@ public interface WriteCallback
|
||||||
* @param x
|
* @param x
|
||||||
* the reason for the write failure
|
* the reason for the write failure
|
||||||
*/
|
*/
|
||||||
public void writeFailed(Throwable x);
|
void writeFailed(Throwable x);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -44,5 +44,17 @@ public interface WriteCallback
|
||||||
*
|
*
|
||||||
* @see #writeFailed(Throwable)
|
* @see #writeFailed(Throwable)
|
||||||
*/
|
*/
|
||||||
public abstract void writeSuccess();
|
void writeSuccess();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void fail(Throwable cause)
|
||||||
|
{
|
||||||
|
writeFailed(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void succeed()
|
||||||
|
{
|
||||||
|
writeSuccess();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,14 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.api.extensions;
|
package org.eclipse.jetty.websocket.api.extensions;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for dealing with Incoming Frames.
|
* Interface for dealing with Incoming Frames.
|
||||||
*/
|
*/
|
||||||
public interface IncomingFrames
|
public interface IncomingFrames
|
||||||
{
|
{
|
||||||
public void incomingError(Throwable t);
|
void incomingError(Throwable t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the incoming frame.
|
* Process the incoming frame.
|
||||||
|
@ -34,5 +36,29 @@ public interface IncomingFrames
|
||||||
*
|
*
|
||||||
* @param frame the frame to process
|
* @param frame the frame to process
|
||||||
*/
|
*/
|
||||||
public void incomingFrame(Frame frame);
|
// @Deprecated
|
||||||
|
// void incomingFrame(Frame frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the incoming frame.
|
||||||
|
* <p>
|
||||||
|
* Note: if you need to hang onto any information from the frame, be sure
|
||||||
|
* to copy it, as the information contained in the Frame will be released
|
||||||
|
* and/or reused by the implementation.
|
||||||
|
*
|
||||||
|
* @param frame the frame to process
|
||||||
|
* @param callback the read completion
|
||||||
|
*/
|
||||||
|
default void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//xincomingFrame(frame);
|
||||||
|
callback.succeed();
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
callback.fail(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
package org.eclipse.jetty.websocket.api.extensions;
|
package org.eclipse.jetty.websocket.api.extensions;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for dealing with frames outgoing to (eventually) the network layer.
|
* Interface for dealing with frames outgoing to (eventually) the network layer.
|
||||||
|
@ -39,6 +39,5 @@ public interface OutgoingFrames
|
||||||
* @param callback the callback to notify when the frame is written.
|
* @param callback the callback to notify when the frame is written.
|
||||||
* @param batchMode the batch mode requested by the sender.
|
* @param batchMode the batch mode requested by the sender.
|
||||||
*/
|
*/
|
||||||
void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode);
|
void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -564,20 +564,7 @@ public class WebSocketUpgradeRequest extends HttpRequest implements CompleteList
|
||||||
{
|
{
|
||||||
throw new HttpResponseException("Invalid Sec-WebSocket-Accept hash",response);
|
throw new HttpResponseException("Invalid Sec-WebSocket-Accept hash",response);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can upgrade
|
|
||||||
EndPoint endp = oldConn.getEndPoint();
|
|
||||||
|
|
||||||
WebSocketClientConnection connection = new WebSocketClientConnection(endp,wsClient.getExecutor(),wsClient.getScheduler(),localEndpoint.getPolicy(),
|
|
||||||
wsClient.getBufferPool());
|
|
||||||
|
|
||||||
URI requestURI = this.getURI();
|
|
||||||
|
|
||||||
WebSocketSession session = getSessionFactory().createSession(requestURI,localEndpoint,connection);
|
|
||||||
session.setUpgradeRequest(new ClientUpgradeRequest(this));
|
|
||||||
session.setUpgradeResponse(new ClientUpgradeResponse(response));
|
|
||||||
connection.addListener(session);
|
|
||||||
|
|
||||||
ExtensionStack extensionStack = new ExtensionStack(getExtensionFactory());
|
ExtensionStack extensionStack = new ExtensionStack(getExtensionFactory());
|
||||||
List<ExtensionConfig> extensions = new ArrayList<>();
|
List<ExtensionConfig> extensions = new ArrayList<>();
|
||||||
HttpField extField = response.getHeaders().getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS);
|
HttpField extField = response.getHeaders().getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS);
|
||||||
|
@ -597,12 +584,21 @@ public class WebSocketUpgradeRequest extends HttpRequest implements CompleteList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extensionStack.negotiate(extensions);
|
extensionStack.negotiate(extensions);
|
||||||
|
|
||||||
|
// We can upgrade
|
||||||
|
EndPoint endp = oldConn.getEndPoint();
|
||||||
|
|
||||||
extensionStack.configure(connection.getParser());
|
WebSocketClientConnection connection = new WebSocketClientConnection(endp,wsClient.getExecutor(),wsClient.getScheduler(),wsClient.getPolicy(),
|
||||||
extensionStack.configure(connection.getGenerator());
|
wsClient.getBufferPool(), extensionStack);
|
||||||
|
|
||||||
|
URI requestURI = this.getURI();
|
||||||
|
|
||||||
|
WebSocketSession session = getSessionFactory().createSession(requestURI,localEndpoint,connection);
|
||||||
|
session.setUpgradeRequest(new ClientUpgradeRequest(this));
|
||||||
|
session.setUpgradeResponse(new ClientUpgradeResponse(response));
|
||||||
|
connection.addListener(session);
|
||||||
|
|
||||||
// Setup Incoming Routing
|
// Setup Incoming Routing
|
||||||
connection.setNextIncomingFrames(extensionStack);
|
|
||||||
extensionStack.setNextIncoming(session);
|
extensionStack.setNextIncoming(session);
|
||||||
|
|
||||||
// Setup Outgoing Routing
|
// Setup Outgoing Routing
|
||||||
|
|
|
@ -25,13 +25,13 @@ import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
|
||||||
import org.eclipse.jetty.websocket.client.masks.Masker;
|
import org.eclipse.jetty.websocket.client.masks.Masker;
|
||||||
import org.eclipse.jetty.websocket.client.masks.RandomMasker;
|
import org.eclipse.jetty.websocket.client.masks.RandomMasker;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
|
import org.eclipse.jetty.websocket.common.extensions.ExtensionStack;
|
||||||
import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection;
|
import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,9 +41,9 @@ public class WebSocketClientConnection extends AbstractWebSocketConnection
|
||||||
{
|
{
|
||||||
private final Masker masker;
|
private final Masker masker;
|
||||||
|
|
||||||
public WebSocketClientConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy websocketPolicy, ByteBufferPool bufferPool)
|
public WebSocketClientConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy websocketPolicy, ByteBufferPool bufferPool, ExtensionStack extensionStack)
|
||||||
{
|
{
|
||||||
super(endp,executor,scheduler,websocketPolicy,bufferPool);
|
super(endp,executor,scheduler,websocketPolicy,bufferPool, extensionStack);
|
||||||
this.masker = new RandomMasker();
|
this.masker = new RandomMasker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ public class WebSocketClientConnection extends AbstractWebSocketConnection
|
||||||
* Override to set the masker.
|
* Override to set the masker.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
if (frame instanceof WebSocketFrame)
|
if (frame instanceof WebSocketFrame)
|
||||||
{
|
{
|
||||||
|
@ -71,10 +71,4 @@ public class WebSocketClientConnection extends AbstractWebSocketConnection
|
||||||
}
|
}
|
||||||
super.outgoingFrame(frame,callback, batchMode);
|
super.outgoingFrame(frame,callback, batchMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNextIncomingFrames(IncomingFrames incoming)
|
|
||||||
{
|
|
||||||
getParser().setIncomingFramesHandler(incoming);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -451,11 +451,16 @@ public class ClientConnectTest
|
||||||
}
|
}
|
||||||
catch (ExecutionException e)
|
catch (ExecutionException e)
|
||||||
{
|
{
|
||||||
assertExpectedError(e, wsocket,
|
if (OS.IS_WINDOWS)
|
||||||
anyOf(
|
{
|
||||||
instanceOf(UpgradeException.class),
|
// On windows, this is a SocketTimeoutException
|
||||||
instanceOf(SocketTimeoutException.class),
|
assertExpectedError(e, wsocket, SocketTimeoutException.class);
|
||||||
instanceOf(ConnectException.class)));
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Expected path - java.net.ConnectException
|
||||||
|
assertExpectedError(e, wsocket, ConnectException.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.io.IOException;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
import org.eclipse.jetty.util.SharedBlockingCallback;
|
import org.eclipse.jetty.util.SharedBlockingCallback;
|
||||||
import org.eclipse.jetty.util.thread.Invocable.InvocationType;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.WriteCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,7 +39,7 @@ public class BlockingWriteCallback extends SharedBlockingCallback
|
||||||
return new WriteBlocker(acquire());
|
return new WriteBlocker(acquire());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WriteBlocker implements WriteCallback, Callback, AutoCloseable
|
public static class WriteBlocker implements FrameCallback, Callback, AutoCloseable
|
||||||
{
|
{
|
||||||
private final Blocker blocker;
|
private final Blocker blocker;
|
||||||
|
|
||||||
|
@ -54,15 +54,15 @@ public class BlockingWriteCallback extends SharedBlockingCallback
|
||||||
// The callback does not block, only the writer blocks
|
// The callback does not block, only the writer blocks
|
||||||
return InvocationType.NON_BLOCKING;
|
return InvocationType.NON_BLOCKING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeFailed(Throwable x)
|
public void fail(Throwable cause)
|
||||||
{
|
{
|
||||||
blocker.failed(x);
|
blocker.failed(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSuccess()
|
public void succeed()
|
||||||
{
|
{
|
||||||
blocker.succeeded();
|
blocker.succeeded();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.util.concurrent.Executor;
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.websocket.api.SuspendToken;
|
import org.eclipse.jetty.websocket.api.SuspendToken;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
import org.eclipse.jetty.websocket.common.io.IOState;
|
import org.eclipse.jetty.websocket.common.io.IOState;
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ public interface LogicalConnection extends OutgoingFrames, SuspendToken
|
||||||
* @see org.eclipse.jetty.websocket.api.StatusCode
|
* @see org.eclipse.jetty.websocket.api.StatusCode
|
||||||
* @see #close(int, String)
|
* @see #close(int, String)
|
||||||
*/
|
*/
|
||||||
public void close();
|
void close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a websocket Close frame, with status code.
|
* Send a websocket Close frame, with status code.
|
||||||
|
@ -51,7 +50,7 @@ public interface LogicalConnection extends OutgoingFrames, SuspendToken
|
||||||
* the (optional) reason. (can be null for no reason)
|
* the (optional) reason. (can be null for no reason)
|
||||||
* @see org.eclipse.jetty.websocket.api.StatusCode
|
* @see org.eclipse.jetty.websocket.api.StatusCode
|
||||||
*/
|
*/
|
||||||
public void close(int statusCode, String reason);
|
void close(int statusCode, String reason);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terminate the connection (no close frame sent)
|
* Terminate the connection (no close frame sent)
|
||||||
|
@ -75,7 +74,7 @@ public interface LogicalConnection extends OutgoingFrames, SuspendToken
|
||||||
*
|
*
|
||||||
* @return the idle timeout in milliseconds
|
* @return the idle timeout in milliseconds
|
||||||
*/
|
*/
|
||||||
public long getIdleTimeout();
|
long getIdleTimeout();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the IOState of the connection.
|
* Get the IOState of the connection.
|
||||||
|
@ -120,7 +119,7 @@ public interface LogicalConnection extends OutgoingFrames, SuspendToken
|
||||||
*
|
*
|
||||||
* @return true if connection is open
|
* @return true if connection is open
|
||||||
*/
|
*/
|
||||||
public boolean isOpen();
|
boolean isOpen();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if the connection is actively reading.
|
* Tests if the connection is actively reading.
|
||||||
|
@ -140,16 +139,6 @@ public interface LogicalConnection extends OutgoingFrames, SuspendToken
|
||||||
*/
|
*/
|
||||||
void setMaxIdleTimeout(long ms);
|
void setMaxIdleTimeout(long ms);
|
||||||
|
|
||||||
/**
|
|
||||||
* Set where the connection should send the incoming frames to.
|
|
||||||
* <p>
|
|
||||||
* Often this is from the Parser to the start of the extension stack, and eventually on to the session.
|
|
||||||
*
|
|
||||||
* @param incoming
|
|
||||||
* the incoming frames handler
|
|
||||||
*/
|
|
||||||
void setNextIncomingFrames(IncomingFrames incoming);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suspend a the incoming read events on the connection.
|
* Suspend a the incoming read events on the connection.
|
||||||
* @return the suspend token
|
* @return the suspend token
|
||||||
|
@ -160,5 +149,5 @@ public interface LogicalConnection extends OutgoingFrames, SuspendToken
|
||||||
* Get Unique ID for the Connection
|
* Get Unique ID for the Connection
|
||||||
* @return the unique ID for the connection
|
* @return the unique ID for the connection
|
||||||
*/
|
*/
|
||||||
public String getId();
|
String getId();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
|
||||||
import org.eclipse.jetty.websocket.common.frames.BinaryFrame;
|
import org.eclipse.jetty.websocket.common.frames.BinaryFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.CloseFrame;
|
import org.eclipse.jetty.websocket.common.frames.CloseFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.ContinuationFrame;
|
import org.eclipse.jetty.websocket.common.frames.ContinuationFrame;
|
||||||
|
@ -48,6 +47,11 @@ import org.eclipse.jetty.websocket.common.io.payload.PayloadProcessor;
|
||||||
*/
|
*/
|
||||||
public class Parser
|
public class Parser
|
||||||
{
|
{
|
||||||
|
public interface Handler
|
||||||
|
{
|
||||||
|
void onFrame(Frame frame);
|
||||||
|
}
|
||||||
|
|
||||||
private enum State
|
private enum State
|
||||||
{
|
{
|
||||||
START,
|
START,
|
||||||
|
@ -61,6 +65,7 @@ public class Parser
|
||||||
private static final Logger LOG = Log.getLogger(Parser.class);
|
private static final Logger LOG = Log.getLogger(Parser.class);
|
||||||
private final WebSocketPolicy policy;
|
private final WebSocketPolicy policy;
|
||||||
private final ByteBufferPool bufferPool;
|
private final ByteBufferPool bufferPool;
|
||||||
|
private final Parser.Handler parserHandler;
|
||||||
|
|
||||||
// State specific
|
// State specific
|
||||||
private State state = State.START;
|
private State state = State.START;
|
||||||
|
@ -86,14 +91,13 @@ public class Parser
|
||||||
*/
|
*/
|
||||||
private byte flagsInUse=0x00;
|
private byte flagsInUse=0x00;
|
||||||
|
|
||||||
private IncomingFrames incomingFramesHandler;
|
public Parser(WebSocketPolicy wspolicy, ByteBufferPool bufferPool, Parser.Handler parserHandler)
|
||||||
|
|
||||||
public Parser(WebSocketPolicy wspolicy, ByteBufferPool bufferPool)
|
|
||||||
{
|
{
|
||||||
this.bufferPool = bufferPool;
|
this.bufferPool = bufferPool;
|
||||||
this.policy = wspolicy;
|
this.policy = wspolicy;
|
||||||
|
this.parserHandler = parserHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertSanePayloadLength(long len)
|
private void assertSanePayloadLength(long len)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
|
@ -124,9 +128,13 @@ public class Parser
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OpCode.TEXT:
|
case OpCode.TEXT:
|
||||||
|
// Quick failure for frames that already exceed messages size limits
|
||||||
|
// TODO: based on buffer limits
|
||||||
policy.assertValidTextMessageSize((int)len);
|
policy.assertValidTextMessageSize((int)len);
|
||||||
break;
|
break;
|
||||||
case OpCode.BINARY:
|
case OpCode.BINARY:
|
||||||
|
// Quick failure for frames that already exceed messages size limits
|
||||||
|
// TODO: based on buffer limits
|
||||||
policy.assertValidBinaryMessageSize((int)len);
|
policy.assertValidBinaryMessageSize((int)len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -155,11 +163,6 @@ public class Parser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IncomingFrames getIncomingFramesHandler()
|
|
||||||
{
|
|
||||||
return incomingFramesHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebSocketPolicy getPolicy()
|
public WebSocketPolicy getPolicy()
|
||||||
{
|
{
|
||||||
return policy;
|
return policy;
|
||||||
|
@ -182,8 +185,6 @@ public class Parser
|
||||||
|
|
||||||
protected void notifyFrame(final Frame f)
|
protected void notifyFrame(final Frame f)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("{} Notify {}",policy.getBehavior(),getIncomingFramesHandler());
|
|
||||||
|
|
||||||
if (policy.getBehavior() == WebSocketBehavior.SERVER)
|
if (policy.getBehavior() == WebSocketBehavior.SERVER)
|
||||||
{
|
{
|
||||||
|
@ -211,33 +212,7 @@ public class Parser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (incomingFramesHandler == null)
|
this.parserHandler.onFrame(f);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
incomingFramesHandler.incomingFrame(f);
|
|
||||||
}
|
|
||||||
catch (WebSocketException e)
|
|
||||||
{
|
|
||||||
notifyWebSocketException(e);
|
|
||||||
}
|
|
||||||
catch (Throwable t)
|
|
||||||
{
|
|
||||||
LOG.warn(t);
|
|
||||||
notifyWebSocketException(new WebSocketException(t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void notifyWebSocketException(WebSocketException e)
|
|
||||||
{
|
|
||||||
LOG.warn(e);
|
|
||||||
if (incomingFramesHandler == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
incomingFramesHandler.incomingError(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parse(ByteBuffer buffer) throws WebSocketException
|
public void parse(ByteBuffer buffer) throws WebSocketException
|
||||||
|
@ -261,24 +236,19 @@ public class Parser
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (WebSocketException e)
|
|
||||||
{
|
|
||||||
buffer.position(buffer.limit()); // consume remaining
|
|
||||||
reset();
|
|
||||||
// let session know
|
|
||||||
notifyWebSocketException(e);
|
|
||||||
// need to throw for proper close behavior in connection
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
catch (Throwable t)
|
catch (Throwable t)
|
||||||
{
|
{
|
||||||
buffer.position(buffer.limit()); // consume remaining
|
buffer.position(buffer.limit()); // consume remaining
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
// let session know
|
// let session know
|
||||||
WebSocketException e = new WebSocketException(t);
|
WebSocketException wse;
|
||||||
notifyWebSocketException(e);
|
if(t instanceof WebSocketException)
|
||||||
// need to throw for proper close behavior in connection
|
wse = (WebSocketException) t;
|
||||||
throw e;
|
else
|
||||||
|
wse = new WebSocketException(t);
|
||||||
|
|
||||||
|
throw wse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,14 +263,10 @@ public class Parser
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the base framing protocol buffer.
|
* Parse the base framing protocol buffer.
|
||||||
* <p>
|
*
|
||||||
* Note the first byte (fin,rsv1,rsv2,rsv3,opcode) are parsed by the {@link Parser#parse(ByteBuffer)} method
|
|
||||||
* <p>
|
|
||||||
* Not overridable
|
|
||||||
*
|
|
||||||
* @param buffer
|
* @param buffer
|
||||||
* the buffer to parse from.
|
* the buffer to parse from.
|
||||||
* @return true if done parsing base framing protocol and ready for parsing of the payload. false if incomplete parsing of base framing protocol.
|
* @return true if done parsing a whole frame. false if incomplete/partial parsing of frame.
|
||||||
*/
|
*/
|
||||||
private boolean parseFrame(ByteBuffer buffer)
|
private boolean parseFrame(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
|
@ -650,30 +616,16 @@ public class Parser
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIncomingFramesHandler(IncomingFrames incoming)
|
|
||||||
{
|
|
||||||
this.incomingFramesHandler = incoming;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("Parser@").append(Integer.toHexString(hashCode()));
|
builder.append("Parser@").append(Integer.toHexString(hashCode()));
|
||||||
builder.append("[");
|
builder.append("[").append(policy.getBehavior());
|
||||||
if (incomingFramesHandler == null)
|
|
||||||
{
|
|
||||||
builder.append("NO_HANDLER");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
builder.append(incomingFramesHandler.getClass().getSimpleName());
|
|
||||||
}
|
|
||||||
builder.append(",s=").append(state);
|
builder.append(",s=").append(state);
|
||||||
builder.append(",c=").append(cursor);
|
builder.append(",c=").append(cursor);
|
||||||
builder.append(",len=").append(payloadLength);
|
builder.append(",len=").append(payloadLength);
|
||||||
builder.append(",f=").append(frame);
|
builder.append(",f=").append(frame);
|
||||||
// builder.append(",p=").append(policy);
|
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.WriteCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
|
@ -299,7 +300,7 @@ public class WebSocketRemoteEndpoint implements RemoteEndpoint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uncheckedSendFrame(WebSocketFrame frame, WriteCallback callback)
|
public void uncheckedSendFrame(WebSocketFrame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -311,7 +312,7 @@ public class WebSocketRemoteEndpoint implements RemoteEndpoint
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
callback.writeFailed(e);
|
callback.fail(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ import org.eclipse.jetty.util.thread.ThreadClassLoaderScope;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.CloseException;
|
import org.eclipse.jetty.websocket.api.CloseException;
|
||||||
import org.eclipse.jetty.websocket.api.CloseStatus;
|
import org.eclipse.jetty.websocket.api.CloseStatus;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
|
@ -383,12 +384,12 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
||||||
// Forward Errors to User WebSocket Object
|
// Forward Errors to User WebSocket Object
|
||||||
endpointFunctions.onError(t);
|
endpointFunctions.onError(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Incoming Raw Frames from Parser
|
* Incoming Raw Frames from Parser (after ExtensionStack)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||||
try
|
try
|
||||||
|
@ -396,6 +397,8 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
||||||
Thread.currentThread().setContextClassLoader(classLoader);
|
Thread.currentThread().setContextClassLoader(classLoader);
|
||||||
if (connection.getIOState().isInputAvailable())
|
if (connection.getIOState().isInputAvailable())
|
||||||
{
|
{
|
||||||
|
// For endpoints that want to see raw frames.
|
||||||
|
// These are immutable.
|
||||||
endpointFunctions.onFrame(frame);
|
endpointFunctions.onFrame(frame);
|
||||||
|
|
||||||
byte opcode = frame.getOpCode();
|
byte opcode = frame.getOpCode();
|
||||||
|
@ -409,6 +412,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
||||||
|
|
||||||
// process handshake
|
// process handshake
|
||||||
getConnection().getIOState().onCloseRemote(close);
|
getConnection().getIOState().onCloseRemote(close);
|
||||||
|
callback.succeed();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -430,6 +434,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
||||||
}
|
}
|
||||||
|
|
||||||
endpointFunctions.onPing(frame.getPayload());
|
endpointFunctions.onPing(frame.getPayload());
|
||||||
|
callback.succeed();
|
||||||
|
|
||||||
getRemote().sendPong(pongBuf);
|
getRemote().sendPong(pongBuf);
|
||||||
break;
|
break;
|
||||||
|
@ -440,23 +445,24 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
||||||
LOG.debug("PONG: {}", BufferUtil.toDetailString(frame.getPayload()));
|
LOG.debug("PONG: {}", BufferUtil.toDetailString(frame.getPayload()));
|
||||||
|
|
||||||
endpointFunctions.onPong(frame.getPayload());
|
endpointFunctions.onPong(frame.getPayload());
|
||||||
|
callback.succeed();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpCode.BINARY:
|
case OpCode.BINARY:
|
||||||
{
|
{
|
||||||
endpointFunctions.onBinary(frame.getPayload(), frame.isFin());
|
endpointFunctions.onBinary(frame, callback);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case OpCode.TEXT:
|
case OpCode.TEXT:
|
||||||
{
|
{
|
||||||
endpointFunctions.onText(frame.getPayload(), frame.isFin());
|
endpointFunctions.onText(frame, callback);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case OpCode.CONTINUATION:
|
case OpCode.CONTINUATION:
|
||||||
{
|
{
|
||||||
endpointFunctions.onContinuation(frame.getPayload(), frame.isFin());
|
endpointFunctions.onContinuation(frame, callback);
|
||||||
if (activeMessageSink != null)
|
if (activeMessageSink != null)
|
||||||
activeMessageSink.accept(frame.getPayload(), frame.isFin());
|
activeMessageSink.accept(frame, callback);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -475,6 +481,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
||||||
}
|
}
|
||||||
catch (NotUtf8Exception e)
|
catch (NotUtf8Exception e)
|
||||||
{
|
{
|
||||||
|
callback.fail(e);
|
||||||
notifyError(e);
|
notifyError(e);
|
||||||
close(StatusCode.BAD_PAYLOAD, e.getMessage());
|
close(StatusCode.BAD_PAYLOAD, e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -487,9 +494,11 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
||||||
Throwable cause = getInvokedCause(t);
|
Throwable cause = getInvokedCause(t);
|
||||||
|
|
||||||
LOG.warn("Unhandled Error (closing connection)", cause);
|
LOG.warn("Unhandled Error (closing connection)", cause);
|
||||||
|
|
||||||
|
callback.fail(cause);
|
||||||
|
|
||||||
notifyError(cause);
|
notifyError(cause);
|
||||||
|
|
||||||
// Unhandled Error, close the connection.
|
// Unhandled Error, close the connection.
|
||||||
switch (getPolicy().getBehavior())
|
switch (getPolicy().getBehavior())
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,8 +29,8 @@ import org.eclipse.jetty.util.component.Dumpable;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
@ -176,13 +176,13 @@ public abstract class AbstractExtension extends AbstractLifeCycle implements Dum
|
||||||
this.nextIncoming.incomingError(e);
|
this.nextIncoming.incomingError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void nextIncomingFrame(Frame frame)
|
protected void nextIncomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
log.debug("nextIncomingFrame({})",frame);
|
log.debug("nextIncomingFrame({})",frame);
|
||||||
this.nextIncoming.incomingFrame(frame);
|
this.nextIncoming.incomingFrame(frame, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void nextOutgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
protected void nextOutgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
log.debug("nextOutgoingFrame({})",frame);
|
log.debug("nextOutgoingFrame({})",frame);
|
||||||
this.nextOutgoing.outgoingFrame(frame,callback, batchMode);
|
this.nextOutgoing.outgoingFrame(frame,callback, batchMode);
|
||||||
|
|
|
@ -33,8 +33,8 @@ import org.eclipse.jetty.util.component.LifeCycle;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||||
|
@ -215,9 +215,9 @@ public class ExtensionStack extends ContainerLifeCycle implements IncomingFrames
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
nextIncoming.incomingFrame(frame);
|
nextIncoming.incomingFrame(frame, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -287,7 +287,7 @@ public class ExtensionStack extends ContainerLifeCycle implements IncomingFrames
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
FrameEntry entry = new FrameEntry(frame,callback,batchMode);
|
FrameEntry entry = new FrameEntry(frame,callback,batchMode);
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
|
@ -383,10 +383,10 @@ public class ExtensionStack extends ContainerLifeCycle implements IncomingFrames
|
||||||
private static class FrameEntry
|
private static class FrameEntry
|
||||||
{
|
{
|
||||||
private final Frame frame;
|
private final Frame frame;
|
||||||
private final WriteCallback callback;
|
private final FrameCallback callback;
|
||||||
private final BatchMode batchMode;
|
private final BatchMode batchMode;
|
||||||
|
|
||||||
private FrameEntry(Frame frame, WriteCallback callback, BatchMode batchMode)
|
private FrameEntry(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
@ -400,7 +400,7 @@ public class ExtensionStack extends ContainerLifeCycle implements IncomingFrames
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Flusher extends IteratingCallback implements WriteCallback
|
private class Flusher extends IteratingCallback implements FrameCallback
|
||||||
{
|
{
|
||||||
private FrameEntry current;
|
private FrameEntry current;
|
||||||
|
|
||||||
|
@ -433,34 +433,34 @@ public class ExtensionStack extends ContainerLifeCycle implements IncomingFrames
|
||||||
// The callback are those provided by WriteCallback (implemented
|
// The callback are those provided by WriteCallback (implemented
|
||||||
// below) and even in case of writeFailed() we call succeeded().
|
// below) and even in case of writeFailed() we call succeeded().
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSuccess()
|
public void succeed()
|
||||||
{
|
{
|
||||||
// Notify first then call succeeded(), otherwise
|
// Notify first then call succeeded(), otherwise
|
||||||
// write callbacks may be invoked out of order.
|
// write callbacks may be invoked out of order.
|
||||||
notifyCallbackSuccess(current.callback);
|
notifyCallbackSuccess(current.callback);
|
||||||
succeeded();
|
succeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeFailed(Throwable x)
|
public void fail(Throwable cause)
|
||||||
{
|
{
|
||||||
// Notify first, the call succeeded() to drain the queue.
|
// Notify first, the call succeeded() to drain the queue.
|
||||||
// We don't want to call failed(x) because that will put
|
// We don't want to call failed(x) because that will put
|
||||||
// this flusher into a final state that cannot be exited,
|
// this flusher into a final state that cannot be exited,
|
||||||
// and the failure of a frame may not mean that the whole
|
// and the failure of a frame may not mean that the whole
|
||||||
// connection is now invalid.
|
// connection is now invalid.
|
||||||
notifyCallbackFailure(current.callback,x);
|
notifyCallbackFailure(current.callback,cause);
|
||||||
succeeded();
|
succeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyCallbackSuccess(WriteCallback callback)
|
private void notifyCallbackSuccess(FrameCallback callback)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
|
@ -468,12 +468,12 @@ public class ExtensionStack extends ContainerLifeCycle implements IncomingFrames
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyCallbackFailure(WriteCallback callback, Throwable failure)
|
private void notifyCallbackFailure(FrameCallback callback, Throwable failure)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.writeFailed(failure);
|
callback.fail(failure);
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.WriteCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
|
@ -65,12 +66,12 @@ public class FrameCaptureExtension extends AbstractExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
saveFrame(frame,false);
|
saveFrame(frame,false);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
nextIncomingFrame(frame);
|
nextIncomingFrame(frame, callback);
|
||||||
}
|
}
|
||||||
catch (Throwable t)
|
catch (Throwable t)
|
||||||
{
|
{
|
||||||
|
@ -81,7 +82,7 @@ public class FrameCaptureExtension extends AbstractExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
saveFrame(frame,true);
|
saveFrame(frame,true);
|
||||||
try
|
try
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.eclipse.jetty.util.IteratingCallback;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
|
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
|
||||||
|
@ -127,7 +127,7 @@ public abstract class CompressExtension extends AbstractExtension
|
||||||
*/
|
*/
|
||||||
abstract int getRsvUseMode();
|
abstract int getRsvUseMode();
|
||||||
|
|
||||||
protected void forwardIncoming(Frame frame, ByteAccumulator accumulator)
|
protected void forwardIncoming(Frame frame, FrameCallback callback, ByteAccumulator accumulator)
|
||||||
{
|
{
|
||||||
DataFrame newFrame = new DataFrame(frame);
|
DataFrame newFrame = new DataFrame(frame);
|
||||||
// Unset RSV1 since it's not compressed anymore.
|
// Unset RSV1 since it's not compressed anymore.
|
||||||
|
@ -139,7 +139,7 @@ public abstract class CompressExtension extends AbstractExtension
|
||||||
BufferUtil.flipToFill(buffer);
|
BufferUtil.flipToFill(buffer);
|
||||||
accumulator.transferTo(buffer);
|
accumulator.transferTo(buffer);
|
||||||
newFrame.setPayload(buffer);
|
newFrame.setPayload(buffer);
|
||||||
nextIncomingFrame(newFrame);
|
nextIncomingFrame(newFrame, callback);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -199,7 +199,7 @@ public abstract class CompressExtension extends AbstractExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
// We use a queue and an IteratingCallback to handle concurrency.
|
// We use a queue and an IteratingCallback to handle concurrency.
|
||||||
// We must compress and write atomically, otherwise the compression
|
// We must compress and write atomically, otherwise the compression
|
||||||
|
@ -234,12 +234,12 @@ public abstract class CompressExtension extends AbstractExtension
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void notifyCallbackSuccess(WriteCallback callback)
|
protected void notifyCallbackSuccess(FrameCallback callback)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
|
@ -248,12 +248,12 @@ public abstract class CompressExtension extends AbstractExtension
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void notifyCallbackFailure(WriteCallback callback, Throwable failure)
|
protected void notifyCallbackFailure(FrameCallback callback, Throwable failure)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.writeFailed(failure);
|
callback.fail(failure);
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
|
@ -390,10 +390,10 @@ public abstract class CompressExtension extends AbstractExtension
|
||||||
private static class FrameEntry
|
private static class FrameEntry
|
||||||
{
|
{
|
||||||
private final Frame frame;
|
private final Frame frame;
|
||||||
private final WriteCallback callback;
|
private final FrameCallback callback;
|
||||||
private final BatchMode batchMode;
|
private final BatchMode batchMode;
|
||||||
|
|
||||||
private FrameEntry(Frame frame, WriteCallback callback, BatchMode batchMode)
|
private FrameEntry(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
@ -407,7 +407,7 @@ public abstract class CompressExtension extends AbstractExtension
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Flusher extends IteratingCallback implements WriteCallback
|
private class Flusher extends IteratingCallback implements FrameCallback
|
||||||
{
|
{
|
||||||
private FrameEntry current;
|
private FrameEntry current;
|
||||||
private boolean finished = true;
|
private boolean finished = true;
|
||||||
|
@ -564,22 +564,22 @@ public abstract class CompressExtension extends AbstractExtension
|
||||||
while ((entry = pollEntry()) != null)
|
while ((entry = pollEntry()) != null)
|
||||||
notifyCallbackFailure(entry.callback,x);
|
notifyCallbackFailure(entry.callback,x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSuccess()
|
public void succeed()
|
||||||
{
|
{
|
||||||
if (finished)
|
if (finished)
|
||||||
notifyCallbackSuccess(current.callback);
|
notifyCallbackSuccess(current.callback);
|
||||||
succeeded();
|
succeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeFailed(Throwable x)
|
public void fail(Throwable cause)
|
||||||
{
|
{
|
||||||
notifyCallbackFailure(current.callback,x);
|
notifyCallbackFailure(current.callback,cause);
|
||||||
// If something went wrong, very likely the compression context
|
// If something went wrong, very likely the compression context
|
||||||
// will be invalid, so we need to fail this IteratingCallback.
|
// will be invalid, so we need to fail this IteratingCallback.
|
||||||
failed(x);
|
failed(cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.common.extensions.compress;
|
||||||
import java.util.zip.DataFormatException;
|
import java.util.zip.DataFormatException;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.api.BadPayloadException;
|
import org.eclipse.jetty.websocket.api.BadPayloadException;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,7 +50,7 @@ public class DeflateFrameExtension extends CompressExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
// Incoming frames are always non concurrent because
|
// Incoming frames are always non concurrent because
|
||||||
// they are read and parsed with a single thread, and
|
// they are read and parsed with a single thread, and
|
||||||
|
@ -57,7 +58,7 @@ public class DeflateFrameExtension extends CompressExtension
|
||||||
|
|
||||||
if ( frame.getType().isControl() || !frame.isRsv1() || !frame.hasPayload() )
|
if ( frame.getType().isControl() || !frame.isRsv1() || !frame.hasPayload() )
|
||||||
{
|
{
|
||||||
nextIncomingFrame(frame);
|
nextIncomingFrame(frame, callback);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ public class DeflateFrameExtension extends CompressExtension
|
||||||
ByteAccumulator accumulator = newByteAccumulator();
|
ByteAccumulator accumulator = newByteAccumulator();
|
||||||
decompress(accumulator, frame.getPayload());
|
decompress(accumulator, frame.getPayload());
|
||||||
decompress(accumulator, TAIL_BYTES_BUF.slice());
|
decompress(accumulator, TAIL_BYTES_BUF.slice());
|
||||||
forwardIncoming(frame, accumulator);
|
forwardIncoming(frame, callback, accumulator);
|
||||||
}
|
}
|
||||||
catch (DataFormatException e)
|
catch (DataFormatException e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BadPayloadException;
|
import org.eclipse.jetty.websocket.api.BadPayloadException;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
|
@ -52,7 +52,7 @@ public class PerMessageDeflateExtension extends CompressExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
// Incoming frames are always non concurrent because
|
// Incoming frames are always non concurrent because
|
||||||
// they are read and parsed with a single thread, and
|
// they are read and parsed with a single thread, and
|
||||||
|
@ -67,7 +67,7 @@ public class PerMessageDeflateExtension extends CompressExtension
|
||||||
|
|
||||||
if (OpCode.isControlFrame(frame.getOpCode()) || !incomingCompressed)
|
if (OpCode.isControlFrame(frame.getOpCode()) || !incomingCompressed)
|
||||||
{
|
{
|
||||||
nextIncomingFrame(frame);
|
nextIncomingFrame(frame, callback);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ public class PerMessageDeflateExtension extends CompressExtension
|
||||||
decompress(accumulator, TAIL_BYTES_BUF.slice());
|
decompress(accumulator, TAIL_BYTES_BUF.slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
forwardIncoming(frame, accumulator);
|
forwardIncoming(frame, callback, accumulator);
|
||||||
}
|
}
|
||||||
catch (DataFormatException e)
|
catch (DataFormatException e)
|
||||||
{
|
{
|
||||||
|
@ -94,7 +94,7 @@ public class PerMessageDeflateExtension extends CompressExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void nextIncomingFrame(Frame frame)
|
protected void nextIncomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
if (frame.isFin() && !incomingContextTakeover)
|
if (frame.isFin() && !incomingContextTakeover)
|
||||||
{
|
{
|
||||||
|
@ -102,11 +102,11 @@ public class PerMessageDeflateExtension extends CompressExtension
|
||||||
decompressCount.set(0);
|
decompressCount.set(0);
|
||||||
getInflater().reset();
|
getInflater().reset();
|
||||||
}
|
}
|
||||||
super.nextIncomingFrame(frame);
|
super.nextIncomingFrame(frame, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void nextOutgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
protected void nextOutgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
if (frame.isFin() && !outgoingContextTakeover)
|
if (frame.isFin() && !outgoingContextTakeover)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.eclipse.jetty.util.IteratingCallback;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
|
@ -52,13 +52,13 @@ public class FragmentExtension extends AbstractExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
nextIncomingFrame(frame);
|
nextIncomingFrame(frame, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
ByteBuffer payload = frame.getPayload();
|
ByteBuffer payload = frame.getPayload();
|
||||||
int length = payload != null ? payload.remaining() : 0;
|
int length = payload != null ? payload.remaining() : 0;
|
||||||
|
@ -101,10 +101,10 @@ public class FragmentExtension extends AbstractExtension
|
||||||
private static class FrameEntry
|
private static class FrameEntry
|
||||||
{
|
{
|
||||||
private final Frame frame;
|
private final Frame frame;
|
||||||
private final WriteCallback callback;
|
private final FrameCallback callback;
|
||||||
private final BatchMode batchMode;
|
private final BatchMode batchMode;
|
||||||
|
|
||||||
private FrameEntry(Frame frame, WriteCallback callback, BatchMode batchMode)
|
private FrameEntry(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
@ -118,7 +118,7 @@ public class FragmentExtension extends AbstractExtension
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Flusher extends IteratingCallback implements WriteCallback
|
private class Flusher extends IteratingCallback implements FrameCallback
|
||||||
{
|
{
|
||||||
private FrameEntry current;
|
private FrameEntry current;
|
||||||
private boolean finished = true;
|
private boolean finished = true;
|
||||||
|
@ -180,34 +180,34 @@ public class FragmentExtension extends AbstractExtension
|
||||||
// The callback are those provided by WriteCallback (implemented
|
// The callback are those provided by WriteCallback (implemented
|
||||||
// below) and even in case of writeFailed() we call succeeded().
|
// below) and even in case of writeFailed() we call succeeded().
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSuccess()
|
public void succeed()
|
||||||
{
|
{
|
||||||
// Notify first then call succeeded(), otherwise
|
// Notify first then call succeeded(), otherwise
|
||||||
// write callbacks may be invoked out of order.
|
// write callbacks may be invoked out of order.
|
||||||
notifyCallbackSuccess(current.callback);
|
notifyCallbackSuccess(current.callback);
|
||||||
succeeded();
|
succeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeFailed(Throwable x)
|
public void fail(Throwable cause)
|
||||||
{
|
{
|
||||||
// Notify first, the call succeeded() to drain the queue.
|
// Notify first, the call succeeded() to drain the queue.
|
||||||
// We don't want to call failed(x) because that will put
|
// We don't want to call failed(x) because that will put
|
||||||
// this flusher into a final state that cannot be exited,
|
// this flusher into a final state that cannot be exited,
|
||||||
// and the failure of a frame may not mean that the whole
|
// and the failure of a frame may not mean that the whole
|
||||||
// connection is now invalid.
|
// connection is now invalid.
|
||||||
notifyCallbackFailure(current.callback, x);
|
notifyCallbackFailure(current.callback, cause);
|
||||||
succeeded();
|
succeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyCallbackSuccess(WriteCallback callback)
|
private void notifyCallbackSuccess(FrameCallback callback)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
|
@ -216,12 +216,12 @@ public class FragmentExtension extends AbstractExtension
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyCallbackFailure(WriteCallback callback, Throwable failure)
|
private void notifyCallbackFailure(FrameCallback callback, Throwable failure)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.writeFailed(failure);
|
callback.fail(failure);
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.eclipse.jetty.websocket.common.extensions.identity;
|
||||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
|
import org.eclipse.jetty.websocket.common.extensions.AbstractExtension;
|
||||||
|
@ -50,14 +50,14 @@ public class IdentityExtension extends AbstractExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
// pass through
|
// pass through
|
||||||
nextIncomingFrame(frame);
|
nextIncomingFrame(frame, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
// pass through
|
// pass through
|
||||||
nextOutgoingFrame(frame,callback, batchMode);
|
nextOutgoingFrame(frame,callback, batchMode);
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketConnectionListener;
|
import org.eclipse.jetty.websocket.api.WebSocketConnectionListener;
|
||||||
|
@ -702,42 +703,42 @@ public class CommonEndpointFunctions<T extends Session> extends AbstractLifeCycl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onText(ByteBuffer payload, boolean fin)
|
public void onText(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
assertIsStarted();
|
assertIsStarted();
|
||||||
|
|
||||||
if (activeMessageSink == null)
|
if (activeMessageSink == null)
|
||||||
activeMessageSink = onTextSink;
|
activeMessageSink = onTextSink;
|
||||||
|
|
||||||
acceptMessage(payload, fin);
|
acceptMessage(frame, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBinary(ByteBuffer payload, boolean fin)
|
public void onBinary(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
assertIsStarted();
|
assertIsStarted();
|
||||||
|
|
||||||
if (activeMessageSink == null)
|
if (activeMessageSink == null)
|
||||||
activeMessageSink = onBinarySink;
|
activeMessageSink = onBinarySink;
|
||||||
|
|
||||||
acceptMessage(payload, fin);
|
acceptMessage(frame, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContinuation(ByteBuffer payload, boolean fin)
|
public void onContinuation(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
acceptMessage(payload, fin);
|
acceptMessage(frame, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void acceptMessage(ByteBuffer payload, boolean fin)
|
private void acceptMessage(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
// No message sink is active
|
// No message sink is active
|
||||||
if (activeMessageSink == null)
|
if (activeMessageSink == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Accept the payload into the message sink
|
// Accept the payload into the message sink
|
||||||
activeMessageSink.accept(payload, fin);
|
activeMessageSink.accept(frame, callback);
|
||||||
if (fin)
|
if (frame.isFin())
|
||||||
activeMessageSink = null;
|
activeMessageSink = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.common.function;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.component.LifeCycle;
|
import org.eclipse.jetty.util.component.LifeCycle;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
|
|
||||||
|
@ -39,11 +40,11 @@ public interface EndpointFunctions<T> extends LifeCycle
|
||||||
|
|
||||||
void onError(Throwable cause);
|
void onError(Throwable cause);
|
||||||
|
|
||||||
void onText(ByteBuffer payload, boolean fin);
|
void onText(Frame frame, FrameCallback callback);
|
||||||
|
|
||||||
void onBinary(ByteBuffer payload, boolean fin);
|
void onBinary(Frame frame, FrameCallback callback);
|
||||||
|
|
||||||
void onContinuation(ByteBuffer payload, boolean fin);
|
void onContinuation(Frame frame, FrameCallback callback);
|
||||||
|
|
||||||
void onPing(ByteBuffer payload);
|
void onPing(ByteBuffer payload);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.CloseException;
|
import org.eclipse.jetty.websocket.api.CloseException;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.SuspendToken;
|
import org.eclipse.jetty.websocket.api.SuspendToken;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
||||||
|
@ -54,15 +55,16 @@ import org.eclipse.jetty.websocket.common.ConnectionState;
|
||||||
import org.eclipse.jetty.websocket.common.Generator;
|
import org.eclipse.jetty.websocket.common.Generator;
|
||||||
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
||||||
import org.eclipse.jetty.websocket.common.Parser;
|
import org.eclipse.jetty.websocket.common.Parser;
|
||||||
|
import org.eclipse.jetty.websocket.common.extensions.ExtensionStack;
|
||||||
import org.eclipse.jetty.websocket.common.io.IOState.ConnectionStateListener;
|
import org.eclipse.jetty.websocket.common.io.IOState.ConnectionStateListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the implementation of {@link LogicalConnection} within the framework of the new {@link org.eclipse.jetty.io.Connection} framework of {@code jetty-io}.
|
* Provides the implementation of {@link LogicalConnection} within the framework of the new {@link org.eclipse.jetty.io.Connection} framework of {@code jetty-io}.
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractWebSocketConnection extends AbstractConnection implements LogicalConnection, Connection.UpgradeTo, ConnectionStateListener, Dumpable
|
public abstract class AbstractWebSocketConnection extends AbstractConnection implements LogicalConnection, Connection.UpgradeTo, ConnectionStateListener, Dumpable, Parser.Handler
|
||||||
{
|
{
|
||||||
private final AtomicBoolean closed = new AtomicBoolean();
|
private final AtomicBoolean closed = new AtomicBoolean();
|
||||||
|
|
||||||
private class Flusher extends FrameFlusher
|
private class Flusher extends FrameFlusher
|
||||||
{
|
{
|
||||||
private Flusher(ByteBufferPool bufferPool, int bufferSize, Generator generator, EndPoint endpoint)
|
private Flusher(ByteBufferPool bufferPool, int bufferSize, Generator generator, EndPoint endpoint)
|
||||||
|
@ -219,14 +221,15 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
private final AtomicBoolean suspendToken;
|
private final AtomicBoolean suspendToken;
|
||||||
private final FrameFlusher flusher;
|
private final FrameFlusher flusher;
|
||||||
private final String id;
|
private final String id;
|
||||||
|
private final ExtensionStack extensionStack;
|
||||||
private List<ExtensionConfig> extensions;
|
private List<ExtensionConfig> extensions;
|
||||||
private boolean isFilling;
|
private boolean isFilling;
|
||||||
private ByteBuffer prefillBuffer;
|
private ByteBuffer prefillBuffer;
|
||||||
private ReadMode readMode = ReadMode.PARSE;
|
private ReadMode readMode = ReadMode.PARSE;
|
||||||
private IOState ioState;
|
private IOState ioState;
|
||||||
private Stats stats = new Stats();
|
private Stats stats = new Stats();
|
||||||
|
|
||||||
public AbstractWebSocketConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool)
|
public AbstractWebSocketConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack)
|
||||||
{
|
{
|
||||||
super(endp,executor);
|
super(endp,executor);
|
||||||
this.id = String.format("%s:%d->%s:%d",
|
this.id = String.format("%s:%d->%s:%d",
|
||||||
|
@ -237,8 +240,10 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
this.policy = policy;
|
this.policy = policy;
|
||||||
this.behavior = policy.getBehavior();
|
this.behavior = policy.getBehavior();
|
||||||
this.bufferPool = bufferPool;
|
this.bufferPool = bufferPool;
|
||||||
|
this.extensionStack = extensionStack;
|
||||||
|
|
||||||
this.generator = new Generator(policy,bufferPool);
|
this.generator = new Generator(policy,bufferPool);
|
||||||
this.parser = new Parser(policy,bufferPool);
|
this.parser = new Parser(policy,bufferPool,this);
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.extensions = new ArrayList<>();
|
this.extensions = new ArrayList<>();
|
||||||
this.suspendToken = new AtomicBoolean(false);
|
this.suspendToken = new AtomicBoolean(false);
|
||||||
|
@ -247,6 +252,10 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
this.flusher = new Flusher(bufferPool,policy.getMaxBinaryMessageBufferSize(),generator,endp);
|
this.flusher = new Flusher(bufferPool,policy.getMaxBinaryMessageBufferSize(),generator,endp);
|
||||||
this.setInputBufferSize(policy.getInputBufferSize());
|
this.setInputBufferSize(policy.getInputBufferSize());
|
||||||
this.setMaxIdleTimeout(policy.getIdleTimeout());
|
this.setMaxIdleTimeout(policy.getIdleTimeout());
|
||||||
|
|
||||||
|
this.extensionStack.setPolicy(this.policy);
|
||||||
|
this.extensionStack.configure(this.parser);
|
||||||
|
this.extensionStack.configure(this.generator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -494,7 +503,26 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFrame(Frame frame)
|
||||||
|
{
|
||||||
|
extensionStack.incomingFrame(frame, new FrameCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void fail(Throwable cause)
|
||||||
|
{
|
||||||
|
// TODO: suspend
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void succeed()
|
||||||
|
{
|
||||||
|
// TODO: resume
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFillable()
|
public void onFillable()
|
||||||
{
|
{
|
||||||
|
@ -557,7 +585,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
|
|
||||||
private void notifyError(Throwable t)
|
private void notifyError(Throwable t)
|
||||||
{
|
{
|
||||||
getParser().getIncomingFramesHandler().incomingError(t);
|
extensionStack.incomingError(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -606,7 +634,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
* Frame from API, User, or Internal implementation destined for network.
|
* Frame from API, User, or Internal implementation destined for network.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
{
|
{
|
||||||
|
@ -678,6 +706,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
{
|
{
|
||||||
LOG.debug("Filled {} bytes - {}",filled,BufferUtil.toDetailString(buffer));
|
LOG.debug("Filled {} bytes - {}",filled,BufferUtil.toDetailString(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.parse(buffer);
|
parser.parse(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -697,7 +726,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
{
|
{
|
||||||
LOG.warn(t);
|
LOG.warn(t);
|
||||||
close(StatusCode.ABNORMAL,t.getMessage());
|
close(StatusCode.ABNORMAL,t.getMessage());
|
||||||
// TODO: should probably only switch to discard if a non-ws-endpoint error
|
// TODO: should ws only switch to discard if a non-ws-endpoint error?
|
||||||
return ReadMode.DISCARD;
|
return ReadMode.DISCARD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -745,7 +774,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
getEndPoint().setIdleTimeout(ms);
|
getEndPoint().setIdleTimeout(ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SuspendToken suspend()
|
public SuspendToken suspend()
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,7 @@ import org.eclipse.jetty.util.IteratingCallback;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.common.Generator;
|
import org.eclipse.jetty.websocket.common.Generator;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
|
@ -249,11 +249,11 @@ public class FrameFlusher
|
||||||
private class FrameEntry
|
private class FrameEntry
|
||||||
{
|
{
|
||||||
private final Frame frame;
|
private final Frame frame;
|
||||||
private final WriteCallback callback;
|
private final FrameCallback callback;
|
||||||
private final BatchMode batchMode;
|
private final BatchMode batchMode;
|
||||||
private ByteBuffer headerBuffer;
|
private ByteBuffer headerBuffer;
|
||||||
|
|
||||||
private FrameEntry(Frame frame, WriteCallback callback, BatchMode batchMode)
|
private FrameEntry(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
this.frame = Objects.requireNonNull(frame);
|
this.frame = Objects.requireNonNull(frame);
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
@ -332,7 +332,7 @@ public class FrameFlusher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enqueue(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void enqueue(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
if (closed.get())
|
if (closed.get())
|
||||||
{
|
{
|
||||||
|
@ -382,13 +382,13 @@ public class FrameFlusher
|
||||||
flusher.iterate();
|
flusher.iterate();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void notifyCallbackFailure(WriteCallback callback, Throwable failure)
|
protected void notifyCallbackFailure(FrameCallback callback, Throwable failure)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeFailed(failure);
|
callback.fail(failure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
|
@ -398,13 +398,13 @@ public class FrameFlusher
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void notifyCallbackSuccess(WriteCallback callback)
|
protected void notifyCallbackSuccess(FrameCallback callback)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
package org.eclipse.jetty.websocket.common.io;
|
package org.eclipse.jetty.websocket.common.io;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
|
@ -42,9 +42,9 @@ public class FramePipes
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
this.outgoing.outgoingFrame(frame,null, BatchMode.OFF);
|
this.outgoing.outgoingFrame(frame, callback, BatchMode.OFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,17 +58,9 @@ public class FramePipes
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
try
|
this.incoming.incomingFrame(frame, callback);
|
||||||
{
|
|
||||||
this.incoming.incomingFrame(frame);
|
|
||||||
callback.writeSuccess();
|
|
||||||
}
|
|
||||||
catch (Throwable t)
|
|
||||||
{
|
|
||||||
callback.writeFailed(t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,13 @@
|
||||||
package org.eclipse.jetty.websocket.common.message;
|
package org.eclipse.jetty.websocket.common.message;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
|
||||||
public class ByteArrayMessageSink implements MessageSink
|
public class ByteArrayMessageSink implements MessageSink
|
||||||
{
|
{
|
||||||
|
@ -42,12 +43,13 @@ public class ByteArrayMessageSink implements MessageSink
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ByteBuffer payload, Boolean fin)
|
public void accept(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (payload != null)
|
if (frame.hasPayload())
|
||||||
{
|
{
|
||||||
|
ByteBuffer payload = frame.getPayload();
|
||||||
policy.assertValidBinaryMessageSize(size + payload.remaining());
|
policy.assertValidBinaryMessageSize(size + payload.remaining());
|
||||||
size += payload.remaining();
|
size += payload.remaining();
|
||||||
|
|
||||||
|
@ -56,19 +58,25 @@ public class ByteArrayMessageSink implements MessageSink
|
||||||
|
|
||||||
BufferUtil.writeTo(payload, out);
|
BufferUtil.writeTo(payload, out);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (IOException e)
|
if (frame.isFin())
|
||||||
{
|
|
||||||
throw new RuntimeException("Unable to append Binary Message", e);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (fin)
|
|
||||||
{
|
{
|
||||||
if (out != null)
|
if (out != null)
|
||||||
notifyOnMessage(out.toByteArray());
|
notifyOnMessage(out.toByteArray());
|
||||||
else
|
else
|
||||||
notifyOnMessage(EMPTY_BUFFER);
|
notifyOnMessage(EMPTY_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback.succeed();
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
callback.fail(t);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (frame.isFin())
|
||||||
|
{
|
||||||
// reset
|
// reset
|
||||||
out = null;
|
out = null;
|
||||||
size = 0;
|
size = 0;
|
||||||
|
@ -76,7 +84,7 @@ public class ByteArrayMessageSink implements MessageSink
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object notifyOnMessage(byte buf[])
|
private Object notifyOnMessage(byte buf[])
|
||||||
{
|
{
|
||||||
return onMessageFunction.apply(buf);
|
return onMessageFunction.apply(buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2017 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.message;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
|
||||||
|
public class FrameCallbackBuffer
|
||||||
|
{
|
||||||
|
public ByteBuffer buffer;
|
||||||
|
public FrameCallback callback;
|
||||||
|
|
||||||
|
public FrameCallbackBuffer(FrameCallback callback, ByteBuffer buffer)
|
||||||
|
{
|
||||||
|
this.callback = callback;
|
||||||
|
this.buffer = buffer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,6 @@
|
||||||
package org.eclipse.jetty.websocket.common.message;
|
package org.eclipse.jetty.websocket.common.message;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -27,6 +26,8 @@ import java.util.function.Function;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
|
||||||
public class InputStreamMessageSink implements MessageSink
|
public class InputStreamMessageSink implements MessageSink
|
||||||
{
|
{
|
||||||
|
@ -43,7 +44,7 @@ public class InputStreamMessageSink implements MessageSink
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ByteBuffer payload, Boolean fin)
|
public void accept(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -55,7 +56,7 @@ public class InputStreamMessageSink implements MessageSink
|
||||||
first = true;
|
first = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.accept(payload,fin);
|
stream.accept(frame, callback);
|
||||||
if (first)
|
if (first)
|
||||||
{
|
{
|
||||||
dispatchCompleted = new CountDownLatch(1);
|
dispatchCompleted = new CountDownLatch(1);
|
||||||
|
@ -83,7 +84,7 @@ public class InputStreamMessageSink implements MessageSink
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
//noinspection Duplicates
|
//noinspection Duplicates
|
||||||
if (fin)
|
if (frame.isFin())
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("dispatch complete await() - {}", stream);
|
LOG.debug("dispatch complete await() - {}", stream);
|
||||||
|
|
|
@ -27,12 +27,13 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support class for reading a (single) WebSocket BINARY message via a InputStream.
|
* Support class for reading a WebSocket BINARY message via a InputStream.
|
||||||
* <p>
|
* <p>
|
||||||
* An InputStream that can access a queue of ByteBuffer payloads, along with expected InputStream blocking behavior.
|
* An InputStream that can access a queue of ByteBuffer payloads, along with expected InputStream blocking behavior.
|
||||||
* </p>
|
* </p>
|
||||||
|
@ -40,15 +41,15 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
public class MessageInputStream extends InputStream implements MessageSink
|
public class MessageInputStream extends InputStream implements MessageSink
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(MessageInputStream.class);
|
private static final Logger LOG = Log.getLogger(MessageInputStream.class);
|
||||||
private static final ByteBuffer EOF = ByteBuffer.allocate(0).asReadOnlyBuffer();
|
private static final FrameCallbackBuffer EOF = new FrameCallbackBuffer(new FrameCallback.Adapter(), ByteBuffer.allocate(0).asReadOnlyBuffer());
|
||||||
|
|
||||||
private final BlockingDeque<ByteBuffer> buffers = new LinkedBlockingDeque<>();
|
private final BlockingDeque<FrameCallbackBuffer> buffers = new LinkedBlockingDeque<>();
|
||||||
|
|
||||||
private final AtomicBoolean closed = new AtomicBoolean(false);
|
private final AtomicBoolean closed = new AtomicBoolean(false);
|
||||||
private final long timeoutMs;
|
private final long timeoutMs;
|
||||||
private final CountDownLatch closedLatch = new CountDownLatch(1);
|
private final CountDownLatch closedLatch = new CountDownLatch(1);
|
||||||
|
|
||||||
private ByteBuffer activeBuffer = null;
|
private FrameCallbackBuffer activeBuffer = null;
|
||||||
|
|
||||||
public MessageInputStream()
|
public MessageInputStream()
|
||||||
{
|
{
|
||||||
|
@ -61,16 +62,17 @@ public class MessageInputStream extends InputStream implements MessageSink
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ByteBuffer payload, Boolean fin)
|
public void accept(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
{
|
{
|
||||||
LOG.debug("Appending {} chunk: {}", fin ? "final" : "non-final", BufferUtil.toDetailString(payload));
|
LOG.debug("Appending {}", frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If closed, we should just toss incoming payloads into the bit bucket.
|
// If closed, we should just toss incoming payloads into the bit bucket.
|
||||||
if (closed.get())
|
if (closed.get())
|
||||||
{
|
{
|
||||||
|
callback.fail(new IOException("Already Closed"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,22 +81,29 @@ public class MessageInputStream extends InputStream implements MessageSink
|
||||||
// be processed after this method returns.
|
// be processed after this method returns.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (payload == null)
|
if (!frame.hasPayload())
|
||||||
{
|
{
|
||||||
// skip if no payload
|
// skip if no payload
|
||||||
|
callback.succeed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ByteBuffer payload = frame.getPayload();
|
||||||
|
|
||||||
int capacity = payload.remaining();
|
int capacity = payload.remaining();
|
||||||
if (capacity <= 0)
|
if (capacity <= 0)
|
||||||
{
|
{
|
||||||
// skip if no payload data to copy
|
// skip if no payload data to copy
|
||||||
|
callback.succeed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: the copy buffer should be pooled too, but no buffer pool available from here.
|
// TODO: the copy buffer should be pooled too, but no buffer pool available from here.
|
||||||
ByteBuffer copy = payload.isDirect() ? ByteBuffer.allocateDirect(capacity) : ByteBuffer.allocate(capacity);
|
ByteBuffer copy = payload.isDirect() ? ByteBuffer.allocateDirect(capacity) : ByteBuffer.allocate(capacity);
|
||||||
copy.put(payload).flip();
|
copy.put(payload).flip();
|
||||||
buffers.put(copy);
|
buffers.put(new FrameCallbackBuffer(callback,copy));
|
||||||
|
|
||||||
|
// TODO: backpressure
|
||||||
}
|
}
|
||||||
catch (InterruptedException e)
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +111,7 @@ public class MessageInputStream extends InputStream implements MessageSink
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (fin)
|
if (frame.isFin())
|
||||||
{
|
{
|
||||||
buffers.offer(EOF);
|
buffers.offer(EOF);
|
||||||
}
|
}
|
||||||
|
@ -145,13 +154,14 @@ public class MessageInputStream extends InputStream implements MessageSink
|
||||||
}
|
}
|
||||||
|
|
||||||
// grab a fresh buffer
|
// grab a fresh buffer
|
||||||
while (activeBuffer == null || !activeBuffer.hasRemaining())
|
while (activeBuffer == null || !activeBuffer.buffer.hasRemaining())
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Waiting {} ms to read", timeoutMs);
|
LOG.debug("Waiting {} ms to read", timeoutMs);
|
||||||
if (timeoutMs < 0)
|
if (timeoutMs < 0)
|
||||||
{
|
{
|
||||||
// Wait forever until a buffer is available.
|
// Wait forever until a buffer is available.
|
||||||
|
// TODO: notify connection to resume (if paused)
|
||||||
activeBuffer = buffers.take();
|
activeBuffer = buffers.take();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -177,7 +187,7 @@ public class MessageInputStream extends InputStream implements MessageSink
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return activeBuffer.get() & 0xFF;
|
return activeBuffer.buffer.get() & 0xFF;
|
||||||
}
|
}
|
||||||
catch (InterruptedException x)
|
catch (InterruptedException x)
|
||||||
{
|
{
|
||||||
|
@ -195,6 +205,8 @@ public class MessageInputStream extends InputStream implements MessageSink
|
||||||
throw new IOException("reset() not supported");
|
throw new IOException("reset() not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove await!
|
||||||
|
@Deprecated
|
||||||
public void awaitClose()
|
public void awaitClose()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -19,9 +19,11 @@
|
||||||
package org.eclipse.jetty.websocket.common.message;
|
package org.eclipse.jetty.websocket.common.message;
|
||||||
|
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support class for reading a (single) WebSocket TEXT message via a Reader.
|
* Support class for reading a (single) WebSocket TEXT message via a Reader.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -38,11 +40,13 @@ public class MessageReader extends InputStreamReader implements MessageSink
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ByteBuffer payload, Boolean fin)
|
public void accept(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
this.stream.accept(payload, fin);
|
this.stream.accept(frame, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove await!
|
||||||
|
@Deprecated
|
||||||
public void awaitClose()
|
public void awaitClose()
|
||||||
{
|
{
|
||||||
stream.awaitClose();
|
stream.awaitClose();
|
||||||
|
|
|
@ -18,23 +18,22 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.common.message;
|
package org.eclipse.jetty.websocket.common.message;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import java.util.function.BiConsumer;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink consumer for messages (used for multiple frames with continuations,
|
* Sink consumer for messages (used for multiple frames with continuations,
|
||||||
* and also to allow for streaming APIs)
|
* and also to allow for streaming APIs)
|
||||||
*/
|
*/
|
||||||
public interface MessageSink extends BiConsumer<ByteBuffer, Boolean>
|
public interface MessageSink
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Consume the frame payload to the message.
|
* Consume the frame payload to the message.
|
||||||
*
|
*
|
||||||
* @param payload
|
* @param frame
|
||||||
* the frame payload to append.
|
* the frame, its payload (and fin state) to append
|
||||||
* @param fin
|
* @param callback
|
||||||
* flag indicating if this is the final part of the message or not.
|
* the callback for how the frame was consumed
|
||||||
*/
|
*/
|
||||||
@Override
|
void accept(Frame frame, FrameCallback callback);
|
||||||
void accept(ByteBuffer payload, Boolean fin);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.WriteCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
import org.eclipse.jetty.websocket.common.BlockingWriteCallback;
|
import org.eclipse.jetty.websocket.common.BlockingWriteCallback;
|
||||||
|
@ -50,7 +51,7 @@ public class MessageWriter extends Writer
|
||||||
private TextFrame frame;
|
private TextFrame frame;
|
||||||
private ByteBuffer buffer;
|
private ByteBuffer buffer;
|
||||||
private Utf8CharBuffer utf;
|
private Utf8CharBuffer utf;
|
||||||
private WriteCallback callback;
|
private FrameCallback callback;
|
||||||
private boolean closed;
|
private boolean closed;
|
||||||
|
|
||||||
public MessageWriter(WebSocketSession session)
|
public MessageWriter(WebSocketSession session)
|
||||||
|
@ -199,27 +200,27 @@ public class MessageWriter extends Writer
|
||||||
|
|
||||||
private void notifySuccess()
|
private void notifySuccess()
|
||||||
{
|
{
|
||||||
WriteCallback callback;
|
FrameCallback callback;
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
callback = this.callback;
|
callback = this.callback;
|
||||||
}
|
}
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyFailure(Throwable failure)
|
private void notifyFailure(Throwable failure)
|
||||||
{
|
{
|
||||||
WriteCallback callback;
|
FrameCallback callback;
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
callback = this.callback;
|
callback = this.callback;
|
||||||
}
|
}
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeFailed(failure);
|
callback.fail(failure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,11 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.common.message;
|
package org.eclipse.jetty.websocket.common.message;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
|
||||||
public class PartialBinaryMessageSink implements MessageSink
|
public class PartialBinaryMessageSink implements MessageSink
|
||||||
{
|
{
|
||||||
private final Function<PartialBinaryMessage, Void> onBinaryFunction;
|
private final Function<PartialBinaryMessage, Void> onBinaryFunction;
|
||||||
|
@ -31,8 +33,16 @@ public class PartialBinaryMessageSink implements MessageSink
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ByteBuffer payload, Boolean fin)
|
public void accept(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
onBinaryFunction.apply(new PartialBinaryMessage(payload,fin));
|
try
|
||||||
|
{
|
||||||
|
onBinaryFunction.apply(new PartialBinaryMessage(frame.getPayload(), frame.isFin()));
|
||||||
|
callback.succeed();
|
||||||
|
}
|
||||||
|
catch(Throwable t)
|
||||||
|
{
|
||||||
|
callback.fail(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,10 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.common.message;
|
package org.eclipse.jetty.websocket.common.message;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.common.util.Utf8PartialBuilder;
|
import org.eclipse.jetty.websocket.common.util.Utf8PartialBuilder;
|
||||||
|
|
||||||
public class PartialTextMessageSink implements MessageSink
|
public class PartialTextMessageSink implements MessageSink
|
||||||
|
@ -35,16 +36,21 @@ public class PartialTextMessageSink implements MessageSink
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ByteBuffer payload, Boolean fin)
|
public void accept(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
String partialText = utf8Partial.toPartialString(payload);
|
String partialText = utf8Partial.toPartialString(frame.getPayload());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
onTextFunction.apply(new PartialTextMessage(partialText,fin));
|
onTextFunction.apply(new PartialTextMessage(partialText,frame.isFin()));
|
||||||
|
callback.succeed();
|
||||||
|
}
|
||||||
|
catch(Throwable t)
|
||||||
|
{
|
||||||
|
callback.fail(t);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (fin)
|
if (frame.isFin())
|
||||||
utf8Partial.reset();
|
utf8Partial.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
package org.eclipse.jetty.websocket.common.message;
|
package org.eclipse.jetty.websocket.common.message;
|
||||||
|
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -27,6 +26,8 @@ import java.util.function.Function;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
|
||||||
public class ReaderMessageSink implements MessageSink
|
public class ReaderMessageSink implements MessageSink
|
||||||
{
|
{
|
||||||
|
@ -43,7 +44,7 @@ public class ReaderMessageSink implements MessageSink
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ByteBuffer payload, Boolean fin)
|
public void accept(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -55,7 +56,7 @@ public class ReaderMessageSink implements MessageSink
|
||||||
first = true;
|
first = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.accept(payload, fin);
|
stream.accept(frame, callback);
|
||||||
if (first)
|
if (first)
|
||||||
{
|
{
|
||||||
dispatchCompleted = new CountDownLatch(1);
|
dispatchCompleted = new CountDownLatch(1);
|
||||||
|
@ -84,7 +85,7 @@ public class ReaderMessageSink implements MessageSink
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
//noinspection Duplicates
|
//noinspection Duplicates
|
||||||
if (fin)
|
if (frame.isFin())
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("dispatch complete await() - {}", stream);
|
LOG.debug("dispatch complete await() - {}", stream);
|
||||||
|
|
|
@ -25,7 +25,9 @@ import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
|
||||||
public class StringMessageSink implements MessageSink
|
public class StringMessageSink implements MessageSink
|
||||||
{
|
{
|
||||||
|
@ -42,13 +44,14 @@ public class StringMessageSink implements MessageSink
|
||||||
this.onMessageFunction = onMessageFunction;
|
this.onMessageFunction = onMessageFunction;
|
||||||
this.size = 0;
|
this.size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
@Override
|
@Override
|
||||||
public void accept(ByteBuffer payload, Boolean fin)
|
public void accept(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
if (payload != null)
|
if (frame.hasPayload())
|
||||||
{
|
{
|
||||||
|
ByteBuffer payload = frame.getPayload();
|
||||||
policy.assertValidTextMessageSize(size + payload.remaining());
|
policy.assertValidTextMessageSize(size + payload.remaining());
|
||||||
size += payload.remaining();
|
size += payload.remaining();
|
||||||
|
|
||||||
|
@ -62,13 +65,15 @@ public class StringMessageSink implements MessageSink
|
||||||
utf.append(payload);
|
utf.append(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fin)
|
if (frame.isFin())
|
||||||
{
|
{
|
||||||
// notify event
|
// notify event
|
||||||
if (utf != null)
|
if (utf != null)
|
||||||
onMessageFunction.apply(utf.toString());
|
onMessageFunction.apply(utf.toString());
|
||||||
else
|
else
|
||||||
onMessageFunction.apply("");
|
onMessageFunction.apply("");
|
||||||
|
|
||||||
|
callback.succeed();
|
||||||
// reset
|
// reset
|
||||||
size = 0;
|
size = 0;
|
||||||
utf = null;
|
utf = null;
|
||||||
|
|
|
@ -53,9 +53,8 @@ public class ClosePayloadParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2017 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 org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
|
||||||
|
public class FrameCallbackAdapter extends FrameCallback.Adapter
|
||||||
|
{
|
||||||
|
}
|
|
@ -42,9 +42,8 @@ public class GeneratorParserRoundtripTest
|
||||||
{
|
{
|
||||||
WebSocketPolicy policy = WebSocketPolicy.newClientPolicy();
|
WebSocketPolicy policy = WebSocketPolicy.newClientPolicy();
|
||||||
Generator gen = new Generator(policy,bufferPool);
|
Generator gen = new Generator(policy,bufferPool);
|
||||||
Parser parser = new Parser(policy,bufferPool);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new Parser(policy,bufferPool,capture);
|
||||||
|
|
||||||
String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
|
String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
|
||||||
|
|
||||||
|
@ -80,9 +79,8 @@ public class GeneratorParserRoundtripTest
|
||||||
public void testParserAndGeneratorMasked() throws Exception
|
public void testParserAndGeneratorMasked() throws Exception
|
||||||
{
|
{
|
||||||
Generator gen = new Generator(WebSocketPolicy.newClientPolicy(),bufferPool);
|
Generator gen = new Generator(WebSocketPolicy.newClientPolicy(),bufferPool);
|
||||||
Parser parser = new Parser(WebSocketPolicy.newServerPolicy(),bufferPool);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new Parser(WebSocketPolicy.newServerPolicy(),bufferPool,capture);
|
||||||
|
|
||||||
String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
|
String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
|
||||||
|
|
||||||
|
|
|
@ -297,9 +297,8 @@ public class GeneratorTest
|
||||||
|
|
||||||
// Parse complete buffer.
|
// Parse complete buffer.
|
||||||
WebSocketPolicy policy = WebSocketPolicy.newServerPolicy();
|
WebSocketPolicy policy = WebSocketPolicy.newServerPolicy();
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
|
|
||||||
parser.parse(completeBuffer);
|
parser.parse(completeBuffer);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
|
import org.eclipse.jetty.websocket.api.ProtocolException;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
|
@ -39,10 +40,15 @@ import org.eclipse.jetty.websocket.common.test.UnitGenerator;
|
||||||
import org.eclipse.jetty.websocket.common.test.UnitParser;
|
import org.eclipse.jetty.websocket.common.test.UnitParser;
|
||||||
import org.eclipse.jetty.websocket.common.util.Hex;
|
import org.eclipse.jetty.websocket.common.util.Hex;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
public class ParserTest
|
public class ParserTest
|
||||||
{
|
{
|
||||||
|
@Rule
|
||||||
|
public ExpectedException expectedException = ExpectedException.none();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to the server side 5.15 testcase. A normal 2 fragment text text message, followed by another continuation.
|
* Similar to the server side 5.15 testcase. A normal 2 fragment text text message, followed by another continuation.
|
||||||
*/
|
*/
|
||||||
|
@ -57,13 +63,12 @@ public class ParserTest
|
||||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||||
|
|
||||||
ByteBuffer completeBuf = UnitGenerator.generate(send);
|
ByteBuffer completeBuf = UnitGenerator.generate(send);
|
||||||
UnitParser parser = new UnitParser();
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(WebSocketPolicy.newServerPolicy(),capture);
|
||||||
|
|
||||||
parser.parseQuietly(completeBuf);
|
expectedException.expect(ProtocolException.class);
|
||||||
|
parser.parse(completeBuf);
|
||||||
|
|
||||||
capture.assertErrorCount(1);
|
|
||||||
capture.assertHasFrame(OpCode.TEXT,1);
|
capture.assertHasFrame(OpCode.TEXT,1);
|
||||||
capture.assertHasFrame(OpCode.CONTINUATION,1);
|
capture.assertHasFrame(OpCode.CONTINUATION,1);
|
||||||
}
|
}
|
||||||
|
@ -80,12 +85,12 @@ public class ParserTest
|
||||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||||
|
|
||||||
ByteBuffer completeBuf = UnitGenerator.generate(send);
|
ByteBuffer completeBuf = UnitGenerator.generate(send);
|
||||||
UnitParser parser = new UnitParser();
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(WebSocketPolicy.newServerPolicy(),capture);
|
||||||
parser.parseQuietly(completeBuf);
|
|
||||||
|
expectedException.expect(ProtocolException.class);
|
||||||
|
parser.parse(completeBuf);
|
||||||
|
|
||||||
capture.assertErrorCount(1);
|
|
||||||
capture.assertHasFrame(OpCode.TEXT,1); // fragment 1
|
capture.assertHasFrame(OpCode.TEXT,1); // fragment 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,12 +111,10 @@ public class ParserTest
|
||||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||||
|
|
||||||
ByteBuffer completeBuf = UnitGenerator.generate(send);
|
ByteBuffer completeBuf = UnitGenerator.generate(send);
|
||||||
UnitParser parser = new UnitParser();
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(WebSocketPolicy.newServerPolicy(),capture);
|
||||||
parser.parseQuietly(completeBuf);
|
parser.parse(completeBuf);
|
||||||
|
|
||||||
capture.assertErrorCount(0);
|
|
||||||
capture.assertHasFrame(OpCode.TEXT,1);
|
capture.assertHasFrame(OpCode.TEXT,1);
|
||||||
capture.assertHasFrame(OpCode.CONTINUATION,4);
|
capture.assertHasFrame(OpCode.CONTINUATION,4);
|
||||||
capture.assertHasFrame(OpCode.CLOSE,1);
|
capture.assertHasFrame(OpCode.CLOSE,1);
|
||||||
|
@ -130,12 +133,10 @@ public class ParserTest
|
||||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||||
|
|
||||||
ByteBuffer completeBuf = UnitGenerator.generate(send);
|
ByteBuffer completeBuf = UnitGenerator.generate(send);
|
||||||
UnitParser parser = new UnitParser();
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(WebSocketPolicy.newServerPolicy(),capture);
|
||||||
parser.parse(completeBuf);
|
parser.parse(completeBuf);
|
||||||
|
|
||||||
capture.assertErrorCount(0);
|
|
||||||
capture.assertHasFrame(OpCode.TEXT,1);
|
capture.assertHasFrame(OpCode.TEXT,1);
|
||||||
capture.assertHasFrame(OpCode.CLOSE,1);
|
capture.assertHasFrame(OpCode.CLOSE,1);
|
||||||
capture.assertHasFrame(OpCode.PONG,1);
|
capture.assertHasFrame(OpCode.PONG,1);
|
||||||
|
@ -158,7 +159,7 @@ public class ParserTest
|
||||||
byte mini[];
|
byte mini[];
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
DataFrame frame = null;
|
DataFrame frame;
|
||||||
if (continuation)
|
if (continuation)
|
||||||
{
|
{
|
||||||
frame = new ContinuationFrame();
|
frame = new ContinuationFrame();
|
||||||
|
@ -180,12 +181,10 @@ public class ParserTest
|
||||||
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||||
|
|
||||||
ByteBuffer completeBuf = UnitGenerator.generate(send);
|
ByteBuffer completeBuf = UnitGenerator.generate(send);
|
||||||
UnitParser parser = new UnitParser();
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(WebSocketPolicy.newServerPolicy(),capture);
|
||||||
parser.parse(completeBuf);
|
parser.parse(completeBuf);
|
||||||
|
|
||||||
capture.assertErrorCount(0);
|
|
||||||
capture.assertHasFrame(OpCode.TEXT,textCount);
|
capture.assertHasFrame(OpCode.TEXT,textCount);
|
||||||
capture.assertHasFrame(OpCode.CONTINUATION,continuationCount);
|
capture.assertHasFrame(OpCode.CONTINUATION,continuationCount);
|
||||||
capture.assertHasFrame(OpCode.CLOSE,1);
|
capture.assertHasFrame(OpCode.CLOSE,1);
|
||||||
|
@ -199,9 +198,9 @@ public class ParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
|
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -227,9 +226,8 @@ public class ParserTest
|
||||||
|
|
||||||
// Parse, in 4096 sized windows
|
// Parse, in 4096 sized windows
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
|
|
||||||
while (networkBytes.remaining() > 0)
|
while (networkBytes.remaining() > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,9 +43,8 @@ public class PingPayloadParserTest
|
||||||
BufferUtil.flipToFlush(buf,0);
|
BufferUtil.flipToFlush(buf,0);
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
|
|
@ -40,9 +40,8 @@ public class RFC6455ExamplesParserTest
|
||||||
public void testFragmentedUnmaskedTextMessage()
|
public void testFragmentedUnmaskedTextMessage()
|
||||||
{
|
{
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
|
|
||||||
ByteBuffer buf = ByteBuffer.allocate(16);
|
ByteBuffer buf = ByteBuffer.allocate(16);
|
||||||
BufferUtil.clearToFill(buf);
|
BufferUtil.clearToFill(buf);
|
||||||
|
@ -88,9 +87,8 @@ public class RFC6455ExamplesParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -112,9 +110,8 @@ public class RFC6455ExamplesParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -143,9 +140,8 @@ public class RFC6455ExamplesParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -182,9 +178,8 @@ public class RFC6455ExamplesParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -213,9 +208,8 @@ public class RFC6455ExamplesParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -237,9 +231,8 @@ public class RFC6455ExamplesParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
|
|
@ -35,10 +35,15 @@ import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
|
||||||
import org.eclipse.jetty.websocket.common.test.UnitParser;
|
import org.eclipse.jetty.websocket.common.test.UnitParser;
|
||||||
import org.eclipse.jetty.websocket.common.util.MaskedByteBuffer;
|
import org.eclipse.jetty.websocket.common.util.MaskedByteBuffer;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
public class TextPayloadParserTest
|
public class TextPayloadParserTest
|
||||||
{
|
{
|
||||||
|
@Rule
|
||||||
|
public ExpectedException expectedException = ExpectedException.none();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFrameTooLargeDueToPolicy() throws Exception
|
public void testFrameTooLargeDueToPolicy() throws Exception
|
||||||
{
|
{
|
||||||
|
@ -59,13 +64,13 @@ public class TextPayloadParserTest
|
||||||
MaskedByteBuffer.putMask(buf);
|
MaskedByteBuffer.putMask(buf);
|
||||||
MaskedByteBuffer.putPayload(buf,utf);
|
MaskedByteBuffer.putPayload(buf,utf);
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
UnitParser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parseQuietly(buf);
|
|
||||||
|
expectedException.expect(MessageTooLargeException.class);
|
||||||
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertHasErrors(MessageTooLargeException.class,1);
|
|
||||||
capture.assertHasNoFrames();
|
capture.assertHasNoFrames();
|
||||||
|
|
||||||
MessageTooLargeException err = (MessageTooLargeException)capture.getErrors().poll();
|
MessageTooLargeException err = (MessageTooLargeException)capture.getErrors().poll();
|
||||||
|
@ -75,7 +80,7 @@ public class TextPayloadParserTest
|
||||||
@Test
|
@Test
|
||||||
public void testLongMaskedText() throws Exception
|
public void testLongMaskedText() throws Exception
|
||||||
{
|
{
|
||||||
StringBuffer sb = new StringBuffer(); ;
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < 3500; i++)
|
for (int i = 0; i < 3500; i++)
|
||||||
{
|
{
|
||||||
sb.append("Hell\uFF4f Big W\uFF4Frld ");
|
sb.append("Hell\uFF4f Big W\uFF4Frld ");
|
||||||
|
@ -97,12 +102,10 @@ public class TextPayloadParserTest
|
||||||
|
|
||||||
WebSocketPolicy policy = WebSocketPolicy.newServerPolicy();
|
WebSocketPolicy policy = WebSocketPolicy.newServerPolicy();
|
||||||
policy.setMaxTextMessageSize(100000);
|
policy.setMaxTextMessageSize(100000);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.TEXT,1);
|
capture.assertHasFrame(OpCode.TEXT,1);
|
||||||
WebSocketFrame txt = capture.getFrames().poll();
|
WebSocketFrame txt = capture.getFrames().poll();
|
||||||
Assert.assertThat("TextFrame.data",txt.getPayloadAsUTF8(),is(expectedText));
|
Assert.assertThat("TextFrame.data",txt.getPayloadAsUTF8(),is(expectedText));
|
||||||
|
@ -111,7 +114,7 @@ public class TextPayloadParserTest
|
||||||
@Test
|
@Test
|
||||||
public void testMediumMaskedText() throws Exception
|
public void testMediumMaskedText() throws Exception
|
||||||
{
|
{
|
||||||
StringBuffer sb = new StringBuffer(); ;
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < 14; i++)
|
for (int i = 0; i < 14; i++)
|
||||||
{
|
{
|
||||||
sb.append("Hell\uFF4f Medium W\uFF4Frld ");
|
sb.append("Hell\uFF4f Medium W\uFF4Frld ");
|
||||||
|
@ -132,12 +135,10 @@ public class TextPayloadParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.TEXT,1);
|
capture.assertHasFrame(OpCode.TEXT,1);
|
||||||
WebSocketFrame txt = capture.getFrames().poll();
|
WebSocketFrame txt = capture.getFrames().poll();
|
||||||
Assert.assertThat("TextFrame.data",txt.getPayloadAsUTF8(),is(expectedText));
|
Assert.assertThat("TextFrame.data",txt.getPayloadAsUTF8(),is(expectedText));
|
||||||
|
@ -169,12 +170,10 @@ public class TextPayloadParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.TEXT,1);
|
capture.assertHasFrame(OpCode.TEXT,1);
|
||||||
capture.assertHasFrame(OpCode.CONTINUATION,1);
|
capture.assertHasFrame(OpCode.CONTINUATION,1);
|
||||||
WebSocketFrame txt = capture.getFrames().poll();
|
WebSocketFrame txt = capture.getFrames().poll();
|
||||||
|
@ -197,12 +196,10 @@ public class TextPayloadParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.TEXT,1);
|
capture.assertHasFrame(OpCode.TEXT,1);
|
||||||
WebSocketFrame txt = capture.getFrames().poll();
|
WebSocketFrame txt = capture.getFrames().poll();
|
||||||
Assert.assertThat("TextFrame.data",txt.getPayloadAsUTF8(),is(expectedText));
|
Assert.assertThat("TextFrame.data",txt.getPayloadAsUTF8(),is(expectedText));
|
||||||
|
@ -223,12 +220,10 @@ public class TextPayloadParserTest
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(buf);
|
parser.parse(buf);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.TEXT,1);
|
capture.assertHasFrame(OpCode.TEXT,1);
|
||||||
WebSocketFrame txt = capture.getFrames().poll();
|
WebSocketFrame txt = capture.getFrames().poll();
|
||||||
Assert.assertThat("TextFrame.data",txt.getPayloadAsUTF8(),is(expectedText));
|
Assert.assertThat("TextFrame.data",txt.getPayloadAsUTF8(),is(expectedText));
|
||||||
|
|
|
@ -304,10 +304,9 @@ public class TestABCase1_1
|
||||||
}
|
}
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -338,10 +337,9 @@ public class TestABCase1_1
|
||||||
}
|
}
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -372,10 +370,9 @@ public class TestABCase1_1
|
||||||
}
|
}
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -406,10 +403,9 @@ public class TestABCase1_1
|
||||||
}
|
}
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -443,9 +439,8 @@ public class TestABCase1_1
|
||||||
expected.flip();
|
expected.flip();
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
policy.setMaxTextMessageSize(length);
|
policy.setMaxTextMessageSize(length);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -480,9 +475,8 @@ public class TestABCase1_1
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
policy.setMaxTextMessageSize(length);
|
policy.setMaxTextMessageSize(length);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -503,10 +497,9 @@ public class TestABCase1_1
|
||||||
{ (byte)0x81, (byte)0x00 });
|
{ (byte)0x81, (byte)0x00 });
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
|
|
@ -323,10 +323,9 @@ public class TestABCase1_2
|
||||||
}
|
}
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -357,10 +356,9 @@ public class TestABCase1_2
|
||||||
}
|
}
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -391,10 +389,9 @@ public class TestABCase1_2
|
||||||
}
|
}
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -425,10 +422,9 @@ public class TestABCase1_2
|
||||||
}
|
}
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -461,9 +457,8 @@ public class TestABCase1_2
|
||||||
expected.flip();
|
expected.flip();
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
policy.setMaxBinaryMessageSize(length);
|
policy.setMaxBinaryMessageSize(length);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -498,9 +493,8 @@ public class TestABCase1_2
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
policy.setMaxBinaryMessageSize(length);
|
policy.setMaxBinaryMessageSize(length);
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
@ -521,10 +515,9 @@ public class TestABCase1_2
|
||||||
{ (byte)0x82, (byte)0x00 });
|
{ (byte)0x82, (byte)0x00 });
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
capture.assertNoErrors();
|
||||||
|
|
|
@ -39,11 +39,16 @@ import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
|
||||||
import org.eclipse.jetty.websocket.common.test.UnitGenerator;
|
import org.eclipse.jetty.websocket.common.test.UnitGenerator;
|
||||||
import org.eclipse.jetty.websocket.common.test.UnitParser;
|
import org.eclipse.jetty.websocket.common.test.UnitParser;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
public class TestABCase2
|
public class TestABCase2
|
||||||
{
|
{
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
@Rule
|
||||||
|
public ExpectedException expectedException = ExpectedException.none();
|
||||||
|
|
||||||
|
private WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGenerate125OctetPingCase2_4()
|
public void testGenerate125OctetPingCase2_4()
|
||||||
|
@ -184,13 +189,11 @@ public class TestABCase2
|
||||||
expected.put(bytes);
|
expected.put(bytes);
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.PING,1);
|
capture.assertHasFrame(OpCode.PING,1);
|
||||||
|
|
||||||
Frame pActual = capture.getFrames().poll();
|
Frame pActual = capture.getFrames().poll();
|
||||||
|
@ -214,13 +217,11 @@ public class TestABCase2
|
||||||
expected.put(bytes);
|
expected.put(bytes);
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.PING,1);
|
capture.assertHasFrame(OpCode.PING,1);
|
||||||
|
|
||||||
Frame pActual = capture.getFrames().poll();
|
Frame pActual = capture.getFrames().poll();
|
||||||
|
@ -237,13 +238,11 @@ public class TestABCase2
|
||||||
{ (byte)0x89, (byte)0x00 });
|
{ (byte)0x89, (byte)0x00 });
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.PING,1);
|
capture.assertHasFrame(OpCode.PING,1);
|
||||||
|
|
||||||
Frame pActual = capture.getFrames().poll();
|
Frame pActual = capture.getFrames().poll();
|
||||||
|
@ -268,13 +267,11 @@ public class TestABCase2
|
||||||
expected.put(messageBytes);
|
expected.put(messageBytes);
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.PING,1);
|
capture.assertHasFrame(OpCode.PING,1);
|
||||||
|
|
||||||
Frame pActual = capture.getFrames().poll();
|
Frame pActual = capture.getFrames().poll();
|
||||||
|
@ -311,13 +308,12 @@ public class TestABCase2
|
||||||
expected.put(bytes);
|
expected.put(bytes);
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
UnitParser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parseQuietly(expected);
|
|
||||||
|
|
||||||
Assert.assertEquals("error should be returned for too large of ping payload",1,capture.getErrorCount(ProtocolException.class));
|
expectedException.expect(ProtocolException.class);
|
||||||
|
parser.parse(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,21 +18,25 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.common.ab;
|
package org.eclipse.jetty.websocket.common.ab;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
|
||||||
import org.eclipse.jetty.websocket.api.ProtocolException;
|
import org.eclipse.jetty.websocket.api.ProtocolException;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.common.Parser;
|
import org.eclipse.jetty.websocket.common.Parser;
|
||||||
import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
|
import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
|
||||||
import org.eclipse.jetty.websocket.common.test.UnitParser;
|
import org.eclipse.jetty.websocket.common.test.UnitParser;
|
||||||
import org.junit.Assert;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
public class TestABCase4
|
public class TestABCase4
|
||||||
{
|
{
|
||||||
|
@Rule
|
||||||
|
public ExpectedException expectedException = ExpectedException.none();
|
||||||
|
|
||||||
private WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
private WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -43,28 +47,13 @@ public class TestABCase4
|
||||||
expected.put(new byte[] { (byte)0x8b, 0x00 });
|
expected.put(new byte[] { (byte)0x8b, 0x00 });
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
|
Parser parser = new UnitParser(policy,capture);
|
||||||
try (StacklessLogging logging = new StacklessLogging(Parser.class))
|
|
||||||
{
|
expectedException.expect(ProtocolException.class);
|
||||||
Parser parser = new UnitParser(policy);
|
expectedException.expectMessage(containsString("Unknown opcode: 11"));
|
||||||
parser.setIncomingFramesHandler(capture);
|
parser.parse(expected);
|
||||||
try
|
|
||||||
{
|
|
||||||
parser.parse(expected);
|
|
||||||
}
|
|
||||||
catch (ProtocolException ignore)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.assertEquals("error on undefined opcode",1,capture.getErrorCount(WebSocketException.class));
|
|
||||||
|
|
||||||
Throwable known = capture.getErrors().poll();
|
|
||||||
|
|
||||||
Assert.assertTrue("undefined option should be in message",known.getMessage().contains("Unknown opcode: 11"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -77,26 +66,11 @@ public class TestABCase4
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
|
Parser parser = new UnitParser(policy, capture);
|
||||||
try (StacklessLogging logging = new StacklessLogging(Parser.class))
|
|
||||||
{
|
expectedException.expect(ProtocolException.class);
|
||||||
Parser parser = new UnitParser(policy);
|
expectedException.expectMessage(containsString("Unknown opcode: 12"));
|
||||||
parser.setIncomingFramesHandler(capture);
|
parser.parse(expected);
|
||||||
try
|
|
||||||
{
|
|
||||||
parser.parse(expected);
|
|
||||||
}
|
|
||||||
catch (ProtocolException ignore)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.assertEquals("error on undefined opcode",1,capture.getErrorCount(WebSocketException.class));
|
|
||||||
|
|
||||||
Throwable known = capture.getErrors().poll();
|
|
||||||
|
|
||||||
Assert.assertTrue("undefined option should be in message",known.getMessage().contains("Unknown opcode: 12"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -107,28 +81,13 @@ public class TestABCase4
|
||||||
expected.put(new byte[] { (byte)0x83, 0x00 });
|
expected.put(new byte[] { (byte)0x83, 0x00 });
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
|
Parser parser = new UnitParser(policy, capture);
|
||||||
try (StacklessLogging logging = new StacklessLogging(Parser.class))
|
|
||||||
{
|
expectedException.expect(ProtocolException.class);
|
||||||
Parser parser = new UnitParser(policy);
|
expectedException.expectMessage(containsString("Unknown opcode: 3"));
|
||||||
parser.setIncomingFramesHandler(capture);
|
parser.parse(expected);
|
||||||
try
|
|
||||||
{
|
|
||||||
parser.parse(expected);
|
|
||||||
}
|
|
||||||
catch (ProtocolException ignore)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.assertEquals("error on undefined opcode",1,capture.getErrorCount(WebSocketException.class));
|
|
||||||
|
|
||||||
Throwable known = capture.getErrors().poll();
|
|
||||||
|
|
||||||
Assert.assertTrue("undefined option should be in message",known.getMessage().contains("Unknown opcode: 3"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -141,25 +100,10 @@ public class TestABCase4
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
|
Parser parser = new UnitParser(policy,capture);
|
||||||
try (StacklessLogging logging = new StacklessLogging(Parser.class))
|
|
||||||
{
|
expectedException.expect(ProtocolException.class);
|
||||||
Parser parser = new UnitParser(policy);
|
expectedException.expectMessage(containsString("Unknown opcode: 4"));
|
||||||
parser.setIncomingFramesHandler(capture);
|
parser.parse(expected);
|
||||||
try
|
|
||||||
{
|
|
||||||
parser.parse(expected);
|
|
||||||
}
|
|
||||||
catch (ProtocolException ignore)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.assertEquals("error on undefined opcode",1,capture.getErrorCount(WebSocketException.class));
|
|
||||||
|
|
||||||
Throwable known = capture.getErrors().poll();
|
|
||||||
|
|
||||||
Assert.assertTrue("undefined option should be in message",known.getMessage().contains("Unknown opcode: 4"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.common.ab;
|
package org.eclipse.jetty.websocket.common.ab;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
@ -39,12 +38,18 @@ import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
|
||||||
import org.eclipse.jetty.websocket.common.test.UnitGenerator;
|
import org.eclipse.jetty.websocket.common.test.UnitGenerator;
|
||||||
import org.eclipse.jetty.websocket.common.test.UnitParser;
|
import org.eclipse.jetty.websocket.common.test.UnitParser;
|
||||||
import org.eclipse.jetty.websocket.common.util.Hex;
|
import org.eclipse.jetty.websocket.common.util.Hex;
|
||||||
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
public class TestABCase7_3
|
public class TestABCase7_3
|
||||||
{
|
{
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
@Rule
|
||||||
|
public ExpectedException expectedException = ExpectedException.none();
|
||||||
|
|
||||||
|
private WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase7_3_1GenerateEmptyClose()
|
public void testCase7_3_1GenerateEmptyClose()
|
||||||
|
@ -73,20 +78,16 @@ public class TestABCase7_3
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.CLOSE,1);
|
capture.assertHasFrame(OpCode.CLOSE,1);
|
||||||
|
|
||||||
Frame pActual = capture.getFrames().poll();
|
Frame pActual = capture.getFrames().poll();
|
||||||
Assert.assertThat("CloseFrame.payloadLength",pActual.getPayloadLength(),is(0));
|
Assert.assertThat("CloseFrame.payloadLength",pActual.getPayloadLength(),is(0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test(expected = ProtocolException.class)
|
@Test(expected = ProtocolException.class)
|
||||||
public void testCase7_3_2Generate1BytePayloadClose()
|
public void testCase7_3_2Generate1BytePayloadClose()
|
||||||
{
|
{
|
||||||
|
@ -100,17 +101,13 @@ public class TestABCase7_3
|
||||||
public void testCase7_3_2Parse1BytePayloadClose()
|
public void testCase7_3_2Parse1BytePayloadClose()
|
||||||
{
|
{
|
||||||
ByteBuffer expected = Hex.asByteBuffer("880100");
|
ByteBuffer expected = Hex.asByteBuffer("880100");
|
||||||
|
|
||||||
UnitParser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parseQuietly(expected);
|
|
||||||
|
expectedException.expect(ProtocolException.class);
|
||||||
Assert.assertEquals("error on invalid close payload",1,capture.getErrorCount(ProtocolException.class));
|
expectedException.expectMessage(CoreMatchers.containsString("Invalid close frame payload length"));
|
||||||
|
parser.parse(expected);
|
||||||
ProtocolException known = (ProtocolException)capture.getErrors().poll();
|
|
||||||
|
|
||||||
Assert.assertThat("Payload.message",known.getMessage(),containsString("Invalid close frame payload length"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -139,21 +136,17 @@ public class TestABCase7_3
|
||||||
{ (byte)0x88, (byte)0x02, 0x03, (byte)0xe8 });
|
{ (byte)0x88, (byte)0x02, 0x03, (byte)0xe8 });
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.CLOSE,1);
|
capture.assertHasFrame(OpCode.CLOSE,1);
|
||||||
|
|
||||||
Frame pActual = capture.getFrames().poll();
|
Frame pActual = capture.getFrames().poll();
|
||||||
Assert.assertThat("CloseFrame.payloadLength",pActual.getPayloadLength(),is(2));
|
Assert.assertThat("CloseFrame.payloadLength",pActual.getPayloadLength(),is(2));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCase7_3_4GenerateCloseWithStatusReason()
|
public void testCase7_3_4GenerateCloseWithStatusReason()
|
||||||
{
|
{
|
||||||
|
@ -196,18 +189,15 @@ public class TestABCase7_3
|
||||||
expected.putShort((short)1000);
|
expected.putShort((short)1000);
|
||||||
expected.put(messageBytes);
|
expected.put(messageBytes);
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.CLOSE,1);
|
capture.assertHasFrame(OpCode.CLOSE,1);
|
||||||
|
|
||||||
Frame pActual = capture.getFrames().poll();
|
Frame pActual = capture.getFrames().poll();
|
||||||
Assert.assertThat("CloseFrame.payloadLength",pActual.getPayloadLength(),is(messageBytes.length + 2));
|
Assert.assertThat("CloseFrame.payloadLength",pActual.getPayloadLength(),is(messageBytes.length + 2));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -265,18 +255,15 @@ public class TestABCase7_3
|
||||||
|
|
||||||
expected.put(messageBytes);
|
expected.put(messageBytes);
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
Parser parser = new UnitParser(policy,capture);
|
||||||
parser.parse(expected);
|
parser.parse(expected);
|
||||||
|
|
||||||
capture.assertNoErrors();
|
|
||||||
capture.assertHasFrame(OpCode.CLOSE,1);
|
capture.assertHasFrame(OpCode.CLOSE,1);
|
||||||
|
|
||||||
Frame pActual = capture.getFrames().poll();
|
Frame pActual = capture.getFrames().poll();
|
||||||
Assert.assertThat("CloseFrame.payloadLength",pActual.getPayloadLength(),is(125));
|
Assert.assertThat("CloseFrame.payloadLength",pActual.getPayloadLength(),is(125));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = ProtocolException.class)
|
@Test(expected = ProtocolException.class)
|
||||||
|
@ -334,16 +321,12 @@ public class TestABCase7_3
|
||||||
expected.put(messageBytes); // reason
|
expected.put(messageBytes); // reason
|
||||||
|
|
||||||
expected.flip();
|
expected.flip();
|
||||||
|
|
||||||
UnitParser parser = new UnitParser(policy);
|
|
||||||
IncomingFramesCapture capture = new IncomingFramesCapture();
|
IncomingFramesCapture capture = new IncomingFramesCapture();
|
||||||
parser.setIncomingFramesHandler(capture);
|
UnitParser parser = new UnitParser(policy,capture);
|
||||||
parser.parseQuietly(expected);
|
|
||||||
|
expectedException.expect(ProtocolException.class);
|
||||||
Assert.assertEquals("error on invalid close payload",1,capture.getErrorCount(ProtocolException.class));
|
expectedException.expectMessage(CoreMatchers.containsString("Invalid control frame payload length"));
|
||||||
|
parser.parse(expected);
|
||||||
ProtocolException known = (ProtocolException)capture.getErrors().poll();
|
|
||||||
|
|
||||||
Assert.assertThat("Payload.message",known.getMessage(),containsString("Invalid control frame payload length"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.common.extensions;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ public class DummyIncomingFrames implements IncomingFrames
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
LOG.debug("incomingFrame({})",frame);
|
LOG.debug("incomingFrame({})",frame);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ package org.eclipse.jetty.websocket.common.extensions;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
import org.junit.rules.TestName;
|
import org.junit.rules.TestName;
|
||||||
|
@ -45,12 +45,12 @@ public class DummyOutgoingFrames implements OutgoingFrames
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
LOG.debug("outgoingFrame({},{})",frame,callback);
|
LOG.debug("outgoingFrame({},{})",frame,callback);
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.eclipse.jetty.websocket.api.extensions.Extension;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
import org.eclipse.jetty.websocket.common.FrameCallbackAdapter;
|
||||||
import org.eclipse.jetty.websocket.common.Parser;
|
import org.eclipse.jetty.websocket.common.Parser;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
|
@ -57,8 +58,9 @@ public class ExtensionTool
|
||||||
this.extConfig = ExtensionConfig.parse(parameterizedExtension);
|
this.extConfig = ExtensionConfig.parse(parameterizedExtension);
|
||||||
Class<?> extClass = factory.getExtension(extConfig.getName());
|
Class<?> extClass = factory.getExtension(extConfig.getName());
|
||||||
Assert.assertThat("extClass", extClass, notNullValue());
|
Assert.assertThat("extClass", extClass, notNullValue());
|
||||||
|
|
||||||
this.parser = new UnitParser(policy);
|
this.capture = new IncomingFramesCapture();
|
||||||
|
this.parser = new UnitParser(policy,frame -> ext.incomingFrame(frame, new FrameCallbackAdapter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRequestedExtParams()
|
public String getRequestedExtParams()
|
||||||
|
@ -68,15 +70,12 @@ public class ExtensionTool
|
||||||
|
|
||||||
public void assertNegotiated(String expectedNegotiation)
|
public void assertNegotiated(String expectedNegotiation)
|
||||||
{
|
{
|
||||||
this.ext = (Extension)factory.newInstance(extConfig);
|
this.ext = factory.newInstance(extConfig);
|
||||||
|
|
||||||
this.capture = new IncomingFramesCapture();
|
|
||||||
this.ext.setNextIncomingFrames(capture);
|
this.ext.setNextIncomingFrames(capture);
|
||||||
|
|
||||||
this.parser.configureFromExtensions(Collections.singletonList(ext));
|
this.parser.configureFromExtensions(Collections.singletonList(ext));
|
||||||
this.parser.setIncomingFramesHandler(ext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parseIncomingHex(String... rawhex)
|
public void parseIncomingHex(String... rawhex)
|
||||||
{
|
{
|
||||||
int parts = rawhex.length;
|
int parts = rawhex.length;
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
import org.eclipse.jetty.websocket.common.FrameCallbackAdapter;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.extensions.fragment.FragmentExtension;
|
import org.eclipse.jetty.websocket.common.extensions.fragment.FragmentExtension;
|
||||||
|
@ -77,7 +78,7 @@ public class FragmentExtensionTest
|
||||||
for (String q : quote)
|
for (String q : quote)
|
||||||
{
|
{
|
||||||
Frame frame = new TextFrame().setPayload(q);
|
Frame frame = new TextFrame().setPayload(q);
|
||||||
ext.incomingFrame(frame);
|
ext.incomingFrame(frame, new FrameCallbackAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = quote.size();
|
int len = quote.size();
|
||||||
|
@ -121,7 +122,7 @@ public class FragmentExtensionTest
|
||||||
|
|
||||||
String payload = "Are you there?";
|
String payload = "Are you there?";
|
||||||
Frame ping = new PingFrame().setPayload(payload);
|
Frame ping = new PingFrame().setPayload(payload);
|
||||||
ext.incomingFrame(ping);
|
ext.incomingFrame(ping, new FrameCallbackAdapter());
|
||||||
|
|
||||||
capture.assertFrameCount(1);
|
capture.assertFrameCount(1);
|
||||||
capture.assertHasFrame(OpCode.PING, 1);
|
capture.assertHasFrame(OpCode.PING, 1);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
import org.eclipse.jetty.websocket.common.FrameCallbackAdapter;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.extensions.identity.IdentityExtension;
|
import org.eclipse.jetty.websocket.common.extensions.identity.IdentityExtension;
|
||||||
|
@ -52,7 +53,7 @@ public class IdentityExtensionTest
|
||||||
ext.setNextIncomingFrames(capture);
|
ext.setNextIncomingFrames(capture);
|
||||||
|
|
||||||
Frame frame = new TextFrame().setPayload("hello");
|
Frame frame = new TextFrame().setPayload("hello");
|
||||||
ext.incomingFrame(frame);
|
ext.incomingFrame(frame, new FrameCallbackAdapter());
|
||||||
|
|
||||||
capture.assertFrameCount(1);
|
capture.assertFrameCount(1);
|
||||||
capture.assertHasFrame(OpCode.TEXT, 1);
|
capture.assertHasFrame(OpCode.TEXT, 1);
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
import org.eclipse.jetty.websocket.common.util.Hex;
|
import org.eclipse.jetty.websocket.common.util.Hex;
|
||||||
|
@ -32,13 +32,13 @@ public class CapturedHexPayloads implements OutgoingFrames
|
||||||
private List<String> captured = new ArrayList<>();
|
private List<String> captured = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
String hexPayload = Hex.asHex(frame.getPayload());
|
String hexPayload = Hex.asHex(frame.getPayload());
|
||||||
captured.add(hexPayload);
|
captured.add(hexPayload);
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,13 @@ import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
|
import org.eclipse.jetty.websocket.common.FrameCallbackAdapter;
|
||||||
import org.eclipse.jetty.websocket.common.Generator;
|
import org.eclipse.jetty.websocket.common.Generator;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.Parser;
|
import org.eclipse.jetty.websocket.common.Parser;
|
||||||
|
@ -86,10 +87,8 @@ public class DeflateFrameExtensionTest extends AbstractExtensionTest
|
||||||
// Wire up stack
|
// Wire up stack
|
||||||
ext.setNextIncomingFrames(capture);
|
ext.setNextIncomingFrames(capture);
|
||||||
|
|
||||||
Parser parser = new UnitParser(policy);
|
Parser parser = new UnitParser(policy, frame -> ext.incomingFrame(frame, new FrameCallbackAdapter()));
|
||||||
parser.configureFromExtensions(Collections.singletonList(ext));
|
parser.configureFromExtensions(Collections.singletonList(ext));
|
||||||
parser.setIncomingFramesHandler(ext);
|
|
||||||
|
|
||||||
parser.parse(ByteBuffer.wrap(raw));
|
parser.parse(ByteBuffer.wrap(raw));
|
||||||
|
|
||||||
int len = expectedTextDatas.length;
|
int len = expectedTextDatas.length;
|
||||||
|
@ -410,11 +409,11 @@ public class DeflateFrameExtensionTest extends AbstractExtensionTest
|
||||||
clientExtension.setNextOutgoingFrames(new OutgoingFrames()
|
clientExtension.setNextOutgoingFrames(new OutgoingFrames()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
LOG.debug("outgoingFrame({})", frame);
|
LOG.debug("outgoingFrame({})", frame);
|
||||||
serverExtension.incomingFrame(frame);
|
serverExtension.incomingFrame(frame, callback);
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -422,7 +421,7 @@ public class DeflateFrameExtensionTest extends AbstractExtensionTest
|
||||||
serverExtension.setNextIncomingFrames(new IncomingFrames()
|
serverExtension.setNextIncomingFrames(new IncomingFrames()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
LOG.debug("incomingFrame({})", frame);
|
LOG.debug("incomingFrame({})", frame);
|
||||||
try
|
try
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
import org.eclipse.jetty.websocket.common.FrameCallbackAdapter;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.extensions.AbstractExtensionTest;
|
import org.eclipse.jetty.websocket.common.extensions.AbstractExtensionTest;
|
||||||
|
@ -245,7 +246,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest
|
||||||
|
|
||||||
String payload = "Are you there?";
|
String payload = "Are you there?";
|
||||||
Frame ping = new PingFrame().setPayload(payload);
|
Frame ping = new PingFrame().setPayload(payload);
|
||||||
ext.incomingFrame(ping);
|
ext.incomingFrame(ping, new FrameCallbackAdapter());
|
||||||
|
|
||||||
capture.assertFrameCount(1);
|
capture.assertFrameCount(1);
|
||||||
capture.assertHasFrame(OpCode.PING, 1);
|
capture.assertHasFrame(OpCode.PING, 1);
|
||||||
|
@ -291,7 +292,7 @@ public class PerMessageDeflateExtensionTest extends AbstractExtensionTest
|
||||||
{
|
{
|
||||||
TextFrame frame = new TextFrame().setPayload(q);
|
TextFrame frame = new TextFrame().setPayload(q);
|
||||||
frame.setRsv1(false); // indication to extension that frame is not compressed (ie: a normal frame)
|
frame.setRsv1(false); // indication to extension that frame is not compressed (ie: a normal frame)
|
||||||
ext.incomingFrame(frame);
|
ext.incomingFrame(frame, new FrameCallbackAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = quote.size();
|
int len = quote.size();
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketConnectionListener;
|
import org.eclipse.jetty.websocket.api.WebSocketConnectionListener;
|
||||||
|
@ -41,6 +42,8 @@ import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.ContinuationFrame;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.io.LocalWebSocketSession;
|
import org.eclipse.jetty.websocket.common.io.LocalWebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
||||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||||
|
@ -108,7 +111,7 @@ public class CommonEndpointFunctionsTest
|
||||||
{
|
{
|
||||||
// Trigger Events
|
// Trigger Events
|
||||||
endpointFunctions.onOpen(session);
|
endpointFunctions.onOpen(session);
|
||||||
endpointFunctions.onText(BufferUtil.toBuffer("Hello?", UTF8), true);
|
endpointFunctions.onText(new TextFrame().setPayload("Hello?").setFin(true), new FrameCallback.Adapter());
|
||||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +146,7 @@ public class CommonEndpointFunctionsTest
|
||||||
{
|
{
|
||||||
// Trigger Events
|
// Trigger Events
|
||||||
endpointFunctions.onOpen(session);
|
endpointFunctions.onOpen(session);
|
||||||
endpointFunctions.onText(BufferUtil.toBuffer("Hello Text", UTF8), true);
|
endpointFunctions.onText(new TextFrame().setPayload("Hello Text").setFin(true), new FrameCallback.Adapter());
|
||||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +191,7 @@ public class CommonEndpointFunctionsTest
|
||||||
{
|
{
|
||||||
// Trigger Events
|
// Trigger Events
|
||||||
endpointFunctions.onOpen(session);
|
endpointFunctions.onOpen(session);
|
||||||
endpointFunctions.onText(BufferUtil.toBuffer("Hello Text Stream", UTF8), true);
|
endpointFunctions.onText(new TextFrame().setPayload("Hello Text Stream").setFin(true), new FrameCallback.Adapter());
|
||||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,10 +212,10 @@ public class CommonEndpointFunctionsTest
|
||||||
{
|
{
|
||||||
// Trigger Events
|
// Trigger Events
|
||||||
endpointFunctions.onOpen(session);
|
endpointFunctions.onOpen(session);
|
||||||
endpointFunctions.onText(BufferUtil.toBuffer("Hel"), false);
|
endpointFunctions.onText(new TextFrame().setPayload("Hel").setFin(false), new FrameCallback.Adapter());
|
||||||
endpointFunctions.onText(BufferUtil.toBuffer("lo "), false);
|
endpointFunctions.onText(new ContinuationFrame().setPayload("lo ").setFin(false), new FrameCallback.Adapter());
|
||||||
endpointFunctions.onText(BufferUtil.toBuffer("Wor"), false);
|
endpointFunctions.onText(new ContinuationFrame().setPayload("Wor").setFin(false), new FrameCallback.Adapter());
|
||||||
endpointFunctions.onText(BufferUtil.toBuffer("ld"), true);
|
endpointFunctions.onText(new ContinuationFrame().setPayload("ld").setFin(true), new FrameCallback.Adapter());
|
||||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,9 +251,9 @@ public class CommonEndpointFunctionsTest
|
||||||
{
|
{
|
||||||
// Trigger Events
|
// Trigger Events
|
||||||
endpointFunctions.onOpen(session);
|
endpointFunctions.onOpen(session);
|
||||||
endpointFunctions.onText(BufferUtil.toBuffer("Hello"), false);
|
endpointFunctions.onText(new TextFrame().setPayload("Hello").setFin(false), new FrameCallback.Adapter());
|
||||||
endpointFunctions.onText(BufferUtil.toBuffer(" "), false);
|
endpointFunctions.onText(new ContinuationFrame().setPayload(" ").setFin(false), new FrameCallback.Adapter());
|
||||||
endpointFunctions.onText(BufferUtil.toBuffer("World"), true);
|
endpointFunctions.onText(new ContinuationFrame().setPayload("World").setFin(true), new FrameCallback.Adapter());
|
||||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,12 +26,11 @@ import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.thread.ExecutorThreadPool;
|
import org.eclipse.jetty.util.thread.ExecutorThreadPool;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.SuspendToken;
|
import org.eclipse.jetty.websocket.api.SuspendToken;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
import org.eclipse.jetty.websocket.common.ConnectionState;
|
import org.eclipse.jetty.websocket.common.ConnectionState;
|
||||||
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
||||||
|
@ -39,14 +38,13 @@ import org.eclipse.jetty.websocket.common.io.IOState.ConnectionStateListener;
|
||||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||||
import org.junit.rules.TestName;
|
import org.junit.rules.TestName;
|
||||||
|
|
||||||
public class LocalWebSocketConnection implements LogicalConnection, IncomingFrames, ConnectionStateListener
|
public class LocalWebSocketConnection implements LogicalConnection, ConnectionStateListener
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(LocalWebSocketConnection.class);
|
private static final Logger LOG = Log.getLogger(LocalWebSocketConnection.class);
|
||||||
private final String id;
|
private final String id;
|
||||||
private final ByteBufferPool bufferPool;
|
private final ByteBufferPool bufferPool;
|
||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
private WebSocketPolicy policy;
|
private WebSocketPolicy policy;
|
||||||
private IncomingFrames incoming;
|
|
||||||
private IOState ioState = new IOState();
|
private IOState ioState = new IOState();
|
||||||
|
|
||||||
public LocalWebSocketConnection(ByteBufferPool bufferPool)
|
public LocalWebSocketConnection(ByteBufferPool bufferPool)
|
||||||
|
@ -127,11 +125,6 @@ public class LocalWebSocketConnection implements LogicalConnection, IncomingFram
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IncomingFrames getIncoming()
|
|
||||||
{
|
|
||||||
return incoming;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IOState getIOState()
|
public IOState getIOState()
|
||||||
{
|
{
|
||||||
|
@ -162,18 +155,6 @@ public class LocalWebSocketConnection implements LogicalConnection, IncomingFram
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void incomingError(Throwable e)
|
|
||||||
{
|
|
||||||
incoming.incomingError(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void incomingFrame(Frame frame)
|
|
||||||
{
|
|
||||||
incoming.incomingFrame(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpen()
|
public boolean isOpen()
|
||||||
{
|
{
|
||||||
|
@ -217,7 +198,7 @@ public class LocalWebSocketConnection implements LogicalConnection, IncomingFram
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,12 +212,6 @@ public class LocalWebSocketConnection implements LogicalConnection, IncomingFram
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNextIncomingFrames(IncomingFrames incoming)
|
|
||||||
{
|
|
||||||
this.incoming = incoming;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPolicy(WebSocketPolicy policy)
|
public void setPolicy(WebSocketPolicy policy)
|
||||||
{
|
{
|
||||||
this.policy = policy;
|
this.policy = policy;
|
||||||
|
|
|
@ -27,7 +27,11 @@ import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.BinaryFrame;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.ContinuationFrame;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.LeakTrackingBufferPoolRule;
|
import org.eclipse.jetty.websocket.common.test.LeakTrackingBufferPoolRule;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
|
@ -48,9 +52,10 @@ public class MessageInputStreamTest
|
||||||
try (MessageInputStream stream = new MessageInputStream())
|
try (MessageInputStream stream = new MessageInputStream())
|
||||||
{
|
{
|
||||||
// Append a single message (simple, short)
|
// Append a single message (simple, short)
|
||||||
ByteBuffer payload = BufferUtil.toBuffer("Hello World",StandardCharsets.UTF_8);
|
TextFrame frame = new TextFrame();
|
||||||
boolean fin = true;
|
frame.setPayload("Hello World");
|
||||||
stream.accept(payload,fin);
|
frame.setFin(true);
|
||||||
|
stream.accept(frame, new FrameCallback.Adapter());
|
||||||
|
|
||||||
// Read entire message it from the stream.
|
// Read entire message it from the stream.
|
||||||
byte buf[] = new byte[32];
|
byte buf[] = new byte[32];
|
||||||
|
@ -80,14 +85,12 @@ public class MessageInputStreamTest
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
startLatch.countDown();
|
startLatch.countDown();
|
||||||
boolean fin = false;
|
|
||||||
TimeUnit.MILLISECONDS.sleep(200);
|
TimeUnit.MILLISECONDS.sleep(200);
|
||||||
stream.accept(BufferUtil.toBuffer("Saved",StandardCharsets.UTF_8),fin);
|
stream.accept(new BinaryFrame().setPayload("Saved").setFin(false), new FrameCallback.Adapter());
|
||||||
TimeUnit.MILLISECONDS.sleep(200);
|
TimeUnit.MILLISECONDS.sleep(200);
|
||||||
stream.accept(BufferUtil.toBuffer(" by ",StandardCharsets.UTF_8),fin);
|
stream.accept(new ContinuationFrame().setPayload(" by ").setFin(false), new FrameCallback.Adapter());
|
||||||
fin = true;
|
|
||||||
TimeUnit.MILLISECONDS.sleep(200);
|
TimeUnit.MILLISECONDS.sleep(200);
|
||||||
stream.accept(BufferUtil.toBuffer("Zero",StandardCharsets.UTF_8),fin);
|
stream.accept(new ContinuationFrame().setPayload("Zero").setFin(true), new FrameCallback.Adapter());
|
||||||
}
|
}
|
||||||
catch (InterruptedException e)
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
|
@ -125,10 +128,9 @@ public class MessageInputStreamTest
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
boolean fin = true;
|
|
||||||
// wait for a little bit before populating buffers
|
// wait for a little bit before populating buffers
|
||||||
TimeUnit.MILLISECONDS.sleep(400);
|
TimeUnit.MILLISECONDS.sleep(400);
|
||||||
stream.accept(BufferUtil.toBuffer("I will conquer",StandardCharsets.UTF_8),fin);
|
stream.accept(new BinaryFrame().setPayload("I will conquer").setFin(true), new FrameCallback.Adapter());
|
||||||
}
|
}
|
||||||
catch (InterruptedException e)
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
|
@ -189,13 +191,14 @@ public class MessageInputStreamTest
|
||||||
try (MessageInputStream stream = new MessageInputStream())
|
try (MessageInputStream stream = new MessageInputStream())
|
||||||
{
|
{
|
||||||
// Append parts of message
|
// Append parts of message
|
||||||
ByteBuffer msg1 = BufferUtil.toBuffer("Hello ",StandardCharsets.UTF_8);
|
WebSocketFrame msg1 = new BinaryFrame().setPayload("Hello ").setFin(false);
|
||||||
ByteBuffer msg2 = ByteBuffer.allocate(0); // what is being tested
|
// what is being tested (an empty payload)
|
||||||
ByteBuffer msg3 = BufferUtil.toBuffer("World",StandardCharsets.UTF_8);
|
WebSocketFrame msg2 = new ContinuationFrame().setPayload(new byte[0]).setFin(false);
|
||||||
|
WebSocketFrame msg3 = new ContinuationFrame().setPayload("World").setFin(true);
|
||||||
|
|
||||||
stream.accept(msg1,false);
|
stream.accept(msg1, new FrameCallback.Adapter());
|
||||||
stream.accept(msg2,false);
|
stream.accept(msg2, new FrameCallback.Adapter());
|
||||||
stream.accept(msg3,true);
|
stream.accept(msg3, new FrameCallback.Adapter());
|
||||||
|
|
||||||
// Read entire message it from the stream.
|
// Read entire message it from the stream.
|
||||||
byte buf[] = new byte[32];
|
byte buf[] = new byte[32];
|
||||||
|
@ -213,13 +216,15 @@ public class MessageInputStreamTest
|
||||||
try (MessageInputStream stream = new MessageInputStream())
|
try (MessageInputStream stream = new MessageInputStream())
|
||||||
{
|
{
|
||||||
// Append parts of message
|
// Append parts of message
|
||||||
ByteBuffer msg1 = BufferUtil.toBuffer("Hello ",StandardCharsets.UTF_8);
|
WebSocketFrame msg1 = new BinaryFrame().setPayload("Hello ").setFin(false);
|
||||||
ByteBuffer msg2 = null; // what is being tested
|
// what is being tested (a null payload)
|
||||||
ByteBuffer msg3 = BufferUtil.toBuffer("World",StandardCharsets.UTF_8);
|
ByteBuffer nilPayload = null;
|
||||||
|
WebSocketFrame msg2 = new ContinuationFrame().setPayload(nilPayload).setFin(false);
|
||||||
|
WebSocketFrame msg3 = new ContinuationFrame().setPayload("World").setFin(true);
|
||||||
|
|
||||||
stream.accept(msg1,false);
|
stream.accept(msg1, new FrameCallback.Adapter());
|
||||||
stream.accept(msg2,false);
|
stream.accept(msg2, new FrameCallback.Adapter());
|
||||||
stream.accept(msg3,true);
|
stream.accept(msg3, new FrameCallback.Adapter());
|
||||||
|
|
||||||
// Read entire message it from the stream.
|
// Read entire message it from the stream.
|
||||||
byte buf[] = new byte[32];
|
byte buf[] = new byte[32];
|
||||||
|
|
|
@ -22,6 +22,7 @@ import static org.hamcrest.Matchers.allOf;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||||
|
@ -31,7 +32,7 @@ import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.common.io.FramePipes;
|
import org.eclipse.jetty.websocket.common.io.FramePipes;
|
||||||
import org.eclipse.jetty.websocket.common.io.LocalWebSocketSession;
|
import org.eclipse.jetty.websocket.common.io.LocalWebSocketConnection;
|
||||||
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
||||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||||
import org.eclipse.jetty.websocket.common.test.LeakTrackingBufferPoolRule;
|
import org.eclipse.jetty.websocket.common.test.LeakTrackingBufferPoolRule;
|
||||||
|
@ -57,7 +58,7 @@ public class MessageOutputStreamTest
|
||||||
|
|
||||||
private WebSocketPolicy policy;
|
private WebSocketPolicy policy;
|
||||||
private TrackingSocket remoteSocket;
|
private TrackingSocket remoteSocket;
|
||||||
private LocalWebSocketSession session;
|
private WebSocketSession session;
|
||||||
private WebSocketSession remoteSession;
|
private WebSocketSession remoteSession;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -81,14 +82,18 @@ public class MessageOutputStreamTest
|
||||||
|
|
||||||
// remote socket
|
// remote socket
|
||||||
remoteSocket = new TrackingSocket("remote");
|
remoteSocket = new TrackingSocket("remote");
|
||||||
remoteSession = new LocalWebSocketSession(containerScope,testname,remoteSocket);
|
URI remoteURI = new URI("ws://localhost/remote");
|
||||||
|
LocalWebSocketConnection remoteConnection = new LocalWebSocketConnection(bufferPool);
|
||||||
|
remoteSession = new WebSocketSession(containerScope,remoteURI,remoteSocket,remoteConnection);
|
||||||
OutgoingFrames socketPipe = FramePipes.to(remoteSession);
|
OutgoingFrames socketPipe = FramePipes.to(remoteSession);
|
||||||
remoteSession.start();
|
remoteSession.start();
|
||||||
remoteSession.open();
|
remoteSession.open();
|
||||||
|
|
||||||
// Local Session
|
// Local Session
|
||||||
TrackingSocket localSocket = new TrackingSocket("local");
|
TrackingSocket localSocket = new TrackingSocket("local");
|
||||||
session = new LocalWebSocketSession(containerScope,testname,localSocket);
|
URI localURI = new URI("ws://localhost/local");
|
||||||
|
LocalWebSocketConnection localConnection = new LocalWebSocketConnection(bufferPool);
|
||||||
|
session = new WebSocketSession(containerScope,localURI,localSocket,localConnection);
|
||||||
|
|
||||||
// talk to our remote socket
|
// talk to our remote socket
|
||||||
session.setOutgoingHandler(socketPipe);
|
session.setOutgoingHandler(socketPipe);
|
||||||
|
@ -98,7 +103,7 @@ public class MessageOutputStreamTest
|
||||||
session.open();
|
session.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(timeout = 2000)
|
||||||
public void testMultipleWrites() throws Exception
|
public void testMultipleWrites() throws Exception
|
||||||
{
|
{
|
||||||
try (MessageOutputStream stream = new MessageOutputStream(session))
|
try (MessageOutputStream stream = new MessageOutputStream(session))
|
||||||
|
@ -112,8 +117,8 @@ public class MessageOutputStreamTest
|
||||||
String msg = remoteSocket.messageQueue.poll();
|
String msg = remoteSocket.messageQueue.poll();
|
||||||
Assert.assertThat("Message",msg,allOf(containsString("byte[11]"),containsString("Hello World")));
|
Assert.assertThat("Message",msg,allOf(containsString("byte[11]"),containsString("Hello World")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(timeout = 2000)
|
||||||
public void testSingleWrite() throws Exception
|
public void testSingleWrite() throws Exception
|
||||||
{
|
{
|
||||||
try (MessageOutputStream stream = new MessageOutputStream(session))
|
try (MessageOutputStream stream = new MessageOutputStream(session))
|
||||||
|
@ -125,8 +130,8 @@ public class MessageOutputStreamTest
|
||||||
String msg = remoteSocket.messageQueue.poll();
|
String msg = remoteSocket.messageQueue.poll();
|
||||||
Assert.assertThat("Message",msg,allOf(containsString("byte[11]"),containsString("Hello World")));
|
Assert.assertThat("Message",msg,allOf(containsString("byte[11]"),containsString("Hello World")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(timeout = 2000)
|
||||||
public void testWriteMultipleBuffers() throws Exception
|
public void testWriteMultipleBuffers() throws Exception
|
||||||
{
|
{
|
||||||
int bufsize = (int)(policy.getMaxBinaryMessageBufferSize() * 2.5);
|
int bufsize = (int)(policy.getMaxBinaryMessageBufferSize() * 2.5);
|
||||||
|
|
|
@ -100,8 +100,8 @@ public class MessageWriterTest
|
||||||
// open connection
|
// open connection
|
||||||
session.open();
|
session.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(timeout = 2000)
|
||||||
public void testMultipleWrites() throws Exception
|
public void testMultipleWrites() throws Exception
|
||||||
{
|
{
|
||||||
try (MessageWriter stream = new MessageWriter(session))
|
try (MessageWriter stream = new MessageWriter(session))
|
||||||
|
@ -115,8 +115,8 @@ public class MessageWriterTest
|
||||||
String msg = remoteSocket.messageQueue.poll();
|
String msg = remoteSocket.messageQueue.poll();
|
||||||
Assert.assertThat("Message",msg,is("Hello World"));
|
Assert.assertThat("Message",msg,is("Hello World"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(timeout = 20000)
|
||||||
public void testSingleWrite() throws Exception
|
public void testSingleWrite() throws Exception
|
||||||
{
|
{
|
||||||
try (MessageWriter stream = new MessageWriter(session))
|
try (MessageWriter stream = new MessageWriter(session))
|
||||||
|
@ -128,8 +128,8 @@ public class MessageWriterTest
|
||||||
String msg = remoteSocket.messageQueue.poll();
|
String msg = remoteSocket.messageQueue.poll();
|
||||||
Assert.assertThat("Message",msg,is("Hello World"));
|
Assert.assertThat("Message",msg,is("Hello World"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(timeout = 2000)
|
||||||
public void testWriteMultipleBuffers() throws Exception
|
public void testWriteMultipleBuffers() throws Exception
|
||||||
{
|
{
|
||||||
int bufsize = (int)(policy.getMaxTextMessageBufferSize() * 2.5);
|
int bufsize = (int)(policy.getMaxTextMessageBufferSize() * 2.5);
|
||||||
|
|
|
@ -54,8 +54,8 @@ import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||||
|
@ -88,7 +88,7 @@ import org.junit.Assert;
|
||||||
* with regards to basic IO behavior, a write should work as expected, a read should work as expected, but <u>what</u> byte it sends or reads is not within its
|
* with regards to basic IO behavior, a write should work as expected, a read should work as expected, but <u>what</u> byte it sends or reads is not within its
|
||||||
* scope.
|
* scope.
|
||||||
*/
|
*/
|
||||||
public class BlockheadClient implements OutgoingFrames, ConnectionStateListener, AutoCloseable, IBlockheadClient
|
public class BlockheadClient implements OutgoingFrames, ConnectionStateListener, AutoCloseable, IBlockheadClient, Parser.Handler
|
||||||
{
|
{
|
||||||
private class FrameReadingThread extends Thread implements Runnable, IncomingFrames
|
private class FrameReadingThread extends Thread implements Runnable, IncomingFrames
|
||||||
{
|
{
|
||||||
|
@ -167,7 +167,7 @@ public class BlockheadClient implements OutgoingFrames, ConnectionStateListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void incomingFrame(Frame frame)
|
public synchronized void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
this.frames.add(WebSocketFrame.copy(frame));
|
this.frames.add(WebSocketFrame.copy(frame));
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ public class BlockheadClient implements OutgoingFrames, ConnectionStateListener,
|
||||||
// This is a blockhead client, no point tracking leaks on this object.
|
// This is a blockhead client, no point tracking leaks on this object.
|
||||||
this.bufferPool = new MappedByteBufferPool(8192);
|
this.bufferPool = new MappedByteBufferPool(8192);
|
||||||
this.generator = new Generator(policy,bufferPool);
|
this.generator = new Generator(policy,bufferPool);
|
||||||
this.parser = new Parser(policy,bufferPool);
|
this.parser = new Parser(policy,bufferPool,this);
|
||||||
|
|
||||||
this.extensionFactory = new WebSocketExtensionFactory(new SimpleContainerScope(policy,bufferPool));
|
this.extensionFactory = new WebSocketExtensionFactory(new SimpleContainerScope(policy,bufferPool));
|
||||||
this.ioState = new IOState();
|
this.ioState = new IOState();
|
||||||
|
@ -435,7 +435,6 @@ public class BlockheadClient implements OutgoingFrames, ConnectionStateListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure parser
|
// configure parser
|
||||||
parser.setIncomingFramesHandler(extensionStack);
|
|
||||||
ioState.onOpened();
|
ioState.onOpened();
|
||||||
|
|
||||||
LOG.debug("outgoing = {}",outgoing);
|
LOG.debug("outgoing = {}",outgoing);
|
||||||
|
@ -591,7 +590,7 @@ public class BlockheadClient implements OutgoingFrames, ConnectionStateListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
ByteBuffer headerBuf = generator.generateHeaderBytes(frame);
|
ByteBuffer headerBuf = generator.generateHeaderBytes(frame);
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
|
@ -605,14 +604,14 @@ public class BlockheadClient implements OutgoingFrames, ConnectionStateListener,
|
||||||
out.flush();
|
out.flush();
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeFailed(e);
|
callback.fail(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
@ -625,7 +624,13 @@ public class BlockheadClient implements OutgoingFrames, ConnectionStateListener,
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFrame(Frame frame)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
public EventQueue<WebSocketFrame> readFrames(int expectedFrameCount, int timeoutDuration, TimeUnit timeoutUnit) throws Exception
|
public EventQueue<WebSocketFrame> readFrames(int expectedFrameCount, int timeoutDuration, TimeUnit timeoutUnit) throws Exception
|
||||||
{
|
{
|
||||||
frameReader.frames.awaitEventCount(expectedFrameCount,timeoutDuration,timeoutUnit);
|
frameReader.frames.awaitEventCount(expectedFrameCount,timeoutDuration,timeoutUnit);
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.common.test;
|
package org.eclipse.jetty.websocket.common.test;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -46,15 +47,16 @@ import org.eclipse.jetty.util.IO;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.Frame.Type;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame.Type;
|
|
||||||
import org.eclipse.jetty.websocket.common.AcceptHash;
|
import org.eclipse.jetty.websocket.common.AcceptHash;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
|
import org.eclipse.jetty.websocket.common.FrameCallbackAdapter;
|
||||||
import org.eclipse.jetty.websocket.common.Generator;
|
import org.eclipse.jetty.websocket.common.Generator;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.Parser;
|
import org.eclipse.jetty.websocket.common.Parser;
|
||||||
|
@ -88,7 +90,8 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames
|
||||||
|
|
||||||
private Map<String, String> extraResponseHeaders = new HashMap<>();
|
private Map<String, String> extraResponseHeaders = new HashMap<>();
|
||||||
private OutgoingFrames outgoing = this;
|
private OutgoingFrames outgoing = this;
|
||||||
|
private ExtensionStack extensionStack;
|
||||||
|
|
||||||
public BlockheadServerConnection(Socket socket)
|
public BlockheadServerConnection(Socket socket)
|
||||||
{
|
{
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
|
@ -98,7 +101,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames
|
||||||
this.policy.setMaxTextMessageSize(100000);
|
this.policy.setMaxTextMessageSize(100000);
|
||||||
// This is a blockhead server connection, no point tracking leaks on this object.
|
// This is a blockhead server connection, no point tracking leaks on this object.
|
||||||
this.bufferPool = new MappedByteBufferPool(BUFFER_SIZE);
|
this.bufferPool = new MappedByteBufferPool(BUFFER_SIZE);
|
||||||
this.parser = new Parser(policy,bufferPool);
|
this.parser = new Parser(policy,bufferPool,frame -> extensionStack.incomingFrame(frame, new FrameCallbackAdapter()));
|
||||||
this.parseCount = new AtomicInteger(0);
|
this.parseCount = new AtomicInteger(0);
|
||||||
this.generator = new Generator(policy,bufferPool,false);
|
this.generator = new Generator(policy,bufferPool,false);
|
||||||
this.extensionRegistry = new WebSocketExtensionFactory(new SimpleContainerScope(policy,bufferPool));
|
this.extensionRegistry = new WebSocketExtensionFactory(new SimpleContainerScope(policy,bufferPool));
|
||||||
|
@ -214,7 +217,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
{
|
{
|
||||||
LOG.debug("incoming({})",frame);
|
LOG.debug("incoming({})",frame);
|
||||||
int count = parseCount.incrementAndGet();
|
int count = parseCount.incrementAndGet();
|
||||||
|
@ -222,7 +225,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames
|
||||||
{
|
{
|
||||||
LOG.info("Server parsed {} frames",count);
|
LOG.info("Server parsed {} frames",count);
|
||||||
}
|
}
|
||||||
incomingFrames.incomingFrame(WebSocketFrame.copy(frame));
|
incomingFrames.incomingFrame(WebSocketFrame.copy(frame), callback);
|
||||||
|
|
||||||
if (frame.getOpCode() == OpCode.CLOSE)
|
if (frame.getOpCode() == OpCode.CLOSE)
|
||||||
{
|
{
|
||||||
|
@ -245,7 +248,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
ByteBuffer headerBuf = generator.generateHeaderBytes(frame);
|
ByteBuffer headerBuf = generator.generateHeaderBytes(frame);
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
|
@ -261,7 +264,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames
|
||||||
out.flush();
|
out.flush();
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame.getOpCode() == OpCode.CLOSE)
|
if (frame.getOpCode() == OpCode.CLOSE)
|
||||||
|
@ -273,7 +276,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames
|
||||||
{
|
{
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeFailed(t);
|
callback.fail(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -514,7 +517,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames
|
||||||
Assert.assertThat("Request: Sec-WebSocket-Key",key,notNullValue());
|
Assert.assertThat("Request: Sec-WebSocket-Key",key,notNullValue());
|
||||||
|
|
||||||
// collect extensions configured in response header
|
// collect extensions configured in response header
|
||||||
ExtensionStack extensionStack = new ExtensionStack(extensionRegistry);
|
extensionStack = new ExtensionStack(extensionRegistry);
|
||||||
extensionStack.negotiate(extensionConfigs);
|
extensionStack.negotiate(extensionConfigs);
|
||||||
|
|
||||||
// Start with default routing
|
// Start with default routing
|
||||||
|
@ -535,9 +538,6 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames
|
||||||
throw new IOException("Unable to start Extension Stack");
|
throw new IOException("Unable to start Extension Stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure Parser
|
|
||||||
parser.setIncomingFramesHandler(extensionStack);
|
|
||||||
|
|
||||||
// Setup Response
|
// Setup Response
|
||||||
StringBuilder resp = new StringBuilder();
|
StringBuilder resp = new StringBuilder();
|
||||||
resp.append("HTTP/1.1 101 Upgrade\r\n");
|
resp.append("HTTP/1.1 101 Upgrade\r\n");
|
||||||
|
|
|
@ -25,11 +25,10 @@ import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.SuspendToken;
|
import org.eclipse.jetty.websocket.api.SuspendToken;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
|
||||||
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
||||||
import org.eclipse.jetty.websocket.common.io.IOState;
|
import org.eclipse.jetty.websocket.common.io.IOState;
|
||||||
|
|
||||||
|
@ -134,9 +133,9 @@ public class DummyConnection implements LogicalConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -149,13 +148,6 @@ public class DummyConnection implements LogicalConnection
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNextIncomingFrames(IncomingFrames incoming)
|
|
||||||
{
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("setNextIncomingFrames({})", incoming);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SuspendToken suspend()
|
public SuspendToken suspend()
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,19 +27,22 @@ import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
|
import org.eclipse.jetty.websocket.common.Parser;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
public class IncomingFramesCapture implements IncomingFrames
|
public class IncomingFramesCapture implements Parser.Handler, IncomingFrames
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(IncomingFramesCapture.class);
|
private static final Logger LOG = Log.getLogger(IncomingFramesCapture.class);
|
||||||
private EventQueue<WebSocketFrame> frames = new EventQueue<>();
|
private EventQueue<WebSocketFrame> frames = new EventQueue<>();
|
||||||
private EventQueue<Throwable> errors = new EventQueue<>();
|
private EventQueue<Throwable> errors = new EventQueue<>();
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void assertErrorCount(int expectedCount)
|
public void assertErrorCount(int expectedCount)
|
||||||
{
|
{
|
||||||
Assert.assertThat("Captured error count",errors.size(),is(expectedCount));
|
Assert.assertThat("Captured error count",errors.size(),is(expectedCount));
|
||||||
|
@ -63,6 +66,7 @@ public class IncomingFramesCapture implements IncomingFrames
|
||||||
Assert.assertThat("Captured frame count",frames.size(),is(expectedCount));
|
Assert.assertThat("Captured frame count",frames.size(),is(expectedCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void assertHasErrors(Class<? extends WebSocketException> errorType, int expectedCount)
|
public void assertHasErrors(Class<? extends WebSocketException> errorType, int expectedCount)
|
||||||
{
|
{
|
||||||
Assert.assertThat(errorType.getSimpleName(),getErrorCount(errorType),is(expectedCount));
|
Assert.assertThat(errorType.getSimpleName(),getErrorCount(errorType),is(expectedCount));
|
||||||
|
@ -84,6 +88,7 @@ public class IncomingFramesCapture implements IncomingFrames
|
||||||
Assert.assertThat("Frame count",frames.size(),is(0));
|
Assert.assertThat("Frame count",frames.size(),is(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void assertNoErrors()
|
public void assertNoErrors()
|
||||||
{
|
{
|
||||||
Assert.assertThat("Error count",errors.size(),is(0));
|
Assert.assertThat("Error count",errors.size(),is(0));
|
||||||
|
@ -105,6 +110,7 @@ public class IncomingFramesCapture implements IncomingFrames
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public int getErrorCount(Class<? extends Throwable> errorType)
|
public int getErrorCount(Class<? extends Throwable> errorType)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -118,6 +124,7 @@ public class IncomingFramesCapture implements IncomingFrames
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public Queue<Throwable> getErrors()
|
public Queue<Throwable> getErrors()
|
||||||
{
|
{
|
||||||
return errors;
|
return errors;
|
||||||
|
@ -140,23 +147,26 @@ public class IncomingFramesCapture implements IncomingFrames
|
||||||
{
|
{
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingError(Throwable e)
|
public void incomingError(Throwable t)
|
||||||
{
|
{
|
||||||
LOG.debug(e);
|
errors.add(t);
|
||||||
errors.add(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void incomingFrame(Frame frame)
|
public void incomingFrame(Frame frame, FrameCallback callback)
|
||||||
|
{
|
||||||
|
onFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFrame(Frame frame)
|
||||||
{
|
{
|
||||||
WebSocketFrame copy = WebSocketFrame.copy(frame);
|
WebSocketFrame copy = WebSocketFrame.copy(frame);
|
||||||
// TODO: might need to make this optional (depending on use by client vs server tests)
|
|
||||||
// Assert.assertThat("frame.masking must be set",frame.isMasked(),is(true));
|
|
||||||
frames.add(copy);
|
frames.add(copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size()
|
public int size()
|
||||||
{
|
{
|
||||||
return frames.size();
|
return frames.size();
|
||||||
|
|
|
@ -18,21 +18,21 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.common.test;
|
package org.eclipse.jetty.websocket.common.test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
|
|
||||||
public class OutgoingFramesCapture implements OutgoingFrames
|
public class OutgoingFramesCapture implements OutgoingFrames
|
||||||
{
|
{
|
||||||
private LinkedList<WebSocketFrame> frames = new LinkedList<>();
|
private LinkedList<WebSocketFrame> frames = new LinkedList<>();
|
||||||
|
@ -87,7 +87,7 @@ public class OutgoingFramesCapture implements OutgoingFrames
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
frames.add(WebSocketFrame.copy(frame));
|
frames.add(WebSocketFrame.copy(frame));
|
||||||
// Consume bytes
|
// Consume bytes
|
||||||
|
@ -96,7 +96,7 @@ public class OutgoingFramesCapture implements OutgoingFrames
|
||||||
// notify callback
|
// notify callback
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.util.Locale;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.TypeUtil;
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.FrameCallback;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
import org.eclipse.jetty.websocket.common.Generator;
|
import org.eclipse.jetty.websocket.common.Generator;
|
||||||
|
@ -63,7 +63,7 @@ public class OutgoingNetworkBytesCapture implements OutgoingFrames
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode)
|
public void outgoingFrame(Frame frame, FrameCallback callback, BatchMode batchMode)
|
||||||
{
|
{
|
||||||
ByteBuffer buf = ByteBuffer.allocate(Generator.MAX_HEADER_LENGTH + frame.getPayloadLength());
|
ByteBuffer buf = ByteBuffer.allocate(Generator.MAX_HEADER_LENGTH + frame.getPayloadLength());
|
||||||
generator.generateWholeFrame(frame,buf);
|
generator.generateWholeFrame(frame,buf);
|
||||||
|
@ -71,7 +71,7 @@ public class OutgoingNetworkBytesCapture implements OutgoingFrames
|
||||||
captured.add(buf);
|
captured.add(buf);
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
callback.writeSuccess();
|
callback.succeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,14 +28,9 @@ import org.eclipse.jetty.websocket.common.Parser;
|
||||||
|
|
||||||
public class UnitParser extends Parser
|
public class UnitParser extends Parser
|
||||||
{
|
{
|
||||||
public UnitParser()
|
public UnitParser(WebSocketPolicy policy, Parser.Handler handler)
|
||||||
{
|
{
|
||||||
this(WebSocketPolicy.newServerPolicy());
|
super(policy,new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged()),handler);
|
||||||
}
|
|
||||||
|
|
||||||
public UnitParser(WebSocketPolicy policy)
|
|
||||||
{
|
|
||||||
super(policy,new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parsePartial(ByteBuffer buf, int numBytes)
|
private void parsePartial(ByteBuffer buf, int numBytes)
|
||||||
|
@ -52,6 +47,7 @@ public class UnitParser extends Parser
|
||||||
* Use if you know the parse will cause an exception and just don't wnat to make the test console all noisy.
|
* Use if you know the parse will cause an exception and just don't wnat to make the test console all noisy.
|
||||||
* @param buf the buffer to parse
|
* @param buf the buffer to parse
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void parseQuietly(ByteBuffer buf)
|
public void parseQuietly(ByteBuffer buf)
|
||||||
{
|
{
|
||||||
try (StacklessLogging suppress = new StacklessLogging(Parser.class))
|
try (StacklessLogging suppress = new StacklessLogging(Parser.class))
|
||||||
|
|
|
@ -6,4 +6,4 @@ org.eclipse.jetty.LEVEL=WARN
|
||||||
# org.eclipse.jetty.websocket.io.payload.LEVEL=DEBUG
|
# org.eclipse.jetty.websocket.io.payload.LEVEL=DEBUG
|
||||||
# org.eclipse.jetty.websocket.common.extensions.LEVEL=DEBUG
|
# org.eclipse.jetty.websocket.common.extensions.LEVEL=DEBUG
|
||||||
# org.eclipse.jetty.websocket.common.message.LEVEL=DEBUG
|
# org.eclipse.jetty.websocket.common.message.LEVEL=DEBUG
|
||||||
org.eclipse.jetty.websocket.common.function.LEVEL=DEBUG
|
# org.eclipse.jetty.websocket.common.function.LEVEL=DEBUG
|
||||||
|
|
|
@ -26,14 +26,14 @@ import org.eclipse.jetty.io.Connection;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
import org.eclipse.jetty.websocket.common.extensions.ExtensionStack;
|
||||||
import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection;
|
import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection;
|
||||||
|
|
||||||
public class WebSocketServerConnection extends AbstractWebSocketConnection implements Connection.UpgradeTo
|
public class WebSocketServerConnection extends AbstractWebSocketConnection implements Connection.UpgradeTo
|
||||||
{
|
{
|
||||||
public WebSocketServerConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool)
|
public WebSocketServerConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack)
|
||||||
{
|
{
|
||||||
super(endp,executor,scheduler,policy,bufferPool);
|
super(endp,executor,scheduler,policy,bufferPool,extensionStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,10 +47,4 @@ public class WebSocketServerConnection extends AbstractWebSocketConnection imple
|
||||||
{
|
{
|
||||||
return getEndPoint().getRemoteAddress();
|
return getEndPoint().getRemoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNextIncomingFrames(IncomingFrames incoming)
|
|
||||||
{
|
|
||||||
getParser().setIncomingFramesHandler(incoming);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -560,7 +560,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||||
ByteBufferPool bufferPool = connector.getByteBufferPool();
|
ByteBufferPool bufferPool = connector.getByteBufferPool();
|
||||||
|
|
||||||
// Setup websocket connection
|
// Setup websocket connection
|
||||||
AbstractWebSocketConnection wsConnection = new WebSocketServerConnection(endp, executor, scheduler, getPolicy().clonePolicy(), bufferPool);
|
AbstractWebSocketConnection wsConnection = new WebSocketServerConnection(endp, executor, scheduler, getPolicy().clonePolicy(), bufferPool, extensionStack);
|
||||||
|
|
||||||
extensionStack.setPolicy(wsConnection.getPolicy());
|
extensionStack.setPolicy(wsConnection.getPolicy());
|
||||||
extensionStack.configure(wsConnection.getParser());
|
extensionStack.configure(wsConnection.getParser());
|
||||||
|
@ -581,7 +581,6 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||||
wsConnection.addListener(session);
|
wsConnection.addListener(session);
|
||||||
|
|
||||||
// Setup Incoming Routing
|
// Setup Incoming Routing
|
||||||
wsConnection.setNextIncomingFrames(extensionStack);
|
|
||||||
extensionStack.setNextIncoming(session);
|
extensionStack.setNextIncoming(session);
|
||||||
|
|
||||||
// Setup Outgoing Routing
|
// Setup Outgoing Routing
|
||||||
|
|
Loading…
Reference in New Issue