LP#1744158 Websocket proc exits on ejabberd disconnect
authorBill Erickson <berickxx@gmail.com>
Wed, 24 Jan 2018 20:16:14 +0000 (15:16 -0500)
committerJason Stephenson <jason@sigio.com>
Thu, 1 Feb 2018 20:51:54 +0000 (15:51 -0500)
Any errors relaying websocket messages to OpenSRF now result in the WS
client being disconnected, allowing the WS process to exit.  This
prevents the WS gateway from accepting requests it cannot process and
allows the client to connect to a new WS process.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Jason Stephenson <jason@sigio.com>

src/gateway/osrf_websocket_translator.c

index f43fb62..2d3a5e1 100644 (file)
@@ -911,8 +911,12 @@ static size_t on_message_handler_body(void *data,
         msg_body, NULL, thread, recipient, NULL);
 
     message_set_osrf_xid(tmsg, osrfLogGetXid());
-    client_send_message(osrf_handle, tmsg);
 
+    size_t stat = OK;
+    if (client_send_message(osrf_handle, tmsg) != 0) {
+        osrfLogError(OSRF_LOG_MARK, "WS failed sending data to OpenSRF");
+        stat = HTTP_INTERNAL_SERVER_ERROR;
+    }
 
     osrfLogClearXid();
     message_free(tmsg);                                                         
@@ -920,7 +924,7 @@ static size_t on_message_handler_body(void *data,
     free(msg_body);
 
     last_activity_time = time(NULL);
-    return OK;
+    return stat;
 }
 
 static size_t CALLBACK on_message_handler(void *data,
@@ -929,16 +933,25 @@ static size_t CALLBACK on_message_handler(void *data,
 
     if (apr_thread_mutex_lock(trans->mutex) != APR_SUCCESS) {
         osrfLogError(OSRF_LOG_MARK, "WS error locking thread mutex");
-        return 1; // TODO: map to apr_status_t value?
+        return 1;
     }
 
-    apr_status_t stat = on_message_handler_body(data, server, type, buffer, buffer_size);
+    size_t stat = on_message_handler_body(data, server, type, buffer, buffer_size);
 
     if (apr_thread_mutex_unlock(trans->mutex) != APR_SUCCESS) {
         osrfLogError(OSRF_LOG_MARK, "WS error locking thread mutex");
         return 1;
     }
 
+    if (stat != OK) {
+        // Returning a non-OK status alone won't force a disconnect.
+        // Once disconnected, the on_disconnect_handler() handler
+        // will run, clean it all up, and kill the process.
+        osrfLogError(OSRF_LOG_MARK,
+            "Error relaying message, forcing client disconnect");
+        trans->server->close(trans->server);
+    }
+
     return stat;
 }