diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageBinaryCallable.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageBinaryCallable.java index a6d7f3a486b..1271fb13ee0 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageBinaryCallable.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageBinaryCallable.java @@ -20,10 +20,8 @@ package org.eclipse.jetty.websocket.jsr356.annotations; import java.lang.reflect.Method; import java.nio.ByteBuffer; - import javax.websocket.DecodeException; import javax.websocket.Decoder; -import javax.websocket.OnMessage; import org.eclipse.jetty.websocket.jsr356.JsrSession; import org.eclipse.jetty.websocket.jsr356.annotations.Param.Role; @@ -55,12 +53,20 @@ public class OnMessageBinaryCallable extends OnMessageCallable public Object call(Object endpoint, ByteBuffer buf, boolean partialFlag) throws DecodeException { - super.args[idxMessageObject] = binaryDecoder.decode(buf); - if (idxPartialMessageFlag >= 0) + if (binaryDecoder.willDecode(buf.slice())) { - super.args[idxPartialMessageFlag] = partialFlag; + super.args[idxMessageObject] = binaryDecoder.decode(buf); + if (idxPartialMessageFlag >= 0) + { + super.args[idxPartialMessageFlag] = partialFlag; + } + return super.call(endpoint, super.args); + } + else + { + // Per JSR356, if you cannot decode, discard the message. + return null; } - return super.call(endpoint,super.args); } @Override diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageTextCallable.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageTextCallable.java index 82a8ced5eb2..9e245aca857 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageTextCallable.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/annotations/OnMessageTextCallable.java @@ -18,12 +18,9 @@ package org.eclipse.jetty.websocket.jsr356.annotations; -import java.io.Reader; import java.lang.reflect.Method; - import javax.websocket.DecodeException; import javax.websocket.Decoder; -import javax.websocket.OnMessage; import org.eclipse.jetty.websocket.jsr356.JsrSession; import org.eclipse.jetty.websocket.jsr356.annotations.Param.Role; @@ -55,12 +52,20 @@ public class OnMessageTextCallable extends OnMessageCallable public Object call(Object endpoint, String str, boolean partialFlag) throws DecodeException { - super.args[idxMessageObject] = textDecoder.decode(str); - if (idxPartialMessageFlag >= 0) + if (textDecoder.willDecode(str)) { - super.args[idxPartialMessageFlag] = partialFlag; + super.args[idxMessageObject] = textDecoder.decode(str); + if (idxPartialMessageFlag >= 0) + { + super.args[idxPartialMessageFlag] = partialFlag; + } + return super.call(endpoint, super.args); + } + else + { + // Per JSR356, if you cannot decode, discard the message. + return null; } - return super.call(endpoint,super.args); } @Override diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/messages/BinaryWholeMessage.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/messages/BinaryWholeMessage.java index e64d9b1a2a8..d4086fae34a 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/messages/BinaryWholeMessage.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/messages/BinaryWholeMessage.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.websocket.jsr356.messages; +import java.nio.ByteBuffer; import javax.websocket.DecodeException; import javax.websocket.Decoder; import javax.websocket.Decoder.Binary; @@ -54,14 +55,19 @@ public class BinaryWholeMessage extends SimpleBinaryMessage DecoderFactory.Wrapper decoder = msgWrapper.getDecoder(); Decoder.Binary binaryDecoder = (Binary)decoder.getDecoder(); - try + ByteBuffer msg = BufferUtil.toBuffer(data); + + if (binaryDecoder.willDecode(msg.slice())) { - Object obj = binaryDecoder.decode(BufferUtil.toBuffer(data)); - wholeHandler.onMessage(obj); - } - catch (DecodeException e) - { - throw new WebSocketException("Unable to decode binary data",e); + try + { + Object obj = binaryDecoder.decode(msg); + wholeHandler.onMessage(obj); + } + catch (DecodeException e) + { + throw new WebSocketException("Unable to decode binary data", e); + } } } } diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/messages/TextWholeMessage.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/messages/TextWholeMessage.java index 8f11d96c2a2..e3c1ca67be4 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/messages/TextWholeMessage.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/messages/TextWholeMessage.java @@ -50,14 +50,18 @@ public class TextWholeMessage extends SimpleTextMessage DecoderFactory.Wrapper decoder = msgWrapper.getDecoder(); Decoder.Text textDecoder = (Decoder.Text)decoder.getDecoder(); - try + String msg = utf.toString(); + if (textDecoder.willDecode(msg)) { - Object obj = textDecoder.decode(utf.toString()); - wholeHandler.onMessage(obj); - } - catch (DecodeException e) - { - throw new WebSocketException("Unable to decode text data",e); + try + { + Object obj = textDecoder.decode(msg); + wholeHandler.onMessage(obj); + } + catch (DecodeException e) + { + throw new WebSocketException("Unable to decode text data", e); + } } } } diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java index 21afb1e585b..1b0d2fb8ccd 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java @@ -18,9 +18,6 @@ package org.eclipse.jetty.websocket.jsr356.server; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; - import java.io.File; import java.net.URI; import java.util.ArrayList; @@ -28,7 +25,6 @@ import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; - import javax.websocket.ContainerProvider; import javax.websocket.WebSocketContainer; @@ -62,12 +58,17 @@ import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.InputStreamSo import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.ReaderParamSocket; import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.ReaderSocket; import org.eclipse.jetty.websocket.jsr356.server.samples.streaming.StringReturnReaderParamSocket; +import org.hamcrest.Matcher; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.nullValue; + public class EchoTest { private static final List TESTCASES = new ArrayList<>(); @@ -84,7 +85,7 @@ public class EchoTest EchoCase.add(TESTCASES,BooleanTextSocket.class).addMessage(Boolean.FALSE).expect("false"); EchoCase.add(TESTCASES,BooleanTextSocket.class).addMessage("true").expect("true"); EchoCase.add(TESTCASES,BooleanTextSocket.class).addMessage("TRUe").expect("true"); - EchoCase.add(TESTCASES,BooleanTextSocket.class).addMessage("Apple").expect("false"); + EchoCase.add(TESTCASES,BooleanTextSocket.class).addMessage("Apple").expect(null); // fails willDecode EchoCase.add(TESTCASES,BooleanTextSocket.class).addMessage("false").expect("false"); EchoCase.add(TESTCASES,BooleanObjectTextSocket.class).addMessage(true).expect("true"); @@ -278,7 +279,8 @@ public class EchoTest for (String expected : testcase.expectedStrings) { String actual = received.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - assertThat("Received Echo Responses",actual,containsString(expected)); + Matcher expectation = expected == null ? nullValue() : containsString(expected); + assertThat("Received Echo Responses", actual, expectation); } } finally