php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #59217 Connections to RabbitMQ (via CLI)
Submitted: 2010-05-15 21:27 UTC Modified: 2012-11-19 01:23 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: alex at zander dot net Assigned: pierrick (profile)
Status: Closed Package: stomp (PECL)
PHP Version: Stomp 1.0.0, PHP 5.2.11 OS: Linux (Centos 4.6)
Private report: No CVE-ID: None
 [2010-05-15 21:27 UTC] alex at zander dot net
Description:
------------
I am attempting to connect to a RabbitMQ service that has 
been tested and is known to support connections via STOMP 
using other methods.

I have installed this PECL and it appears to be installed 
correctly because it is included in the output from 
phpinfo() and the RabbitMQ log file shows my PHP application 
connecting successfully.

My PHP application is run from the command-line (i.e. not 
via a web server) and it executes successfully but when it 
reaches the line that instantiates the Stomp class it 
freezes and does not progress or terminate until I kill it 
using CTRL-C.



Reproduce code:
---------------
#!/usr/bin/php
<?
try {
    $URI = 'tcp://localhost:61613';
    $conn = new Stomp ( 'tcp://localhost:61613', 'guest', 'guest' );
} catch( StompException $e ) {
    die( $e->getMessage()."\n" );
}
echo "This line never gets executed!";
?>

Expected result:
----------------
When running the application from the command-line, it should 
execute and output the string "This line never gets 
executed!".

Actual result:
--------------
If the username or password are incorrect or not included then 
the application outputs "Unexpected EOF while reading from 
socket" and terminates.

If the username and password are correct then the application 
does not do anything - it does not return from the Stomp 
class's constructor and nothing is output. The application 
does not terminate until I manually terminate it using CTRL-C.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-05-15 21:30 UTC] alex at zander dot net
Updated version information.
 [2010-08-15 20:12 UTC] kalle@php.net
Hi, have you tried the latest version of stomp? And are you using Stomp over SSL?
 [2010-12-16 21:29 UTC] x at x dot com
After a bit of debug (I'm having the same issue with rabbit), it turns out rabbit's stomp adapter doesn't send out a newline after the message end NULL. So, stomp_read_buffer freezes on stomp_recv(stomp, endline, 1) waiting for the newline.

Rather than throwing away the newline after the null (which might not even be there on rabbitmq), I'd suggest just leaving it to be processed with the top of the next message. While parsing the next frame, just throw away the first line if it's empty.

Or, at the very minimum, give us a parameter to disable waiting for newlines after the nulls ;)
 [2011-09-27 10:43 UTC] marcelog at gmail dot com
This issue is still present in 1.0.3, tested with rabbitmq 
2.6.1.

I'm curious about why the newline is expected after the null 
character, and if there's any reason to not fix this 
behaviour.

According to the STOMP protocol 
(http://docs.codehaus.org/display/STOMP/Protocol) 

"The ^@ is a null (control-@ in ASCII) byte. The entire thing 
will be called a Frame in this doc. The frame starts with a 
command (in this case CONNECT), followed by a newline, 
followed by headers in a <key>:<value> with each header 
followed by a newline. A blank line indicates the end of the 
headers and beginning of the body (the body is empty in this 
case), and the null indicates the end of the frame."

Ending the reading loop as soon as the null character is 
encountered (yes, a very naive approach), seems to fix the 
problem, but I'm not sure about any side-effects on doing 
this. However, it seems to work ok 

         if (buffer[i-1] == 0) {
            //char endline[1];
            //if (1 != stomp_recv(stomp, endline, 1) && '\n' 
!= endline[0]) {
            // efree(buffer);
            // return 0;
            //}
            break;
         }
 [2011-09-27 12:41 UTC] pierrick@php.net
Hi :)

The problem is that the null is not used the same way in all 
stomp
implementations. I quickly tried your patch on ActiveMQ (the 
one i'm
using) and few tests are now failing.

Do you have an instance of RabbitMQ installed somewhere I 
can access
it so that I can try and work on a patch ?
 [2011-09-27 16:32 UTC] marcelog at gmail dot com
I think I get it now..

The ABNF (http://stomp.github.com/stomp-specification-
1.1.html#Augmented_BNF) states that the NULL, can be 
*optionally* followed by newlines.

Now it makes sense... Maybe changing stomp_recv() to first 
do a 
MSG_PEEK  (or SSL_peek) can solve this issue (reading 
whatever 
needs to be read and leaving the rest in the socket, without 
consuming all the data at once and avoiding having a 
permanent 
buffer).

It seems that the current code can only be compatible with 
one 
of the implementations (either with or without the optional 
newlines). I think I can give it a shot at coding a patch, 
if 
you think this can be a solution
 [2011-09-27 23:10 UTC] pierrick@php.net
Feel free to submit a patch :)
 [2011-09-28 10:54 UTC] marcelog at gmail dot com
I'll see what I can do. As a side note, here is a discussion 
of the subject in the stomp google group.

http://groups.google.com/group/stomp-
spec/browse_thread/thread/c1f3d362b488dd17#

And another one, where the creator of StompServer talks 
about the same thing:

http://activemq.2283324.n4.nabble.com/Trailing-new-line-in-
frame-td2398368.html

I'm not sure we can do a successfull patch with the actual 
code. What do you think?
 [2012-11-19 01:23 UTC] pierrick@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: pierrick
 [2012-11-19 01:23 UTC] pierrick@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.

You can find the latest version here :
https://github.com/php/pecl-tools-stomp/downloads
 [2013-05-02 21:06 UTC] mi+php at aldan dot algebra dot com
It would seem, the current implementation of the fix is still buggy. In this code:

	if (stomp_select_ex(stomp, 0, 0)) {
		char endline[1];
		if (1 != stomp_recv(stomp, endline, 1) && '\n' != endline[0]) {
			if (*data) {
				efree(*data);
				*data = NULL;
			}
			return 0;
		}
	}

it is possible for stomp_recv to return 0 or -1 -- and not place anything in endline. The memory in the "array" will then be uninitialized, which will SOMETIMES cause the read-failure (when the byte happens to match \n). Something like this is needed:

		char endline = '\0';
		if (1 != stomp_recv(stomp, &endline, 1) && '\n' != endline) {

also, even though false is returned, there is no error set to explain why -- something I fix carefully in the patch attached to Bug 64670.
 [2013-05-02 21:17 UTC] mi+php at aldan dot algebra dot com
Likewise, this code:

      length = stomp_recv(stomp, endbuffer, 2);
      if (endbuffer[0] != '\0' || ((2 == length) && (endbuffer[1] != '\n'))) {
                        RETURN_READ_FRAME_FAIL;

would fail, if the length returned is less than 1.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 15:01:28 2024 UTC