1 2 Previous Next 18 Replies Latest reply on Oct 9, 2014 3:50 PM by harleybl Go to original post
      • 15. Re: Re: Re: HornetQ Stomp Subscription ID Mangling in JBoss EAP 6.2.4
        jbertram

        So I've been looking at your test, the STOMP 1.1 and 1.2 specs, the HornetQ STOMP implementation, and the ActiveMQ STOMP implementation.  I believe that HornetQ is definitely not handling some of the header encoding properly.  However, I think your test is also in error.  I think this line in particular is problematic:

         

        assertEquals("ID:MYMACHINE-50616-635482262727823605-1:1:1:1", frame.getHeader("subscription"));
        
        

         

        According to the spec:

        C style string literal escapes are used to encode any carriage return, line feed or colon that are found within the UTF-8 encoded headers. When decoding frame headers, the following transformations MUST be applied:

        • \r (octet 92 and 114) translates to carriage return (octet 13)
        • \n (octet 92 and 110) translates to line feed (octet 10)
        • \c (octet 92 and 99) translates to : (octet 58)
        • \\ (octet 92 and 92) translates to \ (octet 92)

        Undefined escape sequences such as \t (octet 92 and 116) MUST be treated as a fatal protocol error. Conversely when encoding frame headers, the reverse transformation MUST be applied.

        I interpret this to mean that if you send a header with a '\c' in it then you should expect to get a header with '\c' in it back.  This is how the ActiveMQ STOMP implementation works (which I trust as spec-compliant).  This means that your assertEquals should be this instead:

         

        assertEquals("ID\\cMYMACHINE-50616-635482262727823605-1\\c1\\c1\\c1", frame.getHeader("subscription"));
        
        

         

        Once I commit my fixes this updated assertion will pass.

        • 16. Re: Re: Re: Re: HornetQ Stomp Subscription ID Mangling in JBoss EAP 6.2.4
          harleybl

          I think I see what you are saying and I wrote my test that way because I thought that the recieveFrame() call in this code would do the conversion back from \c to :

           

          frame = newConn.receiveFrame();
          
          
                  System.out.println("received " + frame);
          
          
                  assertEquals("MESSAGE", frame.getCommand());
                  assertEquals("ID:MYMACHINE-50616-635482262727823605-1:1:1:1", frame.getHeader("subscription"));
          
          
          
          
          
          

           

          It sounds like the conversion to and from \c is happening under the covers, so you shouldn't ever send that in a frame.

          If you change the test to send and expect ':' following - will the test pass with your new code?

           

          //subscribe
                  StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
                  newConn.connect(defUser, defPass);
          
          
                  ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
                  subFrame.addHeader("id", "ID:MYMACHINE-50616-635482262727823605-1:1:1:1");
                  subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
                  subFrame.addHeader("ack", "auto");
          
          
                  newConn.sendFrame(subFrame);
          
          
                  frame = newConn.receiveFrame();
          
          
                  System.out.println("received " + frame);
          
          
                  assertEquals("MESSAGE", frame.getCommand());
                  assertEquals("ID:MYMACHINE-50616-635482262727823605-1:1:1:1", frame.getHeader("subscription"));
                  assertNotNull(frame.getHeader("message-id"));
                  assertEquals(getQueuePrefix() + getQueueName(), frame.getHeader("destination"));
                  assertEquals("Hello World 1!", frame.getBody());
          
          
                  //unsub
          
          
          
          
          
          
          
          
          
          
          
          

           

          The current code base I have does not.

          • 17. Re: Re: Re: Re: HornetQ Stomp Subscription ID Mangling in JBoss EAP 6.2.4
            jbertram

            I think I see what you are saying and I wrote my test that way because I thought that the recieveFrame() call in this code would do the conversion back from \c to :

            The helper classes in the HornetQ test-suite for STOMP 1.1 tests do certain conversions, but the one we're concerned with is broken.  In any event, that is only relevant in the HornetQ test-suite.  Other STOMP clients/frameworks would still need to deal with the frame decoding on their own, and if you were dealing with the raw STOMP text frames then you would have to do the decoding manually yourself.  My point is, no matter what kind of helper you might (or might not) have on the client if the frame that leaves the client contains a '\c' then it should expect a '\c' in return.  The current HornetQ STOMP implementation currently gets this wrong.

             

            I will probably fix the helper class in the HornetQ test-suite so that your original test-case passes.

             

            To be clear, I don't know what Apache NMS STOMP does in this case.  I don't know whether it will pass the '\c' characters back to you or do the decoding for you.

            • 18. Re: Re: Re: Re: HornetQ Stomp Subscription ID Mangling in JBoss EAP 6.2.4
              harleybl

              I think we are in agreement. All I can expect the HornetQ Stomp module to do is respect the stomp protocol as defined.

              The Apache.NMS.Stomp client should decode the headers properly and if it doesn't I'll either submit a patch to them or push them to fix it.

              1 2 Previous Next