in artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompDecoder.java [359:539]
protected boolean parseCommand() throws ActiveMQStompException {
int offset = 0;
boolean nextChar = false;
// Some badly behaved STOMP clients add a \n *after* the terminating NUL char at the end of the
// STOMP frame this can manifest as an extra \n at the beginning when the
// next STOMP frame is read - we need to deal with this.
// Besides, Stomp 1.2 allows for extra EOLs after NULL (i.e.
// either "[\r]\n"s or "\n"s)
while (offset < data) {
if (workingBuffer[offset] == NEW_LINE) {
nextChar = false;
} else if (workingBuffer[offset] == CR) {
if (nextChar)
throw BUNDLE.invalidTwoCRs().setHandler(handler);
nextChar = true;
} else {
break;
}
offset++;
}
if (nextChar) {
throw BUNDLE.badCRs().setHandler(handler);
}
if (data < 4 + offset) {
// Need at least four bytes to identify the command
// - up to 3 bytes for the command name + potentially another byte for a leading \n
return false;
}
byte b = workingBuffer[offset];
switch (b) {
case A: {
if (workingBuffer[offset + 1] == B) {
if (!tryIncrement(offset + COMMAND_ABORT_LENGTH + 1)) {
return false;
}
// ABORT
command = COMMAND_ABORT;
} else {
if (!tryIncrement(offset + COMMAND_ACK_LENGTH + 1)) {
return false;
}
// ACK
command = COMMAND_ACK;
}
break;
}
case B: {
if (!tryIncrement(offset + COMMAND_BEGIN_LENGTH + 1)) {
return false;
}
// BEGIN
command = COMMAND_BEGIN;
break;
}
case C: {
if (workingBuffer[offset + 2] == M) {
if (!tryIncrement(offset + COMMAND_COMMIT_LENGTH + 1)) {
return false;
}
// COMMIT
command = COMMAND_COMMIT;
} else if (workingBuffer[offset + 7] == E) {
if (!tryIncrement(offset + COMMAND_CONNECTED_LENGTH + 1)) {
return false;
}
// CONNECTED
command = COMMAND_CONNECTED;
} else {
if (!tryIncrement(offset + COMMAND_CONNECT_LENGTH + 1)) {
return false;
}
// CONNECT
command = COMMAND_CONNECT;
}
break;
}
case D: {
if (!tryIncrement(offset + COMMAND_DISCONNECT_LENGTH + 1)) {
return false;
}
// DISCONNECT
command = COMMAND_DISCONNECT;
break;
}
case R: {
if (!tryIncrement(offset + COMMAND_RECEIPT_LENGTH + 1)) {
return false;
}
// RECEIPT
command = COMMAND_RECEIPT;
break;
}
/**** added by meddy, 27 april 2011, handle header parser for reply to websocket protocol ****/
case E: {
if (!tryIncrement(offset + COMMAND_ERROR_LENGTH + 1)) {
return false;
}
// ERROR
command = COMMAND_ERROR;
break;
}
case M: {
if (!tryIncrement(offset + COMMAND_MESSAGE_LENGTH + 1)) {
return false;
}
// MESSAGE
command = COMMAND_MESSAGE;
break;
}
/**** end ****/
case S: {
if (workingBuffer[offset + 1] == E) {
if (!tryIncrement(offset + COMMAND_SEND_LENGTH + 1)) {
return false;
}
// SEND
command = COMMAND_SEND;
} else if (workingBuffer[offset + 1] == T) {
if (!tryIncrement(offset + COMMAND_STOMP_LENGTH + 1)) {
return false;
}
// STOMP
command = COMMAND_STOMP;
} else {
if (!tryIncrement(offset + COMMAND_SUBSCRIBE_LENGTH + 1)) {
return false;
}
// SUBSCRIBE
command = COMMAND_SUBSCRIBE;
}
break;
}
case U: {
if (!tryIncrement(offset + COMMAND_UNSUBSCRIBE_LENGTH + 1)) {
return false;
}
// UNSUBSCRIBE
command = COMMAND_UNSUBSCRIBE;
break;
}
default: {
throwInvalid();
}
}
// Sanity check
if (workingBuffer[pos - 1] != NEW_LINE) {
//give a signal to try other versions
ActiveMQStompException error = BUNDLE.notValidNewLine(workingBuffer[pos - 1]).setHandler(handler);
error.setCode(ActiveMQStompException.INVALID_EOL_V10);
error.setBody(BUNDLE.unexpectedNewLine(workingBuffer[pos - 1]));
throw error;
}
return true;
}