/**
   * Encodes the given payload and headers into a {@code byte[]}.
   *
   * @param headers the headers
   * @param payload the payload
   * @return the encoded message
   */
  public byte[] encode(Map<String, Object> headers, byte[] payload) {
    Assert.notNull(headers, "'headers' is required");
    Assert.notNull(payload, "'payload' is required");
    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream(128 + payload.length);
      DataOutputStream output = new DataOutputStream(baos);

      if (SimpMessageType.HEARTBEAT.equals(SimpMessageHeaderAccessor.getMessageType(headers))) {
        logger.trace("Encoded heartbeat");
        output.write(StompDecoder.HEARTBEAT_PAYLOAD);
      } else {
        StompCommand command = StompHeaderAccessor.getCommand(headers);
        Assert.notNull(command, "Missing STOMP command: " + headers);
        output.write(command.toString().getBytes(StompDecoder.UTF8_CHARSET));
        output.write(LF);
        writeHeaders(command, headers, payload, output);
        output.write(LF);
        writeBody(payload, output);
        output.write((byte) 0);
      }

      return baos.toByteArray();
    } catch (IOException e) {
      throw new StompConversionException(
          "Failed to encode STOMP frame, headers=" + headers + ".", e);
    }
  }
 @Override
 public String getDetailedLogMessage(Object payload) {
   if (isHeartbeat()) {
     return "heart-beat in session " + getSessionId();
   }
   StompCommand command = getCommand();
   if (command == null) {
     return super.getDetailedLogMessage(payload);
   }
   StringBuilder sb = new StringBuilder();
   sb.append(command.name()).append(" ").append(getNativeHeaders()).append(appendSession());
   if (getUser() != null) {
     sb.append(", user=").append(getUser().getName());
   }
   if (command.isBodyAllowed()) {
     sb.append(appendPayload(payload));
   }
   return sb.toString();
 }
  private void writeHeaders(
      StompCommand command, Map<String, Object> headers, byte[] payload, DataOutputStream output)
      throws IOException {

    @SuppressWarnings("unchecked")
    Map<String, List<String>> nativeHeaders =
        (Map<String, List<String>>) headers.get(NativeMessageHeaderAccessor.NATIVE_HEADERS);

    if (logger.isTraceEnabled()) {
      logger.trace("Encoding STOMP " + command + ", headers=" + nativeHeaders + ".");
    }

    if (nativeHeaders == null) {
      return;
    }

    boolean shouldEscape = (command != StompCommand.CONNECT && command != StompCommand.CONNECTED);

    for (Entry<String, List<String>> entry : nativeHeaders.entrySet()) {
      byte[] key = encodeHeaderString(entry.getKey(), shouldEscape);
      List<String> values = entry.getValue();
      if (StompHeaderAccessor.STOMP_PASSCODE_HEADER.equals(entry.getKey())) {
        values = Arrays.asList(StompHeaderAccessor.getPasscode(headers));
      }
      for (String value : values) {
        output.write(key);
        output.write(COLON);
        output.write(encodeHeaderString(value, shouldEscape));
        output.write(LF);
      }
    }
    if (command.requiresContentLength()) {
      int contentLength = payload.length;
      output.write("content-length:".getBytes(StompDecoder.UTF8_CHARSET));
      output.write(Integer.toString(contentLength).getBytes(StompDecoder.UTF8_CHARSET));
      output.write(LF);
    }
  }
 /** A constructor for creating message headers from a parsed STOMP frame. */
 StompHeaderAccessor(StompCommand command, Map<String, List<String>> externalSourceHeaders) {
   super(command.getMessageType(), externalSourceHeaders);
   setHeader(COMMAND_HEADER, command);
   updateSimpMessageHeadersFromStompHeaders();
 }
Example #5
0
  /** Decode a single STOMP frame from the given {@code buffer} into a {@link Message}. */
  private Message<byte[]> decodeMessage(ByteBuffer buffer, MultiValueMap<String, String> headers) {

    Message<byte[]> decodedMessage = null;
    skipLeadingEol(buffer);
    buffer.mark();

    String command = readCommand(buffer);
    if (command.length() > 0) {

      StompHeaderAccessor headerAccessor = null;
      byte[] payload = null;

      if (buffer.remaining() > 0) {
        StompCommand stompCommand = StompCommand.valueOf(command);
        headerAccessor = StompHeaderAccessor.create(stompCommand);
        initHeaders(headerAccessor);

        readHeaders(buffer, headerAccessor);
        payload = readPayload(buffer, headerAccessor);
      }

      if (payload != null) {
        if ((payload.length > 0) && (!headerAccessor.getCommand().isBodyAllowed())) {
          throw new StompConversionException(
              headerAccessor.getCommand()
                  + " shouldn't have a payload: length="
                  + payload.length
                  + ", headers="
                  + headers);
        }
        headerAccessor.updateSimpMessageHeadersFromStompHeaders();
        headerAccessor.setLeaveMutable(true);
        decodedMessage = MessageBuilder.createMessage(payload, headerAccessor.getMessageHeaders());
        if (logger.isDebugEnabled()) {
          logger.debug("Decoded " + decodedMessage);
        }
      } else {
        if (logger.isTraceEnabled()) {
          logger.trace("Received incomplete frame. Resetting buffer.");
        }
        if (headers != null && headerAccessor != null) {
          String name = NativeMessageHeaderAccessor.NATIVE_HEADERS;
          @SuppressWarnings("unchecked")
          MultiValueMap<String, String> map =
              (MultiValueMap<String, String>) headerAccessor.getHeader(name);
          if (map != null) {
            headers.putAll(map);
          }
        }
        buffer.reset();
      }
    } else {
      if (logger.isTraceEnabled()) {
        logger.trace("Decoded heartbeat");
      }
      StompHeaderAccessor headerAccessor = StompHeaderAccessor.createForHeartbeat();
      initHeaders(headerAccessor);
      headerAccessor.setLeaveMutable(true);
      decodedMessage =
          MessageBuilder.createMessage(HEARTBEAT_PAYLOAD, headerAccessor.getMessageHeaders());
    }
    return decodedMessage;
  }