php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #58949 readFrame does not notice when server shuts down
Submitted: 2009-11-13 09:00 UTC Modified: 2009-11-14 17:49 UTC
From: pop3 at flachtaucher dot de Assigned:
Status: Closed Package: stomp (PECL)
PHP Version: 5.3.0 OS: Linux
Private report: No CVE-ID: None
 [2009-11-13 09:00 UTC] pop3 at flachtaucher dot de
Description:
------------
Server: ActiveMQ 5.3 with Stomp enabled.

Start a client that listens on a queue. Now shut down the ActiveMQ-Server. Client will hang forever without notifying us about the connection drop.



Reproduce code:
---------------
try {
    $stomp = new Stomp('tcp://1.2.3.4:61613', 'user', 'password');
} catch(StompException $e) {
    die('Connection failed: ' . $e->getMessage()."\n");
    exit;
}
$stomp->subscribe('/queue/temp.foo');

while(1) {
  $oRequest = $stomp->readFrame();
  var_dump($oRequest);
}



Shut down server while the client in reproduce code runs.

Expected result:
----------------
We will somehow notice that the server went down (maybe through an exception?)



Actual result:
--------------
Loop continues to run as if no further message was sent be the server.


Here is my patch for better handling in recv(). This also throws an exception if select() gives us an error.


--- stomp-0.3.1.orig/stomp.c    1970-01-01 10:13:08.000000000 +0100
+++ stomp-0.3.1/stomp.c 2009-11-12 14:59:18.000000000 +0100
@@ -30,6 +30,7 @@
 #define RETURN_READ_FRAME_FAIL { frame_destroy(f); return NULL; }

 ZEND_EXTERN_MODULE_GLOBALS(stomp);
+extern stomp_ce_exception;

 /* {{{ stomp_new
  */
@@ -249,12 +250,17 @@
  */
 int stomp_recv(stomp_t *stomp, char *msg, size_t length)
 {
+ssize_t len;
 #if HAVE_STOMP_SSL
     if(stomp->use_ssl) {
         return SSL_read(stomp->ssl_handle, msg, length);
     } else {
 #endif
-        return recv(stomp->fd, msg, length, 0);
+        len = recv(stomp->fd, msg, length, 0);
+        if ( len == 0 ) {
+          zend_throw_exception_ex(stomp_ce_exception, errno TSRMLS_CC, "Unexpected EOF while reading from socket");
+        }
+        return len;
 #if HAVE_STOMP_SSL
     }
 #endif
--- stomp-0.3.1.orig/php_stomp.c        1970-01-01 10:14:21.000000000 +0100
+++ stomp-0.3.1/php_stomp.c     2009-11-12 15:50:06.000000000 +0100
@@ -796,6 +815,7 @@
     zval *stomp_object = getThis();
     stomp_t *stomp = NULL;
     stomp_frame_t *res = NULL;
+    int sel_res;

     if (stomp_object) {
         stomp_object_t *i_obj = NULL;
@@ -808,7 +828,7 @@
         ZEND_FETCH_RESOURCE(stomp, stomp_t *, &arg, -1, PHP_STOMP_RES_NAME, le_stomp);
     }

-    if (stomp_select(stomp) > 0 && (res = stomp_read_frame(stomp))) {
+    if ((sel_res = stomp_select(stomp)) > 0 && (res = stomp_read_frame(stomp))) {
         zval *headers = NULL;
         MAKE_STD_ZVAL(headers);
         array_init(headers);
@@ -845,6 +874,9 @@

         frame_destroy(res);
     } else {
+        if (sel_res == -1) {
+            STOMP_ERROR(0, "Error while selecting from socket: %d", errno);
+        }
         RETURN_FALSE;
     }
 }


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-11-14 17:49 UTC] pierrick@php.net
Fixed in revision 290762
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 21:01:36 2024 UTC