diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/extensions/fragment/FragmentExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/extensions/fragment/FragmentExtension.java index a93d620fe76..187585cee4d 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/extensions/fragment/FragmentExtension.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/extensions/fragment/FragmentExtension.java @@ -52,12 +52,15 @@ public class FragmentExtension extends Extension return; } + boolean continuation = false; + // break apart payload based on maxLength rules while (length > maxLength) { WebSocketFrame frag = new WebSocketFrame(frame); frag.setOpCode(opcode); frag.setFin(false); // always false here + frag.setContinuation(continuation); payload.position(currentPosition); payload.limit(Math.min(payload.position() + maxLength,originalLimit)); frag.setPayload(payload); @@ -66,6 +69,7 @@ public class FragmentExtension extends Extension length -= maxLength; opcode = OpCode.CONTINUATION; + continuation = true; currentPosition = payload.limit(); } @@ -73,6 +77,7 @@ public class FragmentExtension extends Extension WebSocketFrame frag = new WebSocketFrame(frame); frag.setOpCode(opcode); frag.setFin(frame.isFin()); // use original fin + frag.setContinuation(continuation); payload.position(currentPosition); payload.limit(originalLimit); frag.setPayload(payload); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketAsyncConnection.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketAsyncConnection.java index c5f15c88562..37df04a8697 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketAsyncConnection.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketAsyncConnection.java @@ -348,7 +348,6 @@ public class WebSocketAsyncConnection extends AbstractAsyncConnection implements if (LOG.isDebugEnabled()) { LOG.debug("Writing {} frame bytes of {}",buffer.remaining(),frameBytes); - LOG.debug("EndPoint: {}",endpoint); } try { diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketSession.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketSession.java index c5418a546f8..5cc3fa73af6 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketSession.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketSession.java @@ -98,7 +98,7 @@ public class WebSocketSession implements WebSocketConnection, IncomingFrames, Ou { if (LOG.isDebugEnabled()) { - LOG.debug("output({},{},{})",context,callback,frame); + LOG.debug("output({},{},{}) - {}",context,callback,frame,outgoing); } // forward on to chain outgoing.output(context,callback,frame); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/Generator.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/Generator.java index 91c236552c9..c7a09493a02 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/Generator.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/Generator.java @@ -56,8 +56,7 @@ public class Generator */ public static final int OVERHEAD = 28; - @SuppressWarnings("unused") - private final WebSocketPolicy policy; // TODO: remove as unused? + private final WebSocketPolicy policy; private final ByteBufferPool bufferPool; private boolean validating; @@ -378,7 +377,26 @@ public class Generator @Override public String toString() { - return String.format("Generator [basic=%s]",this.getClass().getSimpleName()); + StringBuilder builder = new StringBuilder(); + builder.append("Generator["); + builder.append(policy.getBehavior()); + if (validating) + { + builder.append(",validating"); + } + if (rsv1InUse) + { + builder.append(",+rsv1"); + } + if (rsv2InUse) + { + builder.append(",+rsv2"); + } + if (rsv3InUse) + { + builder.append(",+rsv3"); + } + builder.append("]"); + return builder.toString(); } - } diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java index 0ea33f5dc8e..c1970671182 100644 --- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java +++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java @@ -363,6 +363,20 @@ public class WebSocketServerFactory extends AbstractLifeCycle implements WebSock Extension ext = extIter.next(); ext.setNextOutgoingFrames(outgoing); outgoing = ext; + + // Handle RSV reservations + if (ext.useRsv1()) + { + connection.getGenerator().setRsv1InUse(true); + } + if (ext.useRsv2()) + { + connection.getGenerator().setRsv2InUse(true); + } + if (ext.useRsv3()) + { + connection.getGenerator().setRsv3InUse(true); + } } // Connect incomings diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DeflateExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DeflateExtensionTest.java index 48a17c72296..27f1d2a944e 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DeflateExtensionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DeflateExtensionTest.java @@ -21,8 +21,8 @@ import java.util.Queue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.websocket.protocol.WebSocketFrame; -import org.eclipse.jetty.websocket.server.WebSocketServletRFCTest.RFCServlet; import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient; +import org.eclipse.jetty.websocket.server.helper.EchoServlet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -35,7 +35,7 @@ public class DeflateExtensionTest @BeforeClass public static void startServer() throws Exception { - server = new SimpleServletServer(new RFCServlet()); + server = new SimpleServletServer(new EchoServlet()); server.start(); } @@ -50,8 +50,7 @@ public class DeflateExtensionTest { BlockheadClient client = new BlockheadClient(server.getServerUri()); client.clearExtensions(); - client.addExtensions("x-deflate-frame;minLength=64"); - // client.addExtensions("fragment;minFragments=2"); + client.addExtensions("x-deflate-frame;minLength=8"); client.setProtocols("echo"); try @@ -65,18 +64,18 @@ public class DeflateExtensionTest Assert.assertThat("Response",resp,containsString("x-deflate")); // Server sends a big message - String text = "0123456789ABCDEF "; - text = text + text + text + text; - text = text + text + text + text; - text = text + text + text + text + 'X'; + StringBuilder msg = new StringBuilder(); + for (int i = 0; i < 400; i++) + { + msg.append("0123456789ABCDEF "); + } + msg.append('X'); // so we can see the end in our debugging - client.write(WebSocketFrame.text(text)); - - // TODO: use socket that captures frame payloads to verify fragmentation + client.write(WebSocketFrame.text(msg.toString())); Queue frames = client.readFrames(1,TimeUnit.MILLISECONDS,1000); WebSocketFrame frame = frames.remove(); - Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is(text)); + Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is(msg.toString())); } finally { diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java index e2c3469d647..e0bf8efa94c 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java @@ -21,8 +21,8 @@ import java.util.Queue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.websocket.protocol.WebSocketFrame; -import org.eclipse.jetty.websocket.server.WebSocketServletRFCTest.RFCServlet; import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient; +import org.eclipse.jetty.websocket.server.helper.EchoServlet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -35,7 +35,7 @@ public class FragmentExtensionTest @BeforeClass public static void startServer() throws Exception { - server = new SimpleServletServer(new RFCServlet()); + server = new SimpleServletServer(new EchoServlet()); server.start(); } @@ -45,13 +45,28 @@ public class FragmentExtensionTest server.stop(); } + private String[] split(String str, int partSize) + { + int strLength = str.length(); + int count = (int)Math.ceil((double)str.length() / partSize); + String ret[] = new String[count]; + int idx; + for (int i = 0; i < count; i++) + { + idx = (i * partSize); + ret[i] = str.substring(idx,Math.min(idx + partSize,strLength)); + } + return ret; + } + @Test public void testFragmentExtension() throws Exception { + int fragSize = 4; BlockheadClient client = new BlockheadClient(server.getServerUri()); client.clearExtensions(); - client.addExtensions("fragment;maxLength=4;minFragments=7"); + client.addExtensions("fragment;maxLength=" + fragSize); client.setProtocols("onConnect"); try @@ -67,11 +82,13 @@ public class FragmentExtensionTest String msg = "Sent as a long message that should be split"; client.write(WebSocketFrame.text(msg)); - // TODO: use socket that captures frame counts to verify fragmentation - - Queue frames = client.readFrames(1,TimeUnit.MILLISECONDS,1000); - WebSocketFrame frame = frames.remove(); - Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is(msg)); + String parts[] = split(msg,fragSize); + Queue frames = client.readFrames(parts.length,TimeUnit.MILLISECONDS,1000); + for (int i = 0; i < parts.length; i++) + { + WebSocketFrame frame = frames.remove(); + Assert.assertThat("text[" + i + "].payload",frame.getPayloadAsUTF8(),is(parts[i])); + } } finally { diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java index fa54d36f490..0359f1c4c30 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java @@ -21,8 +21,8 @@ import java.util.Queue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.websocket.protocol.WebSocketFrame; -import org.eclipse.jetty.websocket.server.WebSocketServletRFCTest.RFCServlet; import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient; +import org.eclipse.jetty.websocket.server.helper.EchoServlet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -35,7 +35,7 @@ public class IdentityExtensionTest @BeforeClass public static void startServer() throws Exception { - server = new SimpleServletServer(new RFCServlet()); + server = new SimpleServletServer(new EchoServlet()); server.start(); } @@ -53,7 +53,6 @@ public class IdentityExtensionTest client.addExtensions("identity;param=0"); client.addExtensions("identity;param=1, identity ; param = '2' ; other = ' some = value '"); client.setProtocols("onConnect"); - client.setDebug(true); try { diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java index 2ca95e49a91..de29b05b73d 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java @@ -84,6 +84,7 @@ public class TestABCase5 String fragment1 = "fragment1"; + // Intentionally bad PING (spec says control frames must be FIN==true) buf.put((byte)(NOFIN | OpCode.PING.getCode())); byte b = 0x00; // no masking diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_9.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_9.java index 8a2ae196a73..50604389099 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_9.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_9.java @@ -17,7 +17,6 @@ package org.eclipse.jetty.websocket.server.ab; import static org.hamcrest.Matchers.*; -import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collection; @@ -26,18 +25,12 @@ import java.util.Queue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.protocol.CloseInfo; import org.eclipse.jetty.websocket.protocol.Generator; import org.eclipse.jetty.websocket.protocol.OpCode; import org.eclipse.jetty.websocket.protocol.WebSocketFrame; import org.eclipse.jetty.websocket.server.SimpleServletServer; -import org.eclipse.jetty.websocket.server.WebSocketServerFactory; -import org.eclipse.jetty.websocket.server.WebSocketServlet; import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; @@ -51,44 +44,6 @@ import org.junit.runners.Parameterized.Parameters; @RunWith(value = Parameterized.class) public class TestABCase7_9 { - @SuppressWarnings("serial") - public static class RFCServlet extends WebSocketServlet - { - @Override - public void registerWebSockets(WebSocketServerFactory factory) - { - factory.register(RFCSocket.class); - } - } - - public static class RFCSocket extends WebSocketAdapter - { - private static Logger LOG = Log.getLogger(RFCSocket.class); - - @Override - public void onWebSocketText(String message) - { - LOG.debug("onWebSocketText({})",message); - // Test the RFC 6455 close code 1011 that should close - // trigger a WebSocket server terminated close. - if (message.equals("CRASH")) - { - System.out.printf("Got OnTextMessage"); - throw new RuntimeException("Something bad happened"); - } - - // echo the message back. - try - { - getConnection().write(null,new FutureCallback(),message); - } - catch (IOException e) - { - e.printStackTrace(System.err); - } - } - } - private static SimpleServletServer server; @Parameters diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/blockhead/BlockheadClient.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/blockhead/BlockheadClient.java index 5224b340c1f..fcc8f0026e2 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/blockhead/BlockheadClient.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/blockhead/BlockheadClient.java @@ -31,32 +31,40 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Queue; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.net.ssl.HttpsURLConnection; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.StandardByteBufferPool; import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Utf8StringBuilder; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.Extension; import org.eclipse.jetty.websocket.api.WebSocketException; import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.extensions.WebSocketExtensionRegistry; import org.eclipse.jetty.websocket.io.IncomingFrames; +import org.eclipse.jetty.websocket.io.OutgoingFrames; import org.eclipse.jetty.websocket.protocol.CloseInfo; +import org.eclipse.jetty.websocket.protocol.ExtensionConfig; import org.eclipse.jetty.websocket.protocol.Generator; import org.eclipse.jetty.websocket.protocol.OpCode; import org.eclipse.jetty.websocket.protocol.Parser; import org.eclipse.jetty.websocket.protocol.WebSocketFrame; -import org.eclipse.jetty.websocket.server.UnitGenerator; import org.junit.Assert; /** @@ -71,7 +79,7 @@ import org.junit.Assert; * with regards to basic IO behavior, a write should work as expected, a read should work as expected, but what byte it sends or reads is not within its * scope. */ -public class BlockheadClient implements IncomingFrames +public class BlockheadClient implements IncomingFrames, OutgoingFrames { private static final Logger LOG = Log.getLogger(BlockheadClient.class); /** Set to true to disable timeouts (for debugging reasons) */ @@ -83,6 +91,7 @@ public class BlockheadClient implements IncomingFrames private final Generator generator; private final Parser parser; private final LinkedBlockingDeque incomingFrameQueue; + private final WebSocketExtensionRegistry extensionRegistry; private Socket socket; private OutputStream out; @@ -94,6 +103,8 @@ public class BlockheadClient implements IncomingFrames { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF }; private int timeout = 1000; private AtomicInteger parseCount; + private IncomingFrames incoming = this; + private OutgoingFrames outgoing = this; public BlockheadClient(URI destWebsocketURI) throws URISyntaxException { @@ -108,12 +119,13 @@ public class BlockheadClient implements IncomingFrames policy = WebSocketPolicy.newClientPolicy(); bufferPool = new StandardByteBufferPool(policy.getBufferSize()); - generator = new UnitGenerator(); + generator = new Generator(policy,bufferPool); parser = new Parser(policy); - parser.setIncomingFramesHandler(this); parseCount = new AtomicInteger(0); incomingFrameQueue = new LinkedBlockingDeque<>(); + + extensionRegistry = new WebSocketExtensionRegistry(policy,bufferPool); } public void addExtensions(String xtension) @@ -176,9 +188,64 @@ public class BlockheadClient implements IncomingFrames public String expectUpgradeResponse() throws IOException { String respHeader = readResponseHeader(); + + if (LOG.isDebugEnabled()) + { + LOG.debug("Response Header: {}{}",'\n',respHeader); + } + Assert.assertThat("Response Code",respHeader,startsWith("HTTP/1.1 101 Switching Protocols")); Assert.assertThat("Response Header Upgrade",respHeader,containsString("Upgrade: WebSocket\r\n")); Assert.assertThat("Response Header Connection",respHeader,containsString("Connection: Upgrade\r\n")); + + // collect extensions configured in response header + List extensions = getExtensions(respHeader); + + // Start with default routing + incoming = this; + outgoing = this; + + // Connect extensions + if (extensions != null) + { + Iterator extIter; + // Connect outgoings + extIter = extensions.iterator(); + while (extIter.hasNext()) + { + Extension ext = extIter.next(); + ext.setNextOutgoingFrames(outgoing); + outgoing = ext; + + // Handle RSV reservations + if (ext.useRsv1()) + { + generator.setRsv1InUse(true); + } + if (ext.useRsv2()) + { + generator.setRsv2InUse(true); + } + if (ext.useRsv3()) + { + generator.setRsv3InUse(true); + } + } + + // Connect incomings + Collections.reverse(extensions); + extIter = extensions.iterator(); + while (extIter.hasNext()) + { + Extension ext = extIter.next(); + ext.setNextIncomingFrames(incoming); + incoming = ext; + } + } + + // configure parser + parser.setIncomingFramesHandler(incoming); + return respHeader; } @@ -187,6 +254,27 @@ public class BlockheadClient implements IncomingFrames return extensions; } + private List getExtensions(String respHeader) + { + List extensions = new ArrayList<>(); + + Pattern expat = Pattern.compile("Sec-WebSocket-Extensions: (.*)\r",Pattern.CASE_INSENSITIVE); + Matcher mat = expat.matcher(respHeader); + int offset = 0; + while (mat.find(offset)) + { + String econf = mat.group(1); + LOG.debug("Found Extension Response: {}",econf); + + ExtensionConfig config = ExtensionConfig.parse(econf); + Extension ext = extensionRegistry.newInstance(config); + extensions.add(ext); + + offset = mat.end(1); + } + return extensions; + } + public URI getHttpURI() { return destHttpURI; @@ -258,6 +346,24 @@ public class BlockheadClient implements IncomingFrames } } + @Override + public void output(C context, Callback callback, WebSocketFrame frame) throws IOException + { + ByteBuffer buf = generator.generate(frame); + if (LOG.isDebugEnabled()) + { + LOG.debug("writing out: {}",BufferUtil.toDetailString(buf)); + } + BufferUtil.writeTo(buf,out); + out.flush(); + + if (frame.getOpCode() == OpCode.CLOSE) + { + // FIXME terminate the connection? + disconnect(); + } + } + public int read(ByteBuffer buf) throws IOException { int len = 0; @@ -422,33 +528,21 @@ public class BlockheadClient implements IncomingFrames public void write(WebSocketFrame frame) throws IOException { - LOG.debug("write(Frame->{})",frame); + LOG.debug("write(Frame->{}) to {}",frame,outgoing); frame.setMask(clientmask); // frame.setMask(new byte[] { 0x00, 0x00, 0x00, 0x00 }); - ByteBuffer buf = generator.generate(frame); - if (LOG.isDebugEnabled()) - { - LOG.debug("writing out: {}",BufferUtil.toDetailString(buf)); - } - BufferUtil.writeTo(buf,out); - out.flush(); - - if (frame.getOpCode() == OpCode.CLOSE) - { - // FIXME terminate the connection? - disconnect(); - } + outgoing.output(null,null,frame); } public void writeRaw(ByteBuffer buf) throws IOException { - LOG.debug("write(ByteBuffer->{})",BufferUtil.toDetailString(buf)); + LOG.debug("write(ByteBuffer) {}",BufferUtil.toDetailString(buf)); BufferUtil.writeTo(buf,out); } public void writeRaw(String str) throws IOException { - LOG.debug("write(String->{})",str); + LOG.debug("write((String)[{}]){}{})",str.length(),'\n',str); out.write(StringUtil.getBytes(str,StringUtil.__ISO_8859_1)); } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/BasicEchoSocket.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/BasicEchoSocket.java index 3af3efae6da..ddb56ed7104 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/BasicEchoSocket.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/BasicEchoSocket.java @@ -19,6 +19,9 @@ import java.io.IOException; import org.eclipse.jetty.websocket.api.WebSocketAdapter; +/** + * Example of a blocking echo websocket. + */ public class BasicEchoSocket extends WebSocketAdapter { @Override diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java index 6252c8a86fa..a47d169e2ce 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java @@ -19,6 +19,9 @@ import java.io.IOException; import org.eclipse.jetty.websocket.api.WebSocketAdapter; +/** + * Example of a basic blocking echo socket. + */ public class MyEchoSocket extends WebSocketAdapter { @Override diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/helper/EchoServlet.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/helper/EchoServlet.java new file mode 100644 index 00000000000..f2bc0a0d9b7 --- /dev/null +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/helper/EchoServlet.java @@ -0,0 +1,17 @@ +package org.eclipse.jetty.websocket.server.helper; + +import org.eclipse.jetty.websocket.server.WebSocketServerFactory; +import org.eclipse.jetty.websocket.server.WebSocketServlet; + +/** + * Initialize a simple Echo websocket + */ +@SuppressWarnings("serial") +public class EchoServlet extends WebSocketServlet +{ + @Override + public void registerWebSockets(WebSocketServerFactory factory) + { + factory.register(EchoSocket.class); + } +} diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/helper/EchoSocket.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/helper/EchoSocket.java new file mode 100644 index 00000000000..e9632bad07c --- /dev/null +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/helper/EchoSocket.java @@ -0,0 +1,60 @@ +package org.eclipse.jetty.websocket.server.helper; + +import java.io.IOException; + +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.annotations.OnWebSocketConnect; +import org.eclipse.jetty.websocket.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.WebSocketConnection; + +/** + * Simple Echo WebSocket, using async writes of echo + */ +@WebSocket +public class EchoSocket +{ + private static Logger LOG = Log.getLogger(EchoSocket.class); + + private WebSocketConnection conn; + + @OnWebSocketMessage + public void onBinary(byte buf[], int offset, int len) + { + LOG.debug("onBinary(byte[{}],{},{})",buf.length,offset,len); + + // echo the message back. + try + { + this.conn.write(null,new FutureCallback(),buf,offset,len); + } + catch (IOException e) + { + e.printStackTrace(System.err); + } + } + + @OnWebSocketConnect + public void onOpen(WebSocketConnection conn) + { + this.conn = conn; + } + + @OnWebSocketMessage + public void onText(String message) + { + LOG.debug("onText({})",message); + + // echo the message back. + try + { + this.conn.write(null,new FutureCallback(),message); + } + catch (IOException e) + { + e.printStackTrace(System.err); + } + } +} diff --git a/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties index e27fece16be..607bf07594d 100644 --- a/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties @@ -1,6 +1,9 @@ org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog org.eclipse.jetty.io.LEVEL=WARN +org.eclipse.jetty.server.LEVEL=WARN # org.eclipse.jetty.io.SelectorManager.LEVEL=INFO -org.eclipse.jetty.websocket.LEVEL=INFO -# org.eclipse.jetty.websocket.generator.LEVEL=DEBUG -# org.eclipse.jetty.websocket.server.blockhead.LEVEL=DEBUG \ No newline at end of file +org.eclipse.jetty.websocket.LEVEL=WARN +# org.eclipse.jetty.websocket.extensions.LEVEL=DEBUG +# org.eclipse.jetty.websocket.protocol.Generator.LEVEL=INFO +# org.eclipse.jetty.websocket.protocol.Parser.LEVEL=INFO +# org.eclipse.jetty.websocket.server.blockhead.LEVEL=INFO \ No newline at end of file