Skip Menu |

This queue is for tickets about the AnyEvent-STOMP CPAN distribution.

Report information
The Basics
Id: 68433
Status: open
Priority: 0/
Queue: AnyEvent-STOMP

People
Owner: Nobody in particular
Requestors: TJC [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 0.6
Fixed in: (no value)



Subject: Messages after the first fail to be received properly
I'm connecting to Apache ActiveMQ 5.5.0 with AnyEvent::STOMP. I've already applied the patch for correct content-length on undef bodies, as per my previous bug report. The first MESSAGE to be received will work correctly. All subsequent ones will fail. This appears to be because AE::STOMP is inserting an extra \n in the $raw_headers in _receive_frame(). So instead of them looking like "MESSAGE\n" it looks like "\nMESSAGE\n". Thus, the event is dispatched to the event of type "" rather than MESSAGE.
My kludge for the time being is to add this to line 257: $raw_headers =~ s/^\n//; But I'm sure there's a better way. I'm suspicious that maybe you're not reading the correct amount of data in from the previous message, and are thus off-by-one, leaving a trailing carriage return?
I don't think it's related to the send_frame() issue you posted earlier. Instead, I suspect this is because ActiveMQ is padding the output with additional bytes. (I pleaded with the STOMP protocol folks not to do this, but they refused to listen.) I'm puzzled as to why you have to trim leading line feeds off $raw_headers. The regex should be ignoring them for you: $self->{handle}->unshift_read(regex => qr/\n*([^\n].*?)\n\n/s, ... What happens if you left-anchor the regexp? $self->{handle}->unshift_read(regex => qr/^\n*([^\n].*?)\n\n/s, ... Also, if you could provide a dump of the contents of $raw_headers when this happens, I'd appreciate it.
I don't think it's related to the send_frame() issue you posted earlier. Instead, I suspect this is because ActiveMQ is padding the output with additional bytes. (I pleaded with the STOMP protocol folks not to do this, but they refused to listen.) I'm puzzled as to why you have to trim leading line feeds off $raw_headers. The regex should be ignoring them for you: $self->{handle}->unshift_read(regex => qr/\n*([^\n].*?)\n\n/s, ... What happens if you left-anchor the regexp? $self->{handle}->unshift_read(regex => qr/^\n*([^\n].*?)\n\n/s, ... Also, if you could provide a dump of the contents of $raw_headers when this happens, I'd appreciate it.
Here is the output of the raw headers. I've surrounded them with {{{ and }}} so you can tell where the whitespace ends. In this example, the CONNECTED and first MESSAGE works, but the second MESSAGE does not get through to my app. Notice that it has a \n at the start of the headers. Headers{{{CONNECTED session:ID:adonai-49241-1306224515617-4:64 }}} Headers{{{MESSAGE message-id:ID:adonai-49241-1306224515617-4:65:-1:1:1 destination:/queue/testmail timestamp:1306287038310 expires:0 content-length:13 priority:4 }}} Headers{{{ MESSAGE message-id:ID:adonai-49241-1306224515617-4:65:-1:1:2 destination:/queue/testmail timestamp:1306287041312 expires:0 content-length:13 priority:4 }}}
On Tue May 24 16:24:45 2011, OTTERLEY wrote: Show quoted text
> $self->{handle}->unshift_read(regex => qr/\n*([^\n].*?)\n\n/s, ... > > What happens if you left-anchor the regexp? > > $self->{handle}->unshift_read(regex => qr/^\n*([^\n].*?)\n\n/s, ...
Changing the regex doesn't seem to help - the raw headers are the same as before for the messages after the first.
On Tue May 24 21:34:59 2011, TJC wrote: Show quoted text
> On Tue May 24 16:24:45 2011, OTTERLEY wrote:
> > $self->{handle}->unshift_read(regex => qr/\n*([^\n].*?)\n\n/s, ... > > > > What happens if you left-anchor the regexp? > > > > $self->{handle}->unshift_read(regex => qr/^\n*([^\n].*?)\n\n/s, ...
> > Changing the regex doesn't seem to help - the raw headers are the same
as Show quoted text
> before for the messages after the first.
The regex for AnyEvent::Handle there is matching the final line of the headers, I think? So changing it won't effect the first line of the headers. It seems like a new-line is being carried over from the part where the code reads the body of the message in. In my case, I can fix it like so: @args = ('chunk' => $content_length + 2); (rather than the original, which is $content_length + 1) That looks like ActiveMQ is sending an extraneous carriage return after the terminating NULL byte to me. Hmm. An alternative solution is to change the regex that pulls out the initial COMMAND line to this: if ($raw_headers =~ s/^\n*(.+)\n//) { $command = $1; }
On Tue May 24 21:52:49 2011, TJC wrote: Show quoted text
> On Tue May 24 21:34:59 2011, TJC wrote:
> > On Tue May 24 16:24:45 2011, OTTERLEY wrote:
> > > $self->{handle}->unshift_read(regex => qr/\n*([^\n].*?)\n\n/s, ... > > > > > > What happens if you left-anchor the regexp? > > > > > > $self->{handle}->unshift_read(regex => qr/^\n*([^\n].*?)\n\n/s, ...
> > > > Changing the regex doesn't seem to help - the raw headers are the same
> as
> > before for the messages after the first.
> > > The regex for AnyEvent::Handle there is matching the final line of the > headers, I think? So changing it won't effect the first line of the > headers.
Well, the intent of the regex is: 1) skip any newlines until the first non-LF is encountered, then 2) read and capture all data up till the next \n\n is encountered (i.e., the headers) Show quoted text
> That looks like ActiveMQ is sending an extraneous carriage return after > the terminating NULL byte to me. Hmm.
Indeed, it is. I'm not a fan of the STOMP protocol for that reason. (Their justification is that they wanted to make it easy to interact with via telnet.) Show quoted text
> An alternative solution is to change the regex that pulls out the > initial COMMAND line to this: > > if ($raw_headers =~ s/^\n*(.+)\n//) { > $command = $1; > }
That's an OK workaround, I suppose, but I'd sure like to know why my initial regex is defective.
Show quoted text
> > The regex for AnyEvent::Handle there is matching the final line of
> the
> > headers, I think? So changing it won't effect the first line of the > > headers.
> > Well, the intent of the regex is: > > 1) skip any newlines until the first non-LF is encountered, then > 2) read and capture all data up till the next \n\n is encountered > (i.e., the headers)
[snip] Show quoted text
> I'd sure like to know why my initial regex is defective.
I don't think the regex is being used in the way you think it is. The docs for AnyEvent::Handle say that when passing a regex in, it's used to match the *end* of the block of data you want. (If I have read the docs correctly) Then everything up until that point is sent through, and goes into $raw_headers. So you can't skip characters by using that regex, I think. Umm, I could be wrong though.