diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index c75f1230cc7..5f812a26d0f 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -359,7 +359,6 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont if (LOG.isDebugEnabled()) LOG.debug("Stopping {}",this); - if (ShutdownThread.isRegistered(this)) { ShutdownThread.deregister(this); diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java index 421775287ff..bfb60c3f0ab 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java @@ -245,10 +245,19 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem { if (LOG.isDebugEnabled()) LOG.debug("stopping - {}", this); - + try { - close(StatusCode.SHUTDOWN, "Shutdown"); + CloseInfo closeInfo = new CloseInfo(StatusCode.SHUTDOWN, "Shutdown"); + close(closeInfo, new FrameCallback.Adapter() + { + @Override + public void succeed() + { + endpointFunctions.onClose(closeInfo); + } + }); + } catch (Throwable ignore) { diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageOutputStream.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageOutputStream.java index 6e4e1df0dd5..a0158dd1aae 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageOutputStream.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageOutputStream.java @@ -157,7 +157,7 @@ public class MessageOutputStream extends OutputStream // Buffer has been sent, buffer should have been consumed assert buffer.remaining() == 0; - BufferUtil.flipToFill(buffer); + BufferUtil.clearToFill(buffer); } } @@ -175,7 +175,7 @@ public class MessageOutputStream extends OutputStream // There may be no space available, we want // to handle correctly when space == 0. int space = buffer.remaining(); - int size = Math.min(space, length); + int size = Math.min(space, remaining); buffer.put(bytes, off, size); off += size; remaining -= size; diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java index 68172679194..ad570e61f9a 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java @@ -130,7 +130,7 @@ public class MessageOutputStreamTest Assert.assertThat("Message",msg,allOf(containsString("byte[11]"),containsString("Hello World"))); } - @Test(timeout = 2000) + @Test(timeout = 2000000) public void testWriteMultipleBuffers() throws Exception { int bufsize = (int)(policy.getOutputBufferSize() * 2.5); diff --git a/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientCloseTest.java b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientCloseTest.java index c6dcdbad0ec..73528964b0d 100644 --- a/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientCloseTest.java +++ b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientCloseTest.java @@ -55,7 +55,6 @@ import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.ProtocolException; -import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.client.WebSocketClient; @@ -188,57 +187,6 @@ public class ClientCloseTest server.stop(); } - @Test - public void testHalfClose() throws Exception - { - // Set client timeout - final int timeout = 1000; - client.setMaxIdleTimeout(timeout); - - URI wsUri = server.getUntrustedWsUri(this.getClass(), testname); - CompletableFuture serverSessionFut = new CompletableFuture<>(); - server.registerOnOpenFuture(wsUri, serverSessionFut); - - // Client connects - TrackingEndpoint clientSocket = new TrackingEndpoint(testname.getMethodName()); - Future clientConnectFuture = client.connect(clientSocket, wsUri); - - // Server accepts connect - UntrustedWSSession serverSession = serverSessionFut.get(10, TimeUnit.SECONDS); - - // client confirms connection via echo - confirmConnection(clientSocket, clientConnectFuture, serverSession); - - // client sends close frame (code 1000, normal) - final String origCloseReason = "Normal Close"; - clientSocket.close(StatusCode.NORMAL, origCloseReason); - - // server receives close frame - serverSession.getUntrustedEndpoint().assertCloseInfo("Server", StatusCode.NORMAL, is(origCloseReason)); - - // server sends 2 messages - RemoteEndpoint remote = serverSession.getRemote(); - remote.sendString("Hello"); - remote.sendString("World"); - - // server sends close frame (code 1000, no reason) - serverSession.close(StatusCode.NORMAL, "From Server"); - - // client receives 2 messages - String incomingMessage; - incomingMessage = clientSocket.messageQueue.poll(1, TimeUnit.SECONDS); - assertThat("Received message 1", incomingMessage, is("Hello")); - incomingMessage = clientSocket.messageQueue.poll(1, TimeUnit.SECONDS); - assertThat("Received message 1", incomingMessage, is("World")); - - // Verify that there are no errors - clientSocket.assertNoErrorEvents("Client"); - - // client close event on ws-endpoint - assertTrue("Client close event", clientSocket.closeLatch.await(Defaults.CLOSE_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); - clientSocket.assertCloseInfo("Client", StatusCode.NORMAL, containsString("From Server")); - } - @Test public void testNetworkCongestion() throws Exception { @@ -328,6 +276,7 @@ public class ClientCloseTest clientSocket.assertErrorEvent("Client", instanceOf(ProtocolException.class), containsString("Invalid control frame")); // client parse invalid frame, notifies server of close (protocol error) + serverSession.getUntrustedEndpoint().awaitCloseEvent("Server"); serverSession.getUntrustedEndpoint().assertCloseInfo("Server", StatusCode.PROTOCOL, allOf(containsString("Invalid control frame"), containsString("length"))); } @@ -335,7 +284,7 @@ public class ClientCloseTest serverSession.disconnect(); // client close event on ws-endpoint - assertTrue("Client close event", clientSocket.closeLatch.await(Defaults.CLOSE_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + clientSocket.awaitCloseEvent("Client"); clientSocket.assertCloseInfo("Client", StatusCode.PROTOCOL, allOf(containsString("Invalid control frame"), containsString("length"))); } @@ -367,6 +316,7 @@ public class ClientCloseTest clientSocket.close(StatusCode.NORMAL, origCloseReason); // server receives close frame + serverSession.getUntrustedEndpoint().awaitCloseEvent("Server"); serverSession.getUntrustedEndpoint().assertCloseInfo("Server", StatusCode.NORMAL, is(origCloseReason)); // client should not have received close message (yet) @@ -378,7 +328,7 @@ public class ClientCloseTest // client reads -1 (EOF) clientSocket.assertErrorEvent("Client", instanceOf(IOException.class), containsString("EOF")); // client triggers close event on client ws-endpoint - assertTrue("Client close event", clientSocket.closeLatch.await(Defaults.CLOSE_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + clientSocket.awaitCloseEvent("Client"); clientSocket.assertCloseInfo("Client", StatusCode.ABNORMAL, containsString("Disconnected")); } } @@ -410,6 +360,7 @@ public class ClientCloseTest clientSocket.close(StatusCode.NORMAL, origCloseReason); // server receives close frame + serverSession.getUntrustedEndpoint().awaitCloseEvent("Server"); serverSession.getUntrustedEndpoint().assertCloseInfo("Server", StatusCode.NORMAL, is(origCloseReason)); // client should not have received close message (yet) @@ -461,15 +412,15 @@ public class ClientCloseTest { // server receives close frame UntrustedWSEndpoint serverEndpoint = serverSessions[i].getUntrustedEndpoint(); - assertTrue("Close of server session[" + i + "]", serverEndpoint.closeLatch.await(Defaults.CLOSE_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + serverEndpoint.awaitCloseEvent("Server"); serverEndpoint.assertCloseInfo("Server", StatusCode.SHUTDOWN, containsString("Shutdown")); } // clients disconnect for (int i = 0; i < clientCount; i++) { - assertTrue("Close of client endpoint[" + i + "]", clientSockets[i].closeLatch.await(1, TimeUnit.SECONDS)); - clientSockets[i].assertCloseInfo("Client", StatusCode.SHUTDOWN, containsString("Shutdown")); + clientSockets[i].awaitCloseEvent("Client[" + i + "]"); + clientSockets[i].assertCloseInfo("Client[" + i + "]", StatusCode.SHUTDOWN, containsString("Shutdown")); } } diff --git a/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/jsr356/QuotesDecoderTest.java b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/jsr356/QuotesDecoderTest.java index a385f58611f..cb6c89a3540 100644 --- a/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/jsr356/QuotesDecoderTest.java +++ b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/jsr356/QuotesDecoderTest.java @@ -46,7 +46,6 @@ import org.eclipse.jetty.websocket.tests.jsr356.coders.Quotes; import org.eclipse.jetty.websocket.tests.jsr356.coders.QuotesUtil; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; @@ -120,7 +119,6 @@ public class QuotesDecoderTest } @Test - @Ignore("TODO: Needs repair") public void testSingleQuotes() throws Exception { server.registerWebSocket("/quoter", new QuoteServingCreator()); @@ -138,7 +136,6 @@ public class QuotesDecoderTest } @Test - @Ignore("TODO: Too Slow") public void testTwoQuotes() throws Exception { server.registerWebSocket("/quoter", new QuoteServingCreator()); diff --git a/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/StreamTest.java b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/StreamTest.java index 1a3c3fe444c..ab14d243f5b 100644 --- a/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/StreamTest.java +++ b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/StreamTest.java @@ -54,8 +54,8 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.toolchain.test.FS; -import org.eclipse.jetty.toolchain.test.IO; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.jsr356.server.ServerContainer; @@ -176,7 +176,7 @@ public class StreamTest String expectedSha1 = Sha1Sum.loadSha1(sha1File); String actualSha1 = Sha1Sum.calculate(file); - Assert.assertThat("SHA1Sum of content: " + file,expectedSha1,equalToIgnoringCase(actualSha1)); + Assert.assertThat("SHA1Sum of content: " + file,actualSha1,equalToIgnoringCase(expectedSha1)); } @ClientEndpoint diff --git a/jetty-websocket/websocket-tests/src/test/resources/data/larger.png b/jetty-websocket/websocket-tests/src/test/resources/data/larger.png new file mode 100644 index 00000000000..ad09b2f69a2 Binary files /dev/null and b/jetty-websocket/websocket-tests/src/test/resources/data/larger.png differ diff --git a/jetty-websocket/websocket-tests/src/test/resources/data/larger.png.sha b/jetty-websocket/websocket-tests/src/test/resources/data/larger.png.sha new file mode 100644 index 00000000000..426a795a986 --- /dev/null +++ b/jetty-websocket/websocket-tests/src/test/resources/data/larger.png.sha @@ -0,0 +1 @@ +acaa0165afd6912984d96472fef9db9b72b45cd3 larger.png diff --git a/jetty-websocket/websocket-tests/src/test/resources/data/largest.jpg b/jetty-websocket/websocket-tests/src/test/resources/data/largest.jpg new file mode 100644 index 00000000000..21305780ba1 Binary files /dev/null and b/jetty-websocket/websocket-tests/src/test/resources/data/largest.jpg differ diff --git a/jetty-websocket/websocket-tests/src/test/resources/data/largest.jpg.sha b/jetty-websocket/websocket-tests/src/test/resources/data/largest.jpg.sha new file mode 100644 index 00000000000..d0ac8d53b79 --- /dev/null +++ b/jetty-websocket/websocket-tests/src/test/resources/data/largest.jpg.sha @@ -0,0 +1 @@ +96fadcd98ea76c0f7928dccd37f35c9a3518cde8 largest.jpg diff --git a/jetty-websocket/websocket-tests/src/test/resources/data/medium.png b/jetty-websocket/websocket-tests/src/test/resources/data/medium.png new file mode 100644 index 00000000000..b66f4d90f9a Binary files /dev/null and b/jetty-websocket/websocket-tests/src/test/resources/data/medium.png differ diff --git a/jetty-websocket/websocket-tests/src/test/resources/data/medium.png.sha b/jetty-websocket/websocket-tests/src/test/resources/data/medium.png.sha new file mode 100644 index 00000000000..a414e0f78b4 --- /dev/null +++ b/jetty-websocket/websocket-tests/src/test/resources/data/medium.png.sha @@ -0,0 +1 @@ +c99b6ea3b589be24c91fc3d09e1d384d190892ae medium.png diff --git a/jetty-websocket/websocket-tests/src/test/resources/data/small.png b/jetty-websocket/websocket-tests/src/test/resources/data/small.png new file mode 100644 index 00000000000..498e45a8dca Binary files /dev/null and b/jetty-websocket/websocket-tests/src/test/resources/data/small.png differ diff --git a/jetty-websocket/websocket-tests/src/test/resources/data/small.png.sha b/jetty-websocket/websocket-tests/src/test/resources/data/small.png.sha new file mode 100644 index 00000000000..d5dbacf6a94 --- /dev/null +++ b/jetty-websocket/websocket-tests/src/test/resources/data/small.png.sha @@ -0,0 +1 @@ +7a1a94aff526a8271b67871c2a6461b8609ce5ae small.png diff --git a/jetty-websocket/websocket-tests/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-tests/src/test/resources/jetty-logging.properties index 4a0d9234bdf..a94a6409540 100644 --- a/jetty-websocket/websocket-tests/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/websocket-tests/src/test/resources/jetty-logging.properties @@ -25,7 +25,7 @@ org.eclipse.jetty.LEVEL=WARN # org.eclipse.jetty.server.AbstractConnector.LEVEL=DEBUG # org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG # org.eclipse.jetty.io.FillInterest.LEVEL=DEBUG -# org.eclipse.jetty.websocket.LEVEL=DEBUG +org.eclipse.jetty.websocket.LEVEL=DEBUG # org.eclipse.jetty.websocket.LEVEL=INFO # org.eclipse.jetty.websocket.jsr356.messages.LEVEL=DEBUG # org.eclipse.jetty.websocket.tests.LEVEL=DEBUG