bruno icon indicating copy to clipboard operation
bruno copied to clipboard

STOMP WebSocket Protocol Messages Not Working Due to NUL Character Conversion

Open elienFR opened this issue 1 month ago • 3 comments

I have checked the following:

  • [x] I have searched existing issues and found nothing related to my issue.

This bug is:

  • [x] making Bruno unusable for me
  • [ ] slowing me down but I'm able to continue working
  • [ ] annoying
  • [ ] this feature was working in a previous version but is broken in the current release.

Bruno version

2.14.2

Operating System

Linux 6.14.0-35-generic

Describe the bug

Related to : issue #5969

STOMP is a very simple messaging protocol that supports real-time updates via WebSockets. When establishing a connection to a STOMP server, the client must:

Send an initial HTTP request granted into a WebSocket connection and
Send a WebSocket message to CONNECT to STOMP server then SUBSCRIBE to topics and listening to messages.

STOMP requires that WebSocket messages end with the \u0000 (NUL) character, as described into STOMP Frames policy. However, it looks like Bruno automatically converts this character into literal \u0000, which breaks the STOMP message format — resulting in no response from the server after having properly initialized the connection, and therefore no subscription are recorded and no message are received from the server. I think it comes from the content type. Currently only TEXT, JSON, XML are available. Binary should solve the problem or at least a Text/Hex editor, or a text editor that interprets \u[CodedChar] characters.

How to reproduce

Set up a STOMP server in Spring boot app (Java), or any other language/app that provide STOMP Server sdk.
Connect to the server using a Bruno websocket connection.
Send the initial CONNECT message to establish a STOMP connection (e.g. 
    ---------- Beginning of message----------------
    CONNECT
    browser-session-id:37737a5c-95d3-4b07-bd4f-d1136fe21056
    accept-version:1.2,1.1,1.0
    heart-beat:10000,10000
    
    ^@
    ---------- End of message, '^@' is Nul char in vim ----------------).
Observe that the server does not respond with a CONNECTED RESPONSE.

Bruno appears to automatically transform characters like \u0000 into literal \u0000 in text editor, preventing proper STOMP message formatting.

Including support for sending raw control characters (such as \u0000) in WebSocket messages should resolve this issue and enable full STOMP compatibility (i think).

.bru file to reproduce the bug

meta { name: websocket connection type: ws seq: 4 }

ws { url: http://localhost:8098/real-time?token={{access_token}} body: ws auth: none }

body:ws { name: message 1 content: ''' CONNECT browser-session-id:[SomeId] accept-version:1.2,1.1,1.0 heart-beat:10000,10000

\\u0000

''' }

Screenshots/Live demo link

Image

elienFR avatar Nov 13 '25 16:11 elienFR

I tweaked the .bru file by hex editing it to force the NUL char, it now appears in bruno as a red dot. But it is still sent converted into literal \u0000 :

Image

elienFR avatar Nov 13 '25 16:11 elienFR

There's a similar requirement for https://github.com/usebruno/bruno/issues/5969 where a special unicode character might be used to signify a valid handshake. This is being tracked internally on that. Please subscribe to that issue for updates.

sid-bruno avatar Nov 14 '25 12:11 sid-bruno

With Spring Boot, Stomp and SockJS on the server side, it's possible to send messages from Bruno if they are formatted as JSON. The message must be manually escaped. Not ideal, but it works ...

[ "SUBSCRIBE\nid:sub-0\ndestination:/user/queue/example\n\n\u0000" ]

It's also hard to find out how the server URL must look like: This isn't documented anywhere because the common libraries usually handle it. In my case, it was: ws://localhost:8080/ws/123/1234/websocket where 123 is the server-id and 1234 is the session-id. Both can be freely chosen, but must be identical for all associated requests. The part websocket at the end is a SockJS convention.

volkerliehr avatar Nov 14 '25 17:11 volkerliehr

With Spring Boot, Stomp and SockJS on the server side, it's possible to send messages from Bruno if they are formatted as JSON. The message must be manually escaped. Not ideal, but it works ...

[ "SUBSCRIBE\nid:sub-0\ndestination:/user/queue/example\n\n\u0000" ]

It's also hard to find out how the server URL must look like: This isn't documented anywhere because the common libraries usually handle it. In my case, it was: ws://localhost:8080/ws/123/1234/websocket where 123 is the server-id and 1234 is the session-id. Both can be freely chosen, but must be identical for all associated requests. The part websocket at the end is a SockJS convention.

Understood, we might need help from the community to figure out all the possible common conventions, also because WS is a new addition to Bruno, there's quite a few basic things that still are missing due to lack of bandwidth which we are working on.

The obvious bug is the loss of special characters in this case so we'll prioritise that and we'll get to the other layered protocols as soon as we can

sid-bruno avatar Nov 17 '25 06:11 sid-bruno

With Spring Boot, Stomp and SockJS on the server side, it's possible to send messages from Bruno if they are formatted as JSON. The message must be manually escaped. Not ideal, but it works ...

[ "SUBSCRIBE\nid:sub-0\ndestination:/user/queue/example\n\n\u0000" ]

It's also hard to find out how the server URL must look like: This isn't documented anywhere because the common libraries usually handle it. In my case, it was: ws://localhost:8080/ws/123/1234/websocket where 123 is the server-id and 1234 is the session-id. Both can be freely chosen, but must be identical for all associated requests. The part websocket at the end is a SockJS convention.

Thanks for the tips ! I will try this workaround :)

elienFR avatar Nov 17 '25 14:11 elienFR