From aec60d194e9e6e7b8f94cf0e4670520152a6f825 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sat, 9 Feb 2019 12:01:58 +0100 Subject: [PATCH] fix: handle incoming websocket requests; fix: removed double free; introduced jsonrpc notifications (to handle close) --- src/app/www/js/filesystem_handler.js | 19 +++++----- src/wsfs/jsonrpc/request.c | 7 ++-- src/wsfs/jsonrpc/server.c | 52 +++++++++++++++++++++------- src/wsfs/jsonrpc/server.h | 9 ++++- src/wsfs/operation/close.c | 15 ++------ src/wsfs/operation/open.c | 1 + src/wsfs/server_protocol.c | 9 +++-- src/wsfs/status.c | 17 +++++++++ src/wsfs/status.h | 2 ++ 9 files changed, 92 insertions(+), 39 deletions(-) diff --git a/src/app/www/js/filesystem_handler.js b/src/app/www/js/filesystem_handler.js index 8b4d553..540a8af 100644 --- a/src/app/www/js/filesystem_handler.js +++ b/src/app/www/js/filesystem_handler.js @@ -53,7 +53,7 @@ class FileSystemHandler { const inode = request.params[0]; const handle = request.params[1]; const mode = request.params[2]; - result = this._fs.open(inode, handle, mode); + this._fs.close(inode, handle, mode); } break; case "read": @@ -69,14 +69,17 @@ class FileSystemHandler { break; } - if ("number" !== typeof(result)) { - response = {result: result, id: request.id}; + if ("number" == typeof(request.id)) + { + if ("number" !== typeof(result)) { + response = {result: result, id: request.id}; + } + else { + response = {error: {code: result}, id: request.id}; + } + console.log(response); + this._connection.send(JSON.stringify(response)); } - else { - response = {error: {code: result}, id: request.id}; - } - console.log(response); - this._connection.send(JSON.stringify(response)); } } catch (ex) { console.log(ex, message); } diff --git a/src/wsfs/jsonrpc/request.c b/src/wsfs/jsonrpc/request.c index 705fde9..eca02e2 100644 --- a/src/wsfs/jsonrpc/request.c +++ b/src/wsfs/jsonrpc/request.c @@ -35,7 +35,10 @@ json_t * wsfs_jsonrpc_request_create( json_object_set_new(request, "params", params); - json_object_set_new(request, "id", json_integer(id)); - + if (0 != id) + { + json_object_set_new(request, "id", json_integer(id)); + } + return request; } diff --git a/src/wsfs/jsonrpc/server.c b/src/wsfs/jsonrpc/server.c index 4f7c590..b3d0fc2 100644 --- a/src/wsfs/jsonrpc/server.c +++ b/src/wsfs/jsonrpc/server.c @@ -83,6 +83,11 @@ void wsfs_jsonrpc_server_invoke( { if (!method->invoke(method->user_data, request)) { + server->request.is_pending = false; + server->request.finished = NULL; + server->request.user_data = NULL; + server->request.id = 0; + finished(user_data, WSFS_BAD, NULL); } json_decref(request); @@ -97,9 +102,33 @@ void wsfs_jsonrpc_server_invoke( { finished(user_data, WSFS_BAD_BUSY, NULL); } - } +extern void wsfs_jsonrpc_server_notify( + struct wsfs_jsonrpc_server * server, + char const * method_name, + char const * param_info, + ... +) +{ + struct wsfs_jsonrpc_method const * method = wsfs_jsonrpc_server_getmethod(server, method_name); + if (NULL != method) + { + + va_list args; + va_start(args, param_info); + json_t * request = wsfs_jsonrpc_request_create(method_name, 0, param_info, args); + va_end(args); + if (NULL != request) + { + method->invoke(method->user_data, request); + json_decref(request); + } + } + +} + + void wsfs_jsonrpc_server_onresult( struct wsfs_jsonrpc_server * server, char const * message, @@ -108,20 +137,17 @@ void wsfs_jsonrpc_server_onresult( struct wsfs_jsonrpc_response response; wsfs_jsonrpc_response_init(&response, message, length); - if (-1 != response.id) - { - if ((server->request.is_pending) && (response.id == server->request.id)) - { - wsfs_jsonrpc_method_finished_fn * finished = server->request.finished; - void * user_data = server->request.user_data; + if ((server->request.is_pending) && (response.id == server->request.id)) + { + wsfs_jsonrpc_method_finished_fn * finished = server->request.finished; + void * user_data = server->request.user_data; - server->request.is_pending = false; - server->request.id = 0; - server->request.user_data = NULL; - server->request.finished = NULL; + server->request.is_pending = false; + server->request.id = 0; + server->request.user_data = NULL; + server->request.finished = NULL; - finished(user_data, response.status, response.result); - } + finished(user_data, response.status, response.result); } wsfs_jsonrpc_response_cleanup(&response); diff --git a/src/wsfs/jsonrpc/server.h b/src/wsfs/jsonrpc/server.h index 5acf6bf..6d05d2a 100644 --- a/src/wsfs/jsonrpc/server.h +++ b/src/wsfs/jsonrpc/server.h @@ -50,7 +50,14 @@ extern void wsfs_jsonrpc_server_invoke( struct wsfs_jsonrpc_server * server, wsfs_jsonrpc_method_finished_fn * finished, void * user_data, - char const * method, + char const * method_name, + char const * param_info, + ... +); + +extern void wsfs_jsonrpc_server_notify( + struct wsfs_jsonrpc_server * server, + char const * method_name, char const * param_info, ... ); diff --git a/src/wsfs/operation/close.c b/src/wsfs/operation/close.c index 637d9d3..b2d9385 100644 --- a/src/wsfs/operation/close.c +++ b/src/wsfs/operation/close.c @@ -7,16 +7,6 @@ #include "wsfs/jsonrpc/server.h" #include "wsfs/util.h" - -static void wsfs_operation_close_finished( - void * user_data, - wsfs_status status, - json_t const * WSFS_UNUSED_PARAM(result)) -{ - fuse_req_t request = (fuse_req_t) user_data; - fuse_reply_err(request, (WSFS_GOOD == status) ? 0 : ENOENT); -} - void wsfs_operation_close( fuse_req_t request, fuse_ino_t inode, @@ -26,7 +16,6 @@ void wsfs_operation_close( struct wsfs_jsonrpc_server * rpc = user_data->rpc; int handle = (int) (file_info->fh & INT_MAX); - wsfs_jsonrpc_server_invoke( - rpc, &wsfs_operation_close_finished, request, - "close", "iii", inode, handle, file_info->flags); + wsfs_jsonrpc_server_notify(rpc, "close", "iii", inode, handle, file_info->flags); + fuse_reply_err(request, 0); } diff --git a/src/wsfs/operation/open.c b/src/wsfs/operation/open.c index c68b69e..d3eb65a 100644 --- a/src/wsfs/operation/open.c +++ b/src/wsfs/operation/open.c @@ -6,6 +6,7 @@ #include "wsfs/jsonrpc/server.h" #include "wsfs/util.h" +#include "wsfs/status.h" static void wsfs_operation_open_finished( void * user_data, diff --git a/src/wsfs/server_protocol.c b/src/wsfs/server_protocol.c index 8914f2f..3113200 100644 --- a/src/wsfs/server_protocol.c +++ b/src/wsfs/server_protocol.c @@ -11,8 +11,8 @@ static int wsfs_server_protocol_callback( struct lws * wsi, enum lws_callback_reasons reason, void * WSFS_UNUSED_PARAM(user), - void * WSFS_UNUSED_PARAM(in), - size_t WSFS_UNUSED_PARAM(len)) + void * in, + size_t len) { struct lws_protocols const * ws_protocol = lws_get_protocol(wsi); struct wsfs_server_protocol * protocol = ws_protocol->user; @@ -56,6 +56,11 @@ static int wsfs_server_protocol_callback( } } break; + case LWS_CALLBACK_RECEIVE: + { + wsfs_jsonrpc_server_onresult(&protocol->rpc, in, len); + } + break; case LWS_CALLBACK_RAW_RX_FILE: { wsfs_filesystem_process_request(&protocol->filesystem); diff --git a/src/wsfs/status.c b/src/wsfs/status.c index 3806be4..f8a5e79 100644 --- a/src/wsfs/status.c +++ b/src/wsfs/status.c @@ -10,8 +10,25 @@ case WSFS_BAD_NOTIMPLEMENTED: return -ENOSYS; case WSFS_BAD_TIMEOUT: return -ETIMEDOUT; case WSFS_BAD_BUSY: return -ENOENT; + case WSFS_BAD_FORMAT: return -ENOENT; case WSFS_BAD_NOENTRY: return -ENOENT; case WSFS_BAD_NOACCESS: return -EACCES; default: return -ENOENT; } } + +char const * wsfs_status_tostring(wsfs_status status) +{ + switch(status) + { + case WSFS_GOOD: return "Good"; + case WSFS_BAD: return "Bad"; + case WSFS_BAD_NOTIMPLEMENTED: return "Bad (not implelemted)"; + case WSFS_BAD_TIMEOUT: return "Bad (timeout)"; + case WSFS_BAD_BUSY: return "Bad (busy)"; + case WSFS_BAD_FORMAT: return "Bad (format)"; + case WSFS_BAD_NOENTRY: return "Bad (no entry)"; + case WSFS_BAD_NOACCESS: return "Bad (no access)"; + default: return "Bad (unknown)"; + } +} diff --git a/src/wsfs/status.h b/src/wsfs/status.h index 2b9b870..06f6876 100644 --- a/src/wsfs/status.h +++ b/src/wsfs/status.h @@ -20,6 +20,8 @@ extern "C" { extern int wsfs_status_to_rc(wsfs_status status); +extern char const * wsfs_status_tostring(wsfs_status status); + #ifdef __cplusplus } #endif