This closes #900
This commit is contained in:
commit
895ffb5b3c
|
@ -25,6 +25,7 @@ public class ActiveMQStompException extends Exception {
|
||||||
public static final int NONE = 0;
|
public static final int NONE = 0;
|
||||||
public static final int INVALID_EOL_V10 = 1;
|
public static final int INVALID_EOL_V10 = 1;
|
||||||
public static final int INVALID_COMMAND = 2;
|
public static final int INVALID_COMMAND = 2;
|
||||||
|
public static final int UNDEFINED_ESCAPE = 3;
|
||||||
|
|
||||||
private static final long serialVersionUID = -274452327574950068L;
|
private static final long serialVersionUID = -274452327574950068L;
|
||||||
|
|
||||||
|
|
|
@ -150,4 +150,7 @@ public interface ActiveMQStompProtocolMessageBundle {
|
||||||
|
|
||||||
@Message(id = 339039, value = "No id header in ACK/NACK frame.")
|
@Message(id = 339039, value = "No id header in ACK/NACK frame.")
|
||||||
ActiveMQStompException noIDInAck();
|
ActiveMQStompException noIDInAck();
|
||||||
|
|
||||||
|
@Message(id = 339040, value = "Undefined escape sequence: {0}", format = Message.Format.MESSAGE_FORMAT)
|
||||||
|
ActiveMQStompException undefinedEscapeSequence(String sequence);
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,7 @@ public final class StompConnection implements RemotingConnection {
|
||||||
frame = decode(buffer);
|
frame = decode(buffer);
|
||||||
break;
|
break;
|
||||||
case ActiveMQStompException.INVALID_COMMAND:
|
case ActiveMQStompException.INVALID_COMMAND:
|
||||||
|
case ActiveMQStompException.UNDEFINED_ESCAPE:
|
||||||
frameHandler.onError(e);
|
frameHandler.onError(e);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -558,6 +558,12 @@ public class StompFrameHandlerV11 extends VersionedStompFrameHandler implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void throwUndefinedEscape(byte b) throws ActiveMQStompException {
|
||||||
|
ActiveMQStompException error = BUNDLE.undefinedEscapeSequence(new String(new char[]{ESC_CHAR, (char) b})).setHandler(handler);
|
||||||
|
error.setCode(ActiveMQStompException.UNDEFINED_ESCAPE);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean parseHeaders() throws ActiveMQStompException {
|
protected boolean parseHeaders() throws ActiveMQStompException {
|
||||||
|
|
||||||
|
@ -645,6 +651,9 @@ public class StompFrameHandlerV11 extends VersionedStompFrameHandler implements
|
||||||
|
|
||||||
headerValueWhitespace = false;
|
headerValueWhitespace = false;
|
||||||
|
|
||||||
|
if (isEscaping) {
|
||||||
|
throwUndefinedEscape(b);
|
||||||
|
}
|
||||||
holder.append(b);
|
holder.append(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,6 +230,9 @@ public class StompFrameHandlerV12 extends StompFrameHandlerV11 {
|
||||||
|
|
||||||
headerValueWhitespace = false;
|
headerValueWhitespace = false;
|
||||||
|
|
||||||
|
if (isEscaping) {
|
||||||
|
throwUndefinedEscape(b);
|
||||||
|
}
|
||||||
holder.append(b);
|
holder.append(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -389,6 +389,39 @@ public class StompV11Test extends StompV11TestBase {
|
||||||
newConn.disconnect();
|
newConn.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In 1.1, undefined escapes must cause a fatal protocol error.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testHeaderUndefinedEscape() throws Exception {
|
||||||
|
connV11.connect(defUser, defPass);
|
||||||
|
ClientStompFrame frame = connV11.createFrame("SEND");
|
||||||
|
|
||||||
|
String body = "Hello World 1!";
|
||||||
|
String cLen = String.valueOf(body.getBytes(StandardCharsets.UTF_8).length);
|
||||||
|
|
||||||
|
frame.addHeader("destination", getQueuePrefix() + getQueueName());
|
||||||
|
frame.addHeader("content-type", "text/plain");
|
||||||
|
frame.addHeader("content-length", cLen);
|
||||||
|
String hKey = "undefined-escape";
|
||||||
|
String hVal = "is\\ttab";
|
||||||
|
frame.addHeader(hKey, hVal);
|
||||||
|
|
||||||
|
System.out.println("key: |" + hKey + "| val: |" + hVal + "|");
|
||||||
|
|
||||||
|
frame.setBody(body);
|
||||||
|
|
||||||
|
connV11.sendFrame(frame);
|
||||||
|
|
||||||
|
ClientStompFrame error = connV11.receiveFrame();
|
||||||
|
|
||||||
|
System.out.println("received " + error);
|
||||||
|
|
||||||
|
String desc = "Should have received an ERROR for undefined escape sequence";
|
||||||
|
Assert.assertNotNull(desc, error);
|
||||||
|
Assert.assertEquals(desc, "ERROR", error.getCommand());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHeartBeat() throws Exception {
|
public void testHeartBeat() throws Exception {
|
||||||
//no heart beat at all if heat-beat absent
|
//no heart beat at all if heat-beat absent
|
||||||
|
|
|
@ -564,6 +564,42 @@ public class StompV12Test extends StompV11TestBase {
|
||||||
newConn.disconnect();
|
newConn.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In 1.2, undefined escapes must cause a fatal protocol error.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testHeaderUndefinedEscape() throws Exception {
|
||||||
|
connV12.connect(defUser, defPass);
|
||||||
|
ClientStompFrame frame = connV12.createFrame("SEND");
|
||||||
|
|
||||||
|
String body = "Hello World 1!";
|
||||||
|
String cLen = String.valueOf(body.getBytes(StandardCharsets.UTF_8).length);
|
||||||
|
|
||||||
|
frame.addHeader("destination", getQueuePrefix() + getQueueName());
|
||||||
|
frame.addHeader("content-type", "text/plain");
|
||||||
|
frame.addHeader("content-length", cLen);
|
||||||
|
String hKey = "undefined-escape";
|
||||||
|
String hVal = "is\\ttab";
|
||||||
|
frame.addHeader(hKey, hVal);
|
||||||
|
|
||||||
|
System.out.println("key: |" + hKey + "| val: |" + hVal + "|");
|
||||||
|
|
||||||
|
frame.setBody(body);
|
||||||
|
|
||||||
|
connV12.sendFrame(frame);
|
||||||
|
|
||||||
|
ClientStompFrame error = connV12.receiveFrame();
|
||||||
|
|
||||||
|
System.out.println("received " + error);
|
||||||
|
|
||||||
|
String desc = "Should have received an ERROR for undefined escape sequence";
|
||||||
|
Assert.assertNotNull(desc, error);
|
||||||
|
Assert.assertEquals(desc, "ERROR", error.getCommand());
|
||||||
|
|
||||||
|
waitDisconnect(connV12);
|
||||||
|
Assert.assertFalse("Should be disconnected in STOMP 1.2 after ERROR", connV12.isConnected());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHeartBeat() throws Exception {
|
public void testHeartBeat() throws Exception {
|
||||||
StompClientConnection conn = StompClientConnectionFactory.createClientConnection("1.2", hostname, port);
|
StompClientConnection conn = StompClientConnectionFactory.createClientConnection("1.2", hostname, port);
|
||||||
|
|
Loading…
Reference in New Issue