diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b77e46..00daef9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ set(CMAKE_C_STANDARD 99) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(C_WARNINGS -Wall -Wextra) +set(C_WARNINGS -Wall -Wextra -Werror) set(CMAKE_POSITION_INDEPENDENT_CODE ON) include_directories( @@ -37,6 +37,8 @@ add_compile_options( "-pthread" ) +include(wf_timer) +include(wf_jsonrpc) include(webfuse_core) include(webfuse_adapter) include(webfuse_provider) diff --git a/cmake/unit_tests.cmake b/cmake/unit_tests.cmake index 1ff1be5..13b91f9 100644 --- a/cmake/unit_tests.cmake +++ b/cmake/unit_tests.cmake @@ -7,9 +7,17 @@ include(GoogleTest) pkg_check_modules(GMOCK gmock) add_executable(alltests + lib/wf/jsonrpc/test/wf/jsonrpc/test_is_request.cc + lib/wf/jsonrpc/test/wf/jsonrpc/test_request.cc + lib/wf/jsonrpc/test/wf/jsonrpc/test_is_response.cc + lib/wf/jsonrpc/test/wf/jsonrpc/test_response.cc + lib/wf/jsonrpc/test/wf/jsonrpc/test_server.cc + lib/wf/jsonrpc/test/wf/jsonrpc/test_proxy.cc + lib/wf/jsonrpc/test/wf/jsonrpc/test_response_parser.cc + lib/wf/timer/test/wf/timer/test_timepoint.cc + lib/wf/timer/test/wf/timer/test_timer.cc test/webfuse/utils/tempdir.cc test/webfuse/utils/file_utils.cc - test/webfuse/utils/msleep.cc test/webfuse/utils/die_if.cc test/webfuse/utils/timeout_watcher.cc test/webfuse/utils/path.c @@ -18,6 +26,7 @@ add_executable(alltests test/webfuse/mocks/mock_authenticator.cc test/webfuse/mocks/mock_request.cc test/webfuse/mocks/mock_provider_client.cc + test/webfuse//tests/core/test_util.cc test/webfuse/tests/core/test_container_of.cc test/webfuse/tests/core/test_string.cc test/webfuse/tests/core/test_slist.cc @@ -25,11 +34,8 @@ add_executable(alltests test/webfuse/tests/core/test_status.cc test/webfuse/tests/core/test_message.cc test/webfuse/tests/core/test_message_queue.cc - test/webfuse/tests/adapter/test_response_parser.cc test/webfuse/tests/adapter/test_server.cc test/webfuse/tests/adapter/test_server_config.cc - test/webfuse/tests/adapter/test_timepoint.cc - test/webfuse/tests/adapter/test_timer.cc test/webfuse/tests/adapter/test_credentials.cc test/webfuse/tests/adapter/test_authenticator.cc test/webfuse/tests/adapter/test_authenticators.cc @@ -37,13 +43,6 @@ add_executable(alltests test/webfuse/tests/adapter/test_uuid_mountpoint.cc test/webfuse/tests/adapter/test_uuid_mountpoint_factory.cc test/webfuse/tests/adapter/test_fuse_req.cc - test/webfuse/tests/adapter/jsonrpc/test_util.cc - test/webfuse/tests/adapter/jsonrpc/test_is_request.cc - test/webfuse/tests/adapter/jsonrpc/test_request.cc - test/webfuse/tests/adapter/jsonrpc/test_is_response.cc - test/webfuse/tests/adapter/jsonrpc/test_response.cc - test/webfuse/tests/adapter/jsonrpc/test_server.cc - test/webfuse/tests/adapter/jsonrpc/test_proxy.cc test/webfuse/tests/provider/test_url.cc test/webfuse/tests/provider/test_client_protocol.cc test/webfuse/tests/integration/test_integration.cc @@ -52,6 +51,10 @@ add_executable(alltests ) target_include_directories(alltests PRIVATE + lib/wf/jsonrpc/include + lib/wf/jsonrpc/src + lib/wf/timer/include + lib/wf/timer/src ${FUSE3_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS} ) @@ -65,6 +68,8 @@ target_link_libraries(alltests PUBLIC webfuse-adapter-static webfuse-provider-static webfuse-core + wf_jsonrpc + wf_timer ${FUSE3_LIBRARIES} ${LWS_LIBRARIES} ${JANSSON_LIBRARIES} diff --git a/cmake/webfuse_adapter.cmake b/cmake/webfuse_adapter.cmake index 269204d..bb0f723 100644 --- a/cmake/webfuse_adapter.cmake +++ b/cmake/webfuse_adapter.cmake @@ -19,25 +19,18 @@ add_library(webfuse-adapter-static STATIC lib/webfuse/adapter/impl/mountpoint_factory.c lib/webfuse/adapter/impl/uuid_mountpoint_factory.c lib/webfuse/adapter/impl/uuid_mountpoint.c - lib/webfuse/adapter/impl/time/timepoint.c - lib/webfuse/adapter/impl/time/timer.c - lib/webfuse/adapter/impl/time/timeout_manager.c lib/webfuse/adapter/impl/operation/lookup.c lib/webfuse/adapter/impl/operation/getattr.c lib/webfuse/adapter/impl/operation/readdir.c lib/webfuse/adapter/impl/operation/open.c lib/webfuse/adapter/impl/operation/close.c lib/webfuse/adapter/impl/operation/read.c - lib/webfuse/adapter/impl/jsonrpc/proxy.c - lib/webfuse/adapter/impl/jsonrpc/server.c - lib/webfuse/adapter/impl/jsonrpc/method.c - lib/webfuse/adapter/impl/jsonrpc/request.c - lib/webfuse/adapter/impl/jsonrpc/response.c - lib/webfuse/adapter/impl/jsonrpc/util.c ) target_include_directories(webfuse-adapter-static PRIVATE lib + lib/wf/timer/include + lib/wf/jsonrpc/include ${FUSE3_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS} ) @@ -70,7 +63,7 @@ set_target_properties(webfuse-adapter PROPERTIES SOVERSION 0) set_target_properties(webfuse-adapter PROPERTIES C_VISIBILITY_PRESET hidden) set_target_properties(webfuse-adapter PROPERTIES COMPILE_DEFINITIONS "WF_API=WF_EXPORT") -target_link_libraries(webfuse-adapter PRIVATE webfuse-adapter-static webfuse-core) +target_link_libraries(webfuse-adapter PRIVATE webfuse-adapter-static webfuse-core wf_jsonrpc wf_timer) file(WRITE "${PROJECT_BINARY_DIR}/libwebfuse-adapter.pc" "prefix=\"${CMAKE_INSTALL_PREFIX}\" diff --git a/cmake/webfuse_core.cmake b/cmake/webfuse_core.cmake index 52c7681..dab6223 100644 --- a/cmake/webfuse_core.cmake +++ b/cmake/webfuse_core.cmake @@ -8,10 +8,11 @@ add_library(webfuse-core STATIC lib/webfuse/core/string.c lib/webfuse/core/base64.c lib/webfuse/core/lws_log.c + lib/webfuse/core/json_util.c ) set_target_properties(webfuse-core PROPERTIES OUTPUT_NAME webfuse-core) -target_include_directories(webfuse-core PUBLIC lib) +target_include_directories(webfuse-core PUBLIC lib lib/wf/jsonrpc/include) set_target_properties(webfuse-core PROPERTIES C_VISIBILITY_PRESET hidden) install(DIRECTORY include/webfuse/core DESTINATION include/webfuse COMPONENT headers) diff --git a/cmake/webfuse_provider.cmake b/cmake/webfuse_provider.cmake index 5079cb1..a0c9e08 100644 --- a/cmake/webfuse_provider.cmake +++ b/cmake/webfuse_provider.cmake @@ -9,6 +9,7 @@ add_library(webfuse-provider-static STATIC lib/webfuse/provider/impl/provider.c lib/webfuse/provider/impl/request.c lib/webfuse/provider/impl/dirbuffer.c + lib/webfuse/provider/impl/credentials.c lib/webfuse/provider/impl/operation/lookup.c lib/webfuse/provider/impl/operation/getattr.c lib/webfuse/provider/impl/operation/readdir.c @@ -19,7 +20,11 @@ add_library(webfuse-provider-static STATIC set_target_properties(webfuse-provider-static PROPERTIES OUTPUT_NAME webfuse-provider) set_target_properties(webfuse-provider-static PROPERTIES C_VISIBILITY_PRESET hidden) -target_include_directories(webfuse-provider-static PUBLIC lib) +target_include_directories(webfuse-provider-static PUBLIC + lib + lib/wf/timer/include + lib/wf/jsonrpc/include +) add_library(webfuse-provider SHARED lib/webfuse/provider/api.c diff --git a/cmake/wf_jsonrpc.cmake b/cmake/wf_jsonrpc.cmake new file mode 100644 index 0000000..fae8d74 --- /dev/null +++ b/cmake/wf_jsonrpc.cmake @@ -0,0 +1,24 @@ +# wf_jsonrpc + +add_library(wf_jsonrpc STATIC + lib/wf/jsonrpc/src/wf/jsonrpc/api.c + lib/wf/jsonrpc/src/wf/jsonrpc/impl/proxy.c + lib/wf/jsonrpc/src/wf/jsonrpc/impl/server.c + lib/wf/jsonrpc/src/wf/jsonrpc/impl/method.c + lib/wf/jsonrpc/src/wf/jsonrpc/impl/request.c + lib/wf/jsonrpc/src/wf/jsonrpc/impl/response.c + lib/wf/jsonrpc/src/wf/jsonrpc/impl/error.c +) + +target_link_libraries(wf_jsonrpc PUBLIC wf_timer) + +target_include_directories(wf_jsonrpc PRIVATE + lib/wf/timer/include + lib/wf/jsonrpc/src +) + +target_include_directories(wf_jsonrpc PUBLIC + lib/wf/jsonrpc/include +) + +set_target_properties(wf_jsonrpc PROPERTIES C_VISIBILITY_PRESET hidden) diff --git a/cmake/wf_timer.cmake b/cmake/wf_timer.cmake new file mode 100644 index 0000000..8bdecf2 --- /dev/null +++ b/cmake/wf_timer.cmake @@ -0,0 +1,18 @@ +# timer + +add_library(wf_timer STATIC + lib/wf/timer/src/wf/timer/api.c + lib/wf/timer/src/wf/timer/impl/manager.c + lib/wf/timer/src/wf/timer/impl/timepoint.c + lib/wf/timer/src/wf/timer/impl/timer.c +) + +target_include_directories(wf_timer PRIVATE + lib/wf/timer/src +) + +target_include_directories(wf_timer PUBLIC + lib/wf/timer/include +) + +set_target_properties(wf_timer PROPERTIES C_VISIBILITY_PRESET hidden) diff --git a/include/webfuse/provider/client_config.h b/include/webfuse/provider/client_config.h index 73775f1..0c79dd7 100644 --- a/include/webfuse/provider/client_config.h +++ b/include/webfuse/provider/client_config.h @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" @@ -227,6 +228,17 @@ extern WFP_API void wfp_client_config_set_onread( struct wfp_client_config * config, wfp_read_fn * handler); +//------------------------------------------------------------------------------ +/// \brief Enabled authentication. +/// +/// \param config pointer to client configuration +/// \param get_credentials pointer to function providing credentials when +// needed. +//------------------------------------------------------------------------------ +extern WFP_API void wfp_client_config_enable_authentication( + struct wfp_client_config * config, + wfp_get_credentials_fn * get_credentials); + #ifdef __cplusplus } #endif diff --git a/include/webfuse/provider/credentials.h b/include/webfuse/provider/credentials.h new file mode 100644 index 0000000..a6b0806 --- /dev/null +++ b/include/webfuse/provider/credentials.h @@ -0,0 +1,30 @@ +#ifndef WF_PROVIDER_CREDENTIALS_H +#define WF_PROVIDER_CREDENTIALS_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wfp_credentials; + +typedef void wfp_get_credentials_fn( + struct wfp_credentials * credentials, + void * user_data); + +extern WFP_API void wfp_credentials_set_type( + struct wfp_credentials * credentials, + char const * type); + +extern WFP_API void wfp_credentials_add( + struct wfp_credentials * credentials, + char const * key, + char const * value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/webfuse_provider.h b/include/webfuse_provider.h index 7af3934..19afad2 100644 --- a/include/webfuse_provider.h +++ b/include/webfuse_provider.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/lib/webfuse/adapter/impl/jsonrpc/method.h b/lib/webfuse/adapter/impl/jsonrpc/method.h deleted file mode 100644 index 739f692..0000000 --- a/lib/webfuse/adapter/impl/jsonrpc/method.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_JSONRPC_METHOD_H -#define WF_ADAPTER_IMPL_JSONRPC_METHOD_H - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -struct wf_impl_jsonrpc_request; - -typedef void wf_impl_jsonrpc_method_invoke_fn( - struct wf_impl_jsonrpc_request * request, - char const * method_name, - json_t * params, - void * user_data); - -struct wf_impl_jsonrpc_method -{ - struct wf_impl_jsonrpc_method * next; - char * name; - wf_impl_jsonrpc_method_invoke_fn * invoke; - void * user_data; -}; - -extern struct wf_impl_jsonrpc_method * wf_impl_jsonrpc_method_create( - char const * method_name, - wf_impl_jsonrpc_method_invoke_fn * invoke, - void * user_data); - -extern void wf_impl_jsonrpc_method_dispose( - struct wf_impl_jsonrpc_method * method); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/lib/webfuse/adapter/impl/jsonrpc/proxy.c b/lib/webfuse/adapter/impl/jsonrpc/proxy.c deleted file mode 100644 index ec0da2e..0000000 --- a/lib/webfuse/adapter/impl/jsonrpc/proxy.c +++ /dev/null @@ -1,194 +0,0 @@ -#include "webfuse/adapter/impl/jsonrpc/proxy.h" -#include - -#include "webfuse/adapter/impl/jsonrpc/response.h" - -static void wf_impl_jsonrpc_proxy_timeout( - struct wf_impl_timer * timer) -{ - struct wf_impl_jsonrpc_proxy * proxy = timer->user_data; - - if (proxy->request.is_pending) - { - wf_impl_jsonrpc_proxy_finished_fn * finished = proxy->request.finished; - void * user_data = proxy->request.user_data; - - proxy->request.is_pending = false; - proxy->request.id = 0; - proxy->request.user_data = NULL; - proxy->request.finished = NULL; - wf_impl_timer_cancel(&proxy->request.timer); - - finished(user_data, WF_BAD_TIMEOUT, NULL); - } -} - -static json_t * wf_impl_jsonrpc_request_create( - char const * method, - int id, - char const * param_info, - va_list args) -{ - json_t * request = json_object(); - json_object_set_new(request, "method", json_string(method)); - json_t * params = json_array(); - - for (char const * param_type = param_info; '\0' != *param_type; param_type++) - { - switch(*param_type) - { - case 's': - { - char const * const value = va_arg(args, char const *); - json_array_append_new(params, json_string(value)); - } - break; - case 'i': - { - int const value = va_arg(args, int); - json_array_append_new(params, json_integer(value)); - } - break; - default: - fprintf(stderr, "fatal: unknown param_type '%c'\n", *param_type); - json_decref(params); - json_decref(request); - return NULL; - } - } - - - json_object_set_new(request, "params", params); - if (0 != id) - { - json_object_set_new(request, "id", json_integer(id)); - } - - return request; -} - -void wf_impl_jsonrpc_proxy_init( - struct wf_impl_jsonrpc_proxy * proxy, - struct wf_impl_timeout_manager * timeout_manager, - int timeout, - wf_impl_jsonrpc_send_fn * send, - void * user_data) -{ - proxy->send = send; - proxy->timeout = timeout; - proxy->user_data = user_data; - proxy->request.is_pending = false; - - wf_impl_timer_init(&proxy->request.timer, timeout_manager); -} - -void wf_impl_jsonrpc_proxy_cleanup( - struct wf_impl_jsonrpc_proxy * proxy) -{ - if (proxy->request.is_pending) - { - void * user_data = proxy->request.user_data; - wf_impl_jsonrpc_proxy_finished_fn * finished = proxy->request.finished; - - proxy->request.is_pending = false; - proxy->request.finished = NULL; - proxy->request.user_data = NULL; - proxy->request.id = 0; - wf_impl_timer_cancel(&proxy->request.timer); - - finished(user_data, WF_BAD, NULL); - } - - wf_impl_timer_cleanup(&proxy->request.timer); -} - -void wf_impl_jsonrpc_proxy_invoke( - struct wf_impl_jsonrpc_proxy * proxy, - wf_impl_jsonrpc_proxy_finished_fn * finished, - void * user_data, - char const * method_name, - char const * param_info, - ... -) -{ - if (!proxy->request.is_pending) - { - proxy->request.is_pending = true; - proxy->request.finished = finished; - proxy->request.user_data = user_data; - proxy->request.id = 42; - wf_impl_timer_start(&proxy->request.timer, wf_impl_timepoint_in_msec(proxy->timeout), - &wf_impl_jsonrpc_proxy_timeout, proxy); - - va_list args; - va_start(args, param_info); - json_t * request = wf_impl_jsonrpc_request_create(method_name, proxy->request.id, param_info, args); - va_end(args); - - bool const is_send = ((NULL != request) && (proxy->send(request, proxy->user_data))); - if (!is_send) - { - proxy->request.is_pending = false; - proxy->request.finished = NULL; - proxy->request.user_data = NULL; - proxy->request.id = 0; - wf_impl_timer_cancel(&proxy->request.timer); - - finished(user_data, WF_BAD, NULL); - - } - - if (NULL != request) - { - json_decref(request); - } - } - else - { - finished(user_data, WF_BAD_BUSY, NULL); - } -} - -extern void wf_impl_jsonrpc_proxy_notify( - struct wf_impl_jsonrpc_proxy * proxy, - char const * method_name, - char const * param_info, - ... -) -{ - va_list args; - va_start(args, param_info); - json_t * request = wf_impl_jsonrpc_request_create(method_name, 0, param_info, args); - va_end(args); - if (NULL != request) - { - proxy->send(request, proxy->user_data); - json_decref(request); - } -} - - -void wf_impl_jsonrpc_proxy_onresult( - struct wf_impl_jsonrpc_proxy * proxy, - json_t * message) -{ - struct wf_impl_jsonrpc_response response; - wf_impl_jsonrpc_response_init(&response, message); - - if ((proxy->request.is_pending) && (response.id == proxy->request.id)) - { - wf_impl_jsonrpc_proxy_finished_fn * finished = proxy->request.finished; - void * user_data = proxy->request.user_data; - - proxy->request.is_pending = false; - proxy->request.id = 0; - proxy->request.user_data = NULL; - proxy->request.finished = NULL; - wf_impl_timer_cancel(&proxy->request.timer); - - finished(user_data, response.status, response.result); - } - - wf_impl_jsonrpc_response_cleanup(&response); -} - diff --git a/lib/webfuse/adapter/impl/jsonrpc/proxy.h b/lib/webfuse/adapter/impl/jsonrpc/proxy.h deleted file mode 100644 index 0433747..0000000 --- a/lib/webfuse/adapter/impl/jsonrpc/proxy.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_JSONRPC_PROXY_H -#define WF_ADAPTER_IMPL_JSONRPC_PROXY_H - -#ifndef __cplusplus -#include -#include -#include -#else -#include -#include -using std::size_t; -#endif - -#include -#include "webfuse/adapter/impl/jsonrpc/send_fn.h" -#include "webfuse/adapter/impl/time/timeout_manager.h" -#include "webfuse/adapter/impl/time/timer.h" -#include "webfuse/core/status.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void wf_impl_jsonrpc_proxy_finished_fn( - void * user_data, - wf_status status, - struct json_t const * result); - - -struct wf_impl_jsonrpc_request -{ - bool is_pending; - wf_impl_jsonrpc_proxy_finished_fn * finished; - void * user_data; - int id; - struct wf_impl_timer timer; -}; - -struct wf_impl_jsonrpc_proxy -{ - struct wf_impl_jsonrpc_request request; - int timeout; - wf_impl_jsonrpc_send_fn * send; - void * user_data; -}; - -extern void wf_impl_jsonrpc_proxy_init( - struct wf_impl_jsonrpc_proxy * proxy, - struct wf_impl_timeout_manager * manager, - int timeout, - wf_impl_jsonrpc_send_fn * send, - void * user_data); - -extern void wf_impl_jsonrpc_proxy_cleanup( - struct wf_impl_jsonrpc_proxy * proxy); - -extern void wf_impl_jsonrpc_proxy_invoke( - struct wf_impl_jsonrpc_proxy * proxy, - wf_impl_jsonrpc_proxy_finished_fn * finished, - void * user_data, - char const * method_name, - char const * param_info, - ... -); - -extern void wf_impl_jsonrpc_proxy_notify( - struct wf_impl_jsonrpc_proxy * proxy, - char const * method_name, - char const * param_info, - ... -); - -extern void wf_impl_jsonrpc_proxy_onresult( - struct wf_impl_jsonrpc_proxy * proxy, - json_t * message); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/lib/webfuse/adapter/impl/jsonrpc/request.h b/lib/webfuse/adapter/impl/jsonrpc/request.h deleted file mode 100644 index 7d26228..0000000 --- a/lib/webfuse/adapter/impl/jsonrpc/request.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_JSONRPC_REQUEST_H -#define WF_ADAPTER_IMPL_JSONRPC_REQUEST_H - -#ifndef __cplusplus -#include -#include -#include -#else -#include -#include -using std::size_t; -#endif - -#include -#include "webfuse/core/status.h" -#include "webfuse/adapter/impl/jsonrpc/send_fn.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -struct wf_impl_jsonrpc_request; - -extern bool wf_impl_jsonrpc_is_request( - json_t * message); - -extern struct wf_impl_jsonrpc_request * wf_impl_jsonrpc_request_create( - int id, - wf_impl_jsonrpc_send_fn * send, - void * user_data); - -extern void wf_impl_jsonrpc_request_dispose( - struct wf_impl_jsonrpc_request * request); - -extern void * wf_impl_jsonrpc_request_get_userdata( - struct wf_impl_jsonrpc_request * request); - -extern void wf_impl_jsonrpc_respond( - struct wf_impl_jsonrpc_request * request, - json_t * result); - -extern void wf_impl_jsonrpc_respond_error( - struct wf_impl_jsonrpc_request * request, - wf_status status); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/webfuse/adapter/impl/jsonrpc/response.h b/lib/webfuse/adapter/impl/jsonrpc/response.h deleted file mode 100644 index d53f667..0000000 --- a/lib/webfuse/adapter/impl/jsonrpc/response.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_JSONRPC_RESPONSE_H -#define WF_ADAPTER_IMPL_JSONRPC_RESPONSE_H - -#ifndef __cplusplus -#include -#include -#else -#include -using std::size_t; -#endif - -#include -#include "webfuse/core/status.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct wf_impl_jsonrpc_response -{ - wf_status status; - int id; - json_t * result; -}; - -extern bool wf_impl_jsonrpc_is_response( - json_t * message); - -extern void wf_impl_jsonrpc_response_init( - struct wf_impl_jsonrpc_response * response, - json_t * message); - -extern void wf_impl_jsonrpc_response_cleanup( - struct wf_impl_jsonrpc_response * response); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/lib/webfuse/adapter/impl/jsonrpc/server.c b/lib/webfuse/adapter/impl/jsonrpc/server.c deleted file mode 100644 index 717d71b..0000000 --- a/lib/webfuse/adapter/impl/jsonrpc/server.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "webfuse/adapter/impl/jsonrpc/server.h" -#include "webfuse/adapter/impl/jsonrpc/method.h" -#include "webfuse/adapter/impl/jsonrpc/request.h" -#include "webfuse/core/util.h" - -#include - -void wf_impl_jsonrpc_server_init( - struct wf_impl_jsonrpc_server * server) -{ - server->methods = NULL; -} - -void wf_impl_jsonrpc_server_cleanup( - struct wf_impl_jsonrpc_server * server) -{ - struct wf_impl_jsonrpc_method * current = server->methods; - while (NULL != current) - { - struct wf_impl_jsonrpc_method * next = current->next; - wf_impl_jsonrpc_method_dispose(current); - current = next; - } - server->methods = NULL; -} - -void wf_impl_jsonrpc_server_add( - struct wf_impl_jsonrpc_server * server, - char const * method_name, - wf_impl_jsonrpc_method_invoke_fn * invoke, - void * user_data) -{ - struct wf_impl_jsonrpc_method * method = wf_impl_jsonrpc_method_create(method_name, invoke, user_data); - method->next = server->methods; - server->methods = method; -} - -static void wf_impl_jsonrpc_server_invalid_method_invoke( - struct wf_impl_jsonrpc_request * request, - char const * WF_UNUSED_PARAM(method_name), - json_t * WF_UNUSED_PARAM(params), - void * WF_UNUSED_PARAM(user_data)) -{ - wf_impl_jsonrpc_respond_error(request, WF_BAD_NOTIMPLEMENTED); -} - -static struct wf_impl_jsonrpc_method const wf_impl_jsonrpc_server_invalid_method = -{ - .next = NULL, - .name = "", - .invoke = &wf_impl_jsonrpc_server_invalid_method_invoke, - .user_data = NULL -}; - -static struct wf_impl_jsonrpc_method const * wf_impl_jsonrpc_server_get_method( - struct wf_impl_jsonrpc_server * server, - char const * method_name) -{ - struct wf_impl_jsonrpc_method const * current = server->methods; - while (NULL != current) - { - if (0 == strcmp(method_name, current->name)) - { - return current; - } - - current = current->next; - } - - return &wf_impl_jsonrpc_server_invalid_method; -} - -void wf_impl_jsonrpc_server_process( - struct wf_impl_jsonrpc_server * server, - json_t * request_data, - wf_impl_jsonrpc_send_fn * send, - void * user_data) -{ - json_t * method_holder = json_object_get(request_data, "method"); - json_t * params = json_object_get(request_data, "params"); - json_t * id_holder = json_object_get(request_data, "id"); - - if (json_is_string(method_holder) && - (json_is_array(params) || (json_is_object(params))) && - json_is_integer(id_holder)) - { - char const * method_name = json_string_value(method_holder); - int id = json_integer_value(id_holder); - struct wf_impl_jsonrpc_request * request = wf_impl_jsonrpc_request_create(id, send, user_data); - struct wf_impl_jsonrpc_method const * method = wf_impl_jsonrpc_server_get_method(server, method_name); - - method->invoke(request, method_name, params, method->user_data); - } -} - diff --git a/lib/webfuse/adapter/impl/jsonrpc/server.h b/lib/webfuse/adapter/impl/jsonrpc/server.h deleted file mode 100644 index 51c827b..0000000 --- a/lib/webfuse/adapter/impl/jsonrpc/server.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_JSONRPC_SERVER_H -#define WF_ADAPTER_IMPL_JSONRPC_SERVER_H - -#ifndef __cplusplus -#include -#include -#else -#include -#endif - -#include -#include "webfuse/core/status.h" -#include "webfuse/adapter/impl/jsonrpc/send_fn.h" -#include "webfuse/adapter/impl/jsonrpc/method.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -struct wf_impl_jsonrpc_server -{ - struct wf_impl_jsonrpc_method * methods; -}; - -extern void wf_impl_jsonrpc_server_init( - struct wf_impl_jsonrpc_server * server); - -extern void wf_impl_jsonrpc_server_cleanup( - struct wf_impl_jsonrpc_server * server); - -extern void wf_impl_jsonrpc_server_add( - struct wf_impl_jsonrpc_server * server, - char const * method_name, - wf_impl_jsonrpc_method_invoke_fn * invoke, - void * user_data); - -extern void wf_impl_jsonrpc_server_process( - struct wf_impl_jsonrpc_server * server, - json_t * request, - wf_impl_jsonrpc_send_fn * send, - void * user_data); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/webfuse/adapter/impl/jsonrpc/util.c b/lib/webfuse/adapter/impl/jsonrpc/util.c deleted file mode 100644 index 439eddb..0000000 --- a/lib/webfuse/adapter/impl/jsonrpc/util.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "webfuse/adapter/impl/jsonrpc/util.h" - -int wf_impl_json_get_int(json_t const * object, char const * key, int default_value) -{ - int result = default_value; - - json_t * holder = json_object_get(object, key); - if ((NULL != holder) && (json_is_integer(holder))) - { - result = json_integer_value(holder); - } - - return result; -} \ No newline at end of file diff --git a/lib/webfuse/adapter/impl/jsonrpc/util.h b/lib/webfuse/adapter/impl/jsonrpc/util.h deleted file mode 100644 index 0d5c6ab..0000000 --- a/lib/webfuse/adapter/impl/jsonrpc/util.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_JSON_UTIL_H -#define WF_ADAPTER_IMPL_JSON_UTIL_H - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -extern int wf_impl_json_get_int(json_t const * object, char const * key, int default_value); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/webfuse/adapter/impl/operation/close.c b/lib/webfuse/adapter/impl/operation/close.c index ca63a8e..dcb65fb 100644 --- a/lib/webfuse/adapter/impl/operation/close.c +++ b/lib/webfuse/adapter/impl/operation/close.c @@ -4,7 +4,7 @@ #include #include -#include "webfuse/adapter/impl/jsonrpc/proxy.h" +#include "wf/jsonrpc/proxy.h" #include "webfuse/core/util.h" void wf_impl_operation_close( @@ -13,12 +13,12 @@ void wf_impl_operation_close( struct fuse_file_info * file_info) { struct wf_impl_operations_context * user_data = fuse_req_userdata(request); - struct wf_impl_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); + struct wf_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); if (NULL != rpc) { int handle = (int) (file_info->fh & INT_MAX); - wf_impl_jsonrpc_proxy_notify(rpc, "close", "siii", user_data->name, inode, handle, file_info->flags); + wf_jsonrpc_proxy_notify(rpc, "close", "siii", user_data->name, inode, handle, file_info->flags); } fuse_reply_err(request, 0); diff --git a/lib/webfuse/adapter/impl/operation/getattr.c b/lib/webfuse/adapter/impl/operation/getattr.c index cef8eac..767b06c 100644 --- a/lib/webfuse/adapter/impl/operation/getattr.c +++ b/lib/webfuse/adapter/impl/operation/getattr.c @@ -7,8 +7,8 @@ #include #include -#include "webfuse/adapter/impl/jsonrpc/proxy.h" -#include "webfuse/adapter/impl/jsonrpc/util.h" +#include "wf/jsonrpc/proxy.h" +#include "webfuse/core/json_util.h" #include "webfuse/core/util.h" struct wf_impl_operation_getattr_context @@ -22,16 +22,17 @@ struct wf_impl_operation_getattr_context static void wf_impl_operation_getattr_finished( void * user_data, - wf_status status, - json_t const * data) + json_t const * result, + json_t const * error) { + wf_status status = wf_impl_jsonrpc_get_status(error); struct wf_impl_operation_getattr_context * context = user_data; struct stat buffer; - if (NULL != data) + if (NULL != result) { - json_t * mode_holder = json_object_get(data, "mode"); - json_t * type_holder = json_object_get(data, "type"); + json_t * mode_holder = json_object_get(result, "mode"); + json_t * type_holder = json_object_get(result, "type"); if ((NULL != mode_holder) && (json_is_integer(mode_holder)) && (NULL != type_holder) && (json_is_string(type_holder))) { @@ -52,10 +53,10 @@ static void wf_impl_operation_getattr_finished( buffer.st_uid = context->uid; buffer.st_gid = context->gid; buffer.st_nlink = 1; - buffer.st_size = wf_impl_json_get_int(data, "size", 0); - buffer.st_atime = wf_impl_json_get_int(data, "atime", 0); - buffer.st_mtime = wf_impl_json_get_int(data, "mtime", 0); - buffer.st_ctime = wf_impl_json_get_int(data, "ctime", 0); + buffer.st_size = wf_impl_json_get_int(result, "size", 0); + buffer.st_atime = wf_impl_json_get_int(result, "atime", 0); + buffer.st_mtime = wf_impl_json_get_int(result, "mtime", 0); + buffer.st_ctime = wf_impl_json_get_int(result, "ctime", 0); } else { @@ -82,7 +83,7 @@ void wf_impl_operation_getattr ( { struct fuse_ctx const * context = fuse_req_ctx(request); struct wf_impl_operations_context * user_data = fuse_req_userdata(request); - struct wf_impl_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); + struct wf_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); if (NULL != rpc) { @@ -93,7 +94,7 @@ void wf_impl_operation_getattr ( getattr_context->gid = context->gid; getattr_context->timeout = user_data->timeout; - wf_impl_jsonrpc_proxy_invoke(rpc, &wf_impl_operation_getattr_finished, getattr_context, "getattr", "si", user_data->name, inode); + wf_jsonrpc_proxy_invoke(rpc, &wf_impl_operation_getattr_finished, getattr_context, "getattr", "si", user_data->name, inode); } else { diff --git a/lib/webfuse/adapter/impl/operation/lookup.c b/lib/webfuse/adapter/impl/operation/lookup.c index 3f0cd3b..596f7e4 100644 --- a/lib/webfuse/adapter/impl/operation/lookup.c +++ b/lib/webfuse/adapter/impl/operation/lookup.c @@ -10,8 +10,8 @@ #include -#include "webfuse/adapter/impl/jsonrpc/proxy.h" -#include "webfuse/adapter/impl/jsonrpc/util.h" +#include "wf/jsonrpc/proxy.h" +#include "webfuse/core/json_util.h" #include "webfuse/core/util.h" struct wf_impl_operation_lookup_context @@ -24,18 +24,19 @@ struct wf_impl_operation_lookup_context static void wf_impl_operation_lookup_finished( void * user_data, - wf_status status, - json_t const * data + json_t const * result, + json_t const * error ) { + wf_status status = wf_impl_jsonrpc_get_status(error); struct wf_impl_operation_lookup_context * context = user_data; struct fuse_entry_param buffer; - if (NULL != data) + if (NULL != result) { - json_t * inode_holder = json_object_get(data, "inode"); - json_t * mode_holder = json_object_get(data, "mode"); - json_t * type_holder = json_object_get(data, "type"); + json_t * inode_holder = json_object_get(result, "inode"); + json_t * mode_holder = json_object_get(result, "mode"); + json_t * type_holder = json_object_get(result, "type"); if ((NULL != inode_holder) && (json_is_integer(inode_holder)) && (NULL != mode_holder) && (json_is_integer(mode_holder)) && (NULL != type_holder) && (json_is_string(type_holder))) @@ -61,10 +62,10 @@ static void wf_impl_operation_lookup_finished( buffer.attr.st_uid = context->uid; buffer.attr.st_gid = context->gid; buffer.attr.st_nlink = 1; - buffer.attr.st_size = wf_impl_json_get_int(data, "size", 0); - buffer.attr.st_atime = wf_impl_json_get_int(data, "atime", 0); - buffer.attr.st_mtime = wf_impl_json_get_int(data, "mtime", 0); - buffer.attr.st_ctime = wf_impl_json_get_int(data, "ctime", 0); + buffer.attr.st_size = wf_impl_json_get_int(result, "size", 0); + buffer.attr.st_atime = wf_impl_json_get_int(result, "atime", 0); + buffer.attr.st_mtime = wf_impl_json_get_int(result, "mtime", 0); + buffer.attr.st_ctime = wf_impl_json_get_int(result, "ctime", 0); } else { @@ -91,7 +92,7 @@ void wf_impl_operation_lookup ( { struct fuse_ctx const * context = fuse_req_ctx(request); struct wf_impl_operations_context * user_data = fuse_req_userdata(request); - struct wf_impl_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); + struct wf_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); if (NULL != rpc) { @@ -101,7 +102,7 @@ void wf_impl_operation_lookup ( lookup_context->gid = context->gid; lookup_context->timeout = user_data->timeout; - wf_impl_jsonrpc_proxy_invoke(rpc, &wf_impl_operation_lookup_finished, lookup_context, "lookup", "sis", user_data->name, (int) (parent & INT_MAX), name); + wf_jsonrpc_proxy_invoke(rpc, &wf_impl_operation_lookup_finished, lookup_context, "lookup", "sis", user_data->name, (int) (parent & INT_MAX), name); } else { diff --git a/lib/webfuse/adapter/impl/operation/open.c b/lib/webfuse/adapter/impl/operation/open.c index e82b865..0c10c45 100644 --- a/lib/webfuse/adapter/impl/operation/open.c +++ b/lib/webfuse/adapter/impl/operation/open.c @@ -4,15 +4,17 @@ #include #include -#include "webfuse/adapter/impl/jsonrpc/proxy.h" +#include "wf/jsonrpc/proxy.h" #include "webfuse/core/util.h" #include "webfuse/core/status.h" +#include "webfuse/core/json_util.h" static void wf_impl_operation_open_finished( void * user_data, - wf_status status, - json_t const * result) + json_t const * result, + json_t const * error) { + wf_status status = wf_impl_jsonrpc_get_status(error); fuse_req_t request = user_data; struct fuse_file_info file_info; memset(&file_info, 0, sizeof(struct fuse_file_info)); @@ -47,11 +49,11 @@ void wf_impl_operation_open( struct fuse_file_info * file_info) { struct wf_impl_operations_context * user_data = fuse_req_userdata(request); - struct wf_impl_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); + struct wf_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); if (NULL != rpc) { - wf_impl_jsonrpc_proxy_invoke(rpc, &wf_impl_operation_open_finished, request, "open", "sii", user_data->name, inode, file_info->flags); + wf_jsonrpc_proxy_invoke(rpc, &wf_impl_operation_open_finished, request, "open", "sii", user_data->name, inode, file_info->flags); } else { diff --git a/lib/webfuse/adapter/impl/operation/read.c b/lib/webfuse/adapter/impl/operation/read.c index ec434c5..87330fc 100644 --- a/lib/webfuse/adapter/impl/operation/read.c +++ b/lib/webfuse/adapter/impl/operation/read.c @@ -5,8 +5,9 @@ #include #include -#include "webfuse/adapter/impl/jsonrpc/proxy.h" +#include "wf/jsonrpc/proxy.h" #include "webfuse/core/base64.h" +#include "webfuse/core/json_util.h" #define WF_MAX_READ_LENGTH 4096 @@ -38,17 +39,21 @@ static char * wf_impl_fill_buffer( return buffer; } -static void wf_impl_operation_read_finished(void * user_data, wf_status status, json_t const * data) +static void wf_impl_operation_read_finished( + void * user_data, + json_t const * result, + json_t const * error) { + wf_status status = wf_impl_jsonrpc_get_status(error); fuse_req_t request = user_data; char * buffer = NULL; size_t length = 0; - if (NULL != data) + if (NULL != result) { - json_t * data_holder = json_object_get(data, "data"); - json_t * format_holder = json_object_get(data, "format"); - json_t * count_holder = json_object_get(data, "count"); + json_t * data_holder = json_object_get(result, "data"); + json_t * format_holder = json_object_get(result, "format"); + json_t * count_holder = json_object_get(result, "count"); if (json_is_string(data_holder) && json_is_string(format_holder) && @@ -87,13 +92,13 @@ void wf_impl_operation_read( struct fuse_file_info * file_info) { struct wf_impl_operations_context * user_data = fuse_req_userdata(request); - struct wf_impl_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); + struct wf_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); if (NULL != rpc) { int const length = (size <= WF_MAX_READ_LENGTH) ? (int) size : WF_MAX_READ_LENGTH; int handle = (file_info->fh & INT_MAX); - wf_impl_jsonrpc_proxy_invoke(rpc, &wf_impl_operation_read_finished, request, "read", "siiii", user_data->name, (int) inode, handle, (int) offset, length); + wf_jsonrpc_proxy_invoke(rpc, &wf_impl_operation_read_finished, request, "read", "siiii", user_data->name, (int) inode, handle, (int) offset, length); } else { diff --git a/lib/webfuse/adapter/impl/operation/readdir.c b/lib/webfuse/adapter/impl/operation/readdir.c index 85cfd5b..f188084 100644 --- a/lib/webfuse/adapter/impl/operation/readdir.c +++ b/lib/webfuse/adapter/impl/operation/readdir.c @@ -8,8 +8,9 @@ #include #include -#include "webfuse/adapter/impl/jsonrpc/proxy.h" +#include "wf/jsonrpc/proxy.h" #include "webfuse/core/util.h" +#include "webfuse/core/json_util.h" #define WF_DIRBUFFER_INITIAL_SIZE 1024 @@ -73,9 +74,10 @@ static size_t wf_impl_min(size_t a, size_t b) static void wf_impl_operation_readdir_finished( void * user_data, - wf_status status, - json_t const * result) + json_t const * result, + json_t const * error) { + wf_status status = wf_impl_jsonrpc_get_status(error); struct wf_impl_operation_readdir_context * context = user_data; struct wf_impl_dirbuffer buffer; @@ -137,16 +139,16 @@ void wf_impl_operation_readdir ( struct fuse_file_info * WF_UNUSED_PARAM(file_info)) { struct wf_impl_operations_context * user_data = fuse_req_userdata(request); - struct wf_impl_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); + struct wf_jsonrpc_proxy * rpc = wf_impl_operations_context_get_proxy(user_data); if (NULL != rpc) { - struct wf_impl_operation_readdir_context * readdir_context = malloc(sizeof(struct wf_impl_operation_readdir_context)); - readdir_context->request = request; - readdir_context->size = size; - readdir_context->offset = offset; + struct wf_impl_operation_readdir_context * readdir_context = malloc(sizeof(struct wf_impl_operation_readdir_context)); + readdir_context->request = request; + readdir_context->size = size; + readdir_context->offset = offset; - wf_impl_jsonrpc_proxy_invoke(rpc, &wf_impl_operation_readdir_finished, readdir_context, "readdir", "si", user_data->name, inode); + wf_jsonrpc_proxy_invoke(rpc, &wf_impl_operation_readdir_finished, readdir_context, "readdir", "si", user_data->name, inode); } else { diff --git a/lib/webfuse/adapter/impl/operations.c b/lib/webfuse/adapter/impl/operations.c index 393ab99..9ddad3e 100644 --- a/lib/webfuse/adapter/impl/operations.c +++ b/lib/webfuse/adapter/impl/operations.c @@ -3,15 +3,15 @@ #include "webfuse/adapter/impl/session.h" #include -struct wf_impl_jsonrpc_proxy * wf_impl_operations_context_get_proxy( +struct wf_jsonrpc_proxy * wf_impl_operations_context_get_proxy( struct wf_impl_operations_context * context) { - struct wf_impl_jsonrpc_proxy * proxy = NULL; + struct wf_jsonrpc_proxy * proxy = NULL; struct wf_impl_session * session = context->session; if (NULL != session) { - proxy = &session->rpc; + proxy = session->rpc; } return proxy; diff --git a/lib/webfuse/adapter/impl/operations.h b/lib/webfuse/adapter/impl/operations.h index debe4fa..4d23db2 100644 --- a/lib/webfuse/adapter/impl/operations.h +++ b/lib/webfuse/adapter/impl/operations.h @@ -8,7 +8,7 @@ extern "C" { #endif struct wf_impl_session; -struct wf_impl_jsonrpc_proxy; +struct wf_jsonrpc_proxy; struct wf_impl_operations_context { @@ -49,7 +49,7 @@ extern void wf_impl_operation_read( fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi); -extern struct wf_impl_jsonrpc_proxy * wf_impl_operations_context_get_proxy( +extern struct wf_jsonrpc_proxy * wf_impl_operations_context_get_proxy( struct wf_impl_operations_context * context); #ifdef __cplusplus diff --git a/lib/webfuse/adapter/impl/server_protocol.c b/lib/webfuse/adapter/impl/server_protocol.c index 74d4631..9085a14 100644 --- a/lib/webfuse/adapter/impl/server_protocol.c +++ b/lib/webfuse/adapter/impl/server_protocol.c @@ -9,8 +9,12 @@ #include "webfuse/core/protocol_names.h" #include "webfuse/adapter/impl/credentials.h" -#include "webfuse/adapter/impl/jsonrpc/request.h" #include "webfuse/adapter/impl/uuid_mountpoint_factory.h" +#include "webfuse/core/status_intern.h" + +#include "wf/jsonrpc/request.h" +#include "wf/timer/manager.h" +#include "wf/timer/timer.h" static int wf_impl_server_protocol_callback( struct lws * wsi, @@ -27,7 +31,7 @@ static int wf_impl_server_protocol_callback( struct wf_server_protocol * protocol = ws_protocol->user; - wf_impl_timeout_manager_check(&protocol->timeout_manager); + wf_timer_manager_check(protocol->timer_manager); struct wf_impl_session * session = wf_impl_session_manager_get(&protocol->session_manager, wsi); switch (reason) @@ -41,8 +45,8 @@ static int wf_impl_server_protocol_callback( wsi, &protocol->authenticators, &protocol->mountpoint_factory, - &protocol->timeout_manager, - &protocol->server); + protocol->timer_manager, + protocol->server); if (NULL != session) { @@ -129,7 +133,7 @@ void wf_impl_server_protocol_init_lws( } static void wf_impl_server_protocol_authenticate( - struct wf_impl_jsonrpc_request * request, + struct wf_jsonrpc_request * request, char const * WF_UNUSED_PARAM(method_name), json_t * params, void * WF_UNUSED_PARAM(user_data)) @@ -145,7 +149,7 @@ static void wf_impl_server_protocol_authenticate( struct wf_credentials creds; wf_impl_credentials_init(&creds, type, creds_holder); - struct wf_impl_session * session = wf_impl_jsonrpc_request_get_userdata(request); + struct wf_impl_session * session = wf_jsonrpc_request_get_userdata(request); result = wf_impl_session_authenticate(session, &creds); wf_impl_credentials_cleanup(&creds); @@ -155,11 +159,11 @@ static void wf_impl_server_protocol_authenticate( if (result) { json_t * result = json_object(); - wf_impl_jsonrpc_respond(request, result); + wf_jsonrpc_respond(request, result); } else { - wf_impl_jsonrpc_respond_error(request, WF_BAD_ACCESS_DENIED); + wf_jsonrpc_respond_error(request, WF_BAD_ACCESS_DENIED, wf_status_tostring(WF_BAD_ACCESS_DENIED)); } } @@ -179,12 +183,12 @@ static bool wf_impl_server_protocol_check_name(char const * value) } static void wf_impl_server_protocol_add_filesystem( - struct wf_impl_jsonrpc_request * request, + struct wf_jsonrpc_request * request, char const * WF_UNUSED_PARAM(method_name), json_t * params, void * WF_UNUSED_PARAM(user_data)) { - struct wf_impl_session * session = wf_impl_jsonrpc_request_get_userdata(request); + struct wf_impl_session * session = wf_jsonrpc_request_get_userdata(request); wf_status status = (session->is_authenticated) ? WF_GOOD : WF_BAD_ACCESS_DENIED; char const * name = NULL; @@ -218,11 +222,11 @@ static void wf_impl_server_protocol_add_filesystem( { json_t * result = json_object(); json_object_set_new(result, "id", json_string(name)); - wf_impl_jsonrpc_respond(request, result); + wf_jsonrpc_respond(request, result); } else { - wf_impl_jsonrpc_respond_error(request, status); + wf_jsonrpc_respond_error(request, status, wf_status_tostring(status)); } @@ -236,13 +240,13 @@ void wf_impl_server_protocol_init( wf_impl_mountpoint_factory_move(mountpoint_factory, &protocol->mountpoint_factory); - wf_impl_timeout_manager_init(&protocol->timeout_manager); + protocol->timer_manager = wf_timer_manager_create(); wf_impl_session_manager_init(&protocol->session_manager); wf_impl_authenticators_init(&protocol->authenticators); - wf_impl_jsonrpc_server_init(&protocol->server); - wf_impl_jsonrpc_server_add(&protocol->server, "authenticate", &wf_impl_server_protocol_authenticate, protocol); - wf_impl_jsonrpc_server_add(&protocol->server, "add_filesystem", &wf_impl_server_protocol_add_filesystem, protocol); + protocol->server = wf_jsonrpc_server_create(); + wf_jsonrpc_server_add(protocol->server, "authenticate", &wf_impl_server_protocol_authenticate, protocol); + wf_jsonrpc_server_add(protocol->server, "add_filesystem", &wf_impl_server_protocol_add_filesystem, protocol); } void wf_impl_server_protocol_cleanup( @@ -250,8 +254,8 @@ void wf_impl_server_protocol_cleanup( { protocol->is_operational = false; - wf_impl_jsonrpc_server_cleanup(&protocol->server); - wf_impl_timeout_manager_cleanup(&protocol->timeout_manager); + wf_jsonrpc_server_dispose(protocol->server); + wf_timer_manager_dispose(protocol->timer_manager); wf_impl_authenticators_cleanup(&protocol->authenticators); wf_impl_session_manager_cleanup(&protocol->session_manager); wf_impl_mountpoint_factory_cleanup(&protocol->mountpoint_factory); diff --git a/lib/webfuse/adapter/impl/server_protocol.h b/lib/webfuse/adapter/impl/server_protocol.h index 16da34d..5d8052e 100644 --- a/lib/webfuse/adapter/impl/server_protocol.h +++ b/lib/webfuse/adapter/impl/server_protocol.h @@ -1,12 +1,11 @@ #ifndef WF_ADAPTER_IMPL_SERVER_PROTOCOL_H #define WF_ADAPTER_IMPL_SERVER_PROTOCOL_H -#include "webfuse/adapter/impl/jsonrpc/proxy.h" -#include "webfuse/adapter/impl/time/timeout_manager.h" #include "webfuse/adapter/impl/authenticators.h" #include "webfuse/adapter/impl/mountpoint_factory.h" #include "webfuse/adapter/impl/session_manager.h" -#include "webfuse/adapter/impl/jsonrpc/server.h" +#include "wf/jsonrpc/proxy.h" +#include "wf/jsonrpc/server.h" #ifndef __cplusplus #include @@ -18,14 +17,15 @@ extern "C" #endif struct lws_protocols; +struct wf_timer_manager; struct wf_server_protocol { - struct wf_impl_timeout_manager timeout_manager; struct wf_impl_authenticators authenticators; struct wf_impl_mountpoint_factory mountpoint_factory; struct wf_impl_session_manager session_manager; - struct wf_impl_jsonrpc_server server; + struct wf_jsonrpc_server * server; + struct wf_timer_manager * timer_manager; bool is_operational; }; diff --git a/lib/webfuse/adapter/impl/session.c b/lib/webfuse/adapter/impl/session.c index fb2885a..e1fdd87 100644 --- a/lib/webfuse/adapter/impl/session.c +++ b/lib/webfuse/adapter/impl/session.c @@ -2,15 +2,16 @@ #include "webfuse/adapter/impl/authenticators.h" #include "webfuse/core/message_queue.h" #include "webfuse/core/message.h" -#include "webfuse/adapter/impl/jsonrpc/proxy.h" -#include "webfuse/adapter/impl/jsonrpc/request.h" -#include "webfuse/adapter/impl/jsonrpc/response.h" #include "webfuse/adapter/impl/mountpoint_factory.h" #include "webfuse/adapter/impl/mountpoint.h" #include "webfuse/core/container_of.h" #include "webfuse/core/util.h" +#include "wf/jsonrpc/proxy.h" +#include "wf/jsonrpc/request.h" +#include "wf/jsonrpc/response.h" + #include #include #include @@ -24,7 +25,7 @@ static bool wf_impl_session_send( struct wf_impl_session * session = user_data; struct wf_message * message = wf_message_create(request); - bool result = (session->is_authenticated || wf_impl_jsonrpc_is_response(request)) && (NULL != session->wsi); + bool result = (session->is_authenticated || wf_jsonrpc_is_response(request)) && (NULL != session->wsi); if (result) { @@ -44,8 +45,8 @@ static bool wf_impl_session_send( struct wf_impl_session * wf_impl_session_create( struct lws * wsi, struct wf_impl_authenticators * authenticators, - struct wf_impl_timeout_manager * timeout_manager, - struct wf_impl_jsonrpc_server * server, + struct wf_timer_manager * timer_manager, + struct wf_jsonrpc_server * server, struct wf_impl_mountpoint_factory * mountpoint_factory) { @@ -59,7 +60,7 @@ struct wf_impl_session * wf_impl_session_create( session->authenticators = authenticators; session->server = server; session->mountpoint_factory = mountpoint_factory; - wf_impl_jsonrpc_proxy_init(&session->rpc, timeout_manager, WF_DEFAULT_TIMEOUT, &wf_impl_session_send, session); + session->rpc = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &wf_impl_session_send, session); wf_slist_init(&session->messages); } @@ -83,15 +84,10 @@ static void wf_impl_session_dispose_filesystems( void wf_impl_session_dispose( struct wf_impl_session * session) { - wf_impl_jsonrpc_proxy_cleanup(&session->rpc); + wf_jsonrpc_proxy_dispose(session->rpc); wf_message_queue_cleanup(&session->messages); wf_impl_session_dispose_filesystems(&session->filesystems); - session->is_authenticated = false; - session->wsi = NULL; - session->authenticators = NULL; - session->mountpoint_factory = NULL; - session->server = NULL; free(session); } @@ -159,13 +155,13 @@ void wf_impl_session_receive( json_t * message = json_loadb(data, length, 0, NULL); if (NULL != message) { - if (wf_impl_jsonrpc_is_response(message)) + if (wf_jsonrpc_is_response(message)) { - wf_impl_jsonrpc_proxy_onresult(&session->rpc, message); + wf_jsonrpc_proxy_onresult(session->rpc, message); } - else if (wf_impl_jsonrpc_is_request(message)) + else if (wf_jsonrpc_is_request(message)) { - wf_impl_jsonrpc_server_process(session->server, message, &wf_impl_session_send, session); + wf_jsonrpc_server_process(session->server, message, &wf_impl_session_send, session); } json_decref(message); diff --git a/lib/webfuse/adapter/impl/session.h b/lib/webfuse/adapter/impl/session.h index 9f9b10a..82b042f 100644 --- a/lib/webfuse/adapter/impl/session.h +++ b/lib/webfuse/adapter/impl/session.h @@ -10,11 +10,12 @@ using std::size_t; #endif #include "webfuse/core/message_queue.h" -#include "webfuse/adapter/impl/jsonrpc/proxy.h" -#include "webfuse/adapter/impl/jsonrpc/server.h" #include "webfuse/adapter/impl/filesystem.h" #include "webfuse/core/slist.h" +#include "wf/jsonrpc/proxy.h" +#include "wf/jsonrpc/server.h" + #ifdef __cplusplus extern "C" { @@ -25,7 +26,6 @@ struct wf_message; struct wf_credentials; struct wf_impl_authenticators; struct wf_impl_mountpoint_factory; -struct wf_impl_timeout_manager; struct wf_impl_session { @@ -35,16 +35,16 @@ struct wf_impl_session struct wf_slist messages; struct wf_impl_authenticators * authenticators; struct wf_impl_mountpoint_factory * mountpoint_factory; - struct wf_impl_jsonrpc_server * server; - struct wf_impl_jsonrpc_proxy rpc; + struct wf_jsonrpc_server * server; + struct wf_jsonrpc_proxy * rpc; struct wf_slist filesystems; }; extern struct wf_impl_session * wf_impl_session_create( struct lws * wsi, struct wf_impl_authenticators * authenticators, - struct wf_impl_timeout_manager * timeout_manager, - struct wf_impl_jsonrpc_server * server, + struct wf_timer_manager * timer_manager, + struct wf_jsonrpc_server * server, struct wf_impl_mountpoint_factory * mountpoint_factory); extern void wf_impl_session_dispose( diff --git a/lib/webfuse/adapter/impl/session_manager.c b/lib/webfuse/adapter/impl/session_manager.c index 0574c98..cc41fa0 100644 --- a/lib/webfuse/adapter/impl/session_manager.c +++ b/lib/webfuse/adapter/impl/session_manager.c @@ -28,11 +28,11 @@ struct wf_impl_session * wf_impl_session_manager_add( struct lws * wsi, struct wf_impl_authenticators * authenticators, struct wf_impl_mountpoint_factory * mountpoint_factory, - struct wf_impl_timeout_manager * timeout_manager, - struct wf_impl_jsonrpc_server * server) + struct wf_timer_manager * timer_manager, + struct wf_jsonrpc_server * server) { struct wf_impl_session * session = wf_impl_session_create( - wsi, authenticators, timeout_manager, server, mountpoint_factory); + wsi, authenticators, timer_manager, server, mountpoint_factory); if (NULL != session) { wf_slist_append(&manager->sessions, &session->item); diff --git a/lib/webfuse/adapter/impl/session_manager.h b/lib/webfuse/adapter/impl/session_manager.h index 25b4367..691f133 100644 --- a/lib/webfuse/adapter/impl/session_manager.h +++ b/lib/webfuse/adapter/impl/session_manager.h @@ -15,8 +15,8 @@ extern "C" #endif struct lws; -struct wf_impl_timeout_manager; -struct wf_impl_jsonrpc_server; +struct wf_timer_manager; +struct wf_jsonrpc_server; struct wf_impl_session_manager { @@ -34,8 +34,8 @@ extern struct wf_impl_session * wf_impl_session_manager_add( struct lws * wsi, struct wf_impl_authenticators * authenticators, struct wf_impl_mountpoint_factory * mountpoint_factory, - struct wf_impl_timeout_manager * timeout_manager, - struct wf_impl_jsonrpc_server * server); + struct wf_timer_manager * timer_manager, + struct wf_jsonrpc_server * server); extern struct wf_impl_session * wf_impl_session_manager_get( struct wf_impl_session_manager * manager, diff --git a/lib/webfuse/adapter/impl/time/timeout_manager.c b/lib/webfuse/adapter/impl/time/timeout_manager.c deleted file mode 100644 index 155ffe6..0000000 --- a/lib/webfuse/adapter/impl/time/timeout_manager.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "webfuse/adapter/impl/time/timeout_manager_intern.h" - -#include -#include "webfuse/adapter/impl/time/timer_intern.h" -#include "webfuse/adapter/impl/time/timepoint.h" - -void wf_impl_timeout_manager_init( - struct wf_impl_timeout_manager * manager) -{ - manager->timers = NULL; -} - -void wf_impl_timeout_manager_cleanup( - struct wf_impl_timeout_manager * manager) -{ - struct wf_impl_timer * timer = manager->timers; - while (NULL != timer) - { - struct wf_impl_timer * next = timer->next; - - wf_impl_timer_trigger(timer); - - timer = next; - } - - manager->timers = NULL; - -} - -void wf_impl_timeout_manager_check( - struct wf_impl_timeout_manager * manager) -{ - struct wf_impl_timer * timer = manager->timers; - while (NULL != timer) - { - struct wf_impl_timer * next = timer->next; - - if (wf_impl_timer_is_timeout(timer)) - { - wf_impl_timeout_manager_removetimer(manager, timer); - wf_impl_timer_trigger(timer); - } - - timer = next; - } -} - -void wf_impl_timeout_manager_addtimer( - struct wf_impl_timeout_manager * manager, - struct wf_impl_timer * timer) -{ - if (NULL != manager->timers) - { - manager->timers->prev = timer; - } - - timer->next = manager->timers; - timer->prev = NULL; - manager->timers = timer; -} - -void wf_impl_timeout_manager_removetimer( - struct wf_impl_timeout_manager * manager, - struct wf_impl_timer * timer) -{ - struct wf_impl_timer * prev = timer->prev; - struct wf_impl_timer * next = timer->next; - - if (NULL != prev) - { - prev->next = next; - } - - if (NULL != next) - { - next->prev = prev; - } - - if (manager->timers == timer) - { - manager->timers = next; - } -} - diff --git a/lib/webfuse/adapter/impl/time/timeout_manager.h b/lib/webfuse/adapter/impl/time/timeout_manager.h deleted file mode 100644 index 0e33c1b..0000000 --- a/lib/webfuse/adapter/impl/time/timeout_manager.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_TIME_TIMEOUT_MANAGER_H -#define WF_ADAPTER_IMPL_TIME_TIMEOUT_MANAGER_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -struct wf_impl_timer; -struct wf_impl_timeout_manager -{ - struct wf_impl_timer * timers; -}; - -extern void wf_impl_timeout_manager_init( - struct wf_impl_timeout_manager * manager); - -extern void wf_impl_timeout_manager_cleanup( - struct wf_impl_timeout_manager * manager); - -extern void wf_impl_timeout_manager_check( - struct wf_impl_timeout_manager * manager); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/webfuse/adapter/impl/time/timeout_manager_intern.h b/lib/webfuse/adapter/impl/time/timeout_manager_intern.h deleted file mode 100644 index 67ee0f8..0000000 --- a/lib/webfuse/adapter/impl/time/timeout_manager_intern.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_TIME_TIMEOUT_MANAGER_INTERN_H -#define WF_ADAPTER_IMPL_TIME_TIMEOUT_MANAGER_INTERN_H - -#include "webfuse/adapter/impl/time/timeout_manager.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -extern void wf_impl_timeout_manager_addtimer( - struct wf_impl_timeout_manager * manager, - struct wf_impl_timer * timer); - -extern void wf_impl_timeout_manager_removetimer( - struct wf_impl_timeout_manager * manager, - struct wf_impl_timer * timer); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/lib/webfuse/adapter/impl/time/timepoint.c b/lib/webfuse/adapter/impl/time/timepoint.c deleted file mode 100644 index 8425000..0000000 --- a/lib/webfuse/adapter/impl/time/timepoint.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "webfuse/adapter/impl/time/timepoint.h" - -#include - -#define WF_MSEC_PER_SEC ((wf_impl_timepoint) 1000) -#define WF_NSEC_PER_MSEC ((wf_impl_timepoint) 1000 * 1000) - -wf_impl_timepoint wf_impl_timepoint_now(void) -{ - struct timespec tp; - clock_gettime(CLOCK_MONOTONIC, &tp); - - wf_impl_timepoint const now = (tp.tv_sec * WF_MSEC_PER_SEC) + (tp.tv_nsec / WF_NSEC_PER_MSEC); - return now; -} - -wf_impl_timepoint wf_impl_timepoint_in_msec(wf_impl_timediff value) -{ - wf_impl_timepoint const now = wf_impl_timepoint_now(); - wf_impl_timepoint result = now + ((wf_impl_timepoint) value); - - return result; -} - -bool wf_impl_timepoint_is_elapsed(wf_impl_timepoint tp) -{ - wf_impl_timepoint const now = wf_impl_timepoint_now(); - wf_impl_timediff const diff = (wf_impl_timediff) (tp - now); - - return (0 > diff); -} diff --git a/lib/webfuse/adapter/impl/time/timepoint.h b/lib/webfuse/adapter/impl/time/timepoint.h deleted file mode 100644 index c9f6560..0000000 --- a/lib/webfuse/adapter/impl/time/timepoint.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_TIME_TIMEPOINT_H -#define WF_ADAPTER_IMPL_TIME_TIMEPOINT_H - -#ifndef __cplusplus -#include -#include -#else -#include -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -typedef uint64_t wf_impl_timepoint; -typedef int64_t wf_impl_timediff; - -extern wf_impl_timepoint wf_impl_timepoint_now(void); - -extern wf_impl_timepoint wf_impl_timepoint_in_msec( - wf_impl_timediff value); - -extern bool wf_impl_timepoint_is_elapsed( - wf_impl_timepoint timepoint); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/webfuse/adapter/impl/time/timer.c b/lib/webfuse/adapter/impl/time/timer.c deleted file mode 100644 index 9d1da17..0000000 --- a/lib/webfuse/adapter/impl/time/timer.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "webfuse/adapter/impl/time/timer_intern.h" -#include "webfuse/adapter/impl/time/timeout_manager_intern.h" - -#include -#include - -void wf_impl_timer_init( - struct wf_impl_timer * timer, - struct wf_impl_timeout_manager * manager) -{ - timer->manager = manager; - timer->timeout = 0; - timer->timeout_handler = NULL; - timer->user_data = NULL; - timer->prev = NULL; - timer->next = NULL; -} - -void wf_impl_timer_cleanup( - struct wf_impl_timer * timer) -{ - memset(timer, 0, sizeof(struct wf_impl_timer)); -} - -void wf_impl_timer_start( - struct wf_impl_timer * timer, - wf_impl_timepoint absolute_timeout, - wf_impl_timer_timeout_fn * handler, - void * user_data) -{ - timer->timeout = absolute_timeout; - timer->timeout_handler = handler; - timer->user_data = user_data; - - wf_impl_timeout_manager_addtimer(timer->manager, timer); -} - -void wf_impl_timer_cancel( - struct wf_impl_timer * timer) -{ - wf_impl_timeout_manager_removetimer(timer->manager, timer); - - timer->timeout = 0; - timer->timeout_handler = NULL; - timer->user_data = NULL; -} - -bool wf_impl_timer_is_timeout( - struct wf_impl_timer * timer) -{ - return wf_impl_timepoint_is_elapsed(timer->timeout); -} - - -void wf_impl_timer_trigger( - struct wf_impl_timer * timer) -{ - if (NULL != timer->timeout_handler) - { - timer->prev = NULL; - timer->next = NULL; - - timer->timeout_handler(timer); - } -} diff --git a/lib/webfuse/adapter/impl/time/timer.h b/lib/webfuse/adapter/impl/time/timer.h deleted file mode 100644 index bbc840d..0000000 --- a/lib/webfuse/adapter/impl/time/timer.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_TIME_TIMER_H -#define WF_ADAPTER_IMPL_TIME_TIMER_H - -#include "webfuse/adapter/impl/time/timepoint.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -struct wf_impl_timer; -struct wf_impl_timeout_manager; - -typedef void wf_impl_timer_timeout_fn(struct wf_impl_timer * timer); - -struct wf_impl_timer -{ - struct wf_impl_timeout_manager * manager; - wf_impl_timepoint timeout; - wf_impl_timer_timeout_fn * timeout_handler; - void * user_data; - struct wf_impl_timer * next; - struct wf_impl_timer * prev; -}; - -extern void wf_impl_timer_init( - struct wf_impl_timer * timer, - struct wf_impl_timeout_manager * manager); - -extern void wf_impl_timer_cleanup( - struct wf_impl_timer * timer); - -extern void wf_impl_timer_start( - struct wf_impl_timer * timer, - wf_impl_timepoint absolute_timeout, - wf_impl_timer_timeout_fn * handler, - void * user_data); - -extern void wf_impl_timer_cancel( - struct wf_impl_timer * timer); - -#ifdef __cplusplus -} -#endif - - - -#endif diff --git a/lib/webfuse/adapter/impl/time/timer_intern.h b/lib/webfuse/adapter/impl/time/timer_intern.h deleted file mode 100644 index 6f1f19f..0000000 --- a/lib/webfuse/adapter/impl/time/timer_intern.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef WF_ADAPTER_IMPL_TIME_TIMER_INTERN_H -#define WF_ADAPTER_IMPL_TIME_TIMER_INTERN_H - -#ifndef __cplusplus -#include -#endif - -#include "webfuse/adapter/impl/time/timer.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -extern bool wf_impl_timer_is_timeout( - struct wf_impl_timer * timer); - -extern void wf_impl_timer_trigger( - struct wf_impl_timer * timer); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint.c b/lib/webfuse/adapter/impl/uuid_mountpoint.c index eafa444..4573329 100644 --- a/lib/webfuse/adapter/impl/uuid_mountpoint.c +++ b/lib/webfuse/adapter/impl/uuid_mountpoint.c @@ -60,8 +60,8 @@ static bool wf_impl_uuid_mountpoint_link_first_subdir( { if ((DT_DIR == entry->d_type) && ('.' != entry->d_name[0])) { - symlink(entry->d_name, link_path); - result = true; + int rc = symlink(entry->d_name, link_path); + result = (0 == rc); break; } @@ -114,7 +114,8 @@ wf_impl_uuid_mountpoint_create( mkdir(data->full_path, 0755); data->default_path = wf_create_string("%s/%s/default", root_path, filesystem); - symlink(data->id, data->default_path); + int rc = symlink(data->id, data->default_path); + (void) rc; // ignore missing symlink struct wf_mountpoint * mountpoint = wf_impl_mountpoint_create(data->full_path); wf_impl_mountpoint_set_userdata(mountpoint, data, &wf_impl_uuid_mountpoint_data_dispose); diff --git a/lib/webfuse/core/json_util.c b/lib/webfuse/core/json_util.c new file mode 100644 index 0000000..48fe956 --- /dev/null +++ b/lib/webfuse/core/json_util.c @@ -0,0 +1,48 @@ +#include "webfuse/core/json_util.h" +#include "wf/jsonrpc/status.h" + +int wf_impl_json_get_int(json_t const * object, char const * key, int default_value) +{ + int result = default_value; + + json_t * holder = json_object_get(object, key); + if ((NULL != holder) && (json_is_integer(holder))) + { + result = json_integer_value(holder); + } + + return result; +} + +static wf_status wf_impl_jsonrc_code_to_status(int code) +{ + switch (code) + { + case WF_JSONRPC_GOOD: + return WF_GOOD; + case WF_JSONRPC_BAD: + return WF_BAD; + case WF_JSONRPC_BAD_BUSY: + return WF_BAD_BUSY; + case WF_JSONRPC_BAD_TIMEOUT: + return WF_BAD_TIMEOUT; + case WF_JSONRPC_BAD_FORMAT: + return WF_BAD_FORMAT; + default: + return (wf_status) code; + } +} + +wf_status +wf_impl_jsonrpc_get_status( + json_t const * error) +{ + wf_status status = WF_GOOD; + if (NULL != error) + { + int code = wf_impl_json_get_int(error, "code", WF_BAD_FORMAT); + status = wf_impl_jsonrc_code_to_status(code); + } + + return status; +} diff --git a/lib/webfuse/core/json_util.h b/lib/webfuse/core/json_util.h new file mode 100644 index 0000000..db21ed1 --- /dev/null +++ b/lib/webfuse/core/json_util.h @@ -0,0 +1,26 @@ +#ifndef WF_JSON_UTIL_H +#define WF_JSON_UTIL_H + +#include +#include "webfuse/core/status.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern int +wf_impl_json_get_int( + json_t const * object, + char const * key, + int default_value); + +extern wf_status +wf_impl_jsonrpc_get_status( + json_t const * error); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse/provider/api.c b/lib/webfuse/provider/api.c index 0c0e88a..7c3220b 100644 --- a/lib/webfuse/provider/api.c +++ b/lib/webfuse/provider/api.c @@ -11,6 +11,7 @@ #include "webfuse/provider/impl/client_config.h" #include "webfuse/provider/impl/client.h" #include "webfuse/provider/impl/dirbuffer.h" +#include "webfuse/provider/impl/credentials.h" // respond @@ -155,6 +156,13 @@ void wfp_client_config_set_onread( wfp_impl_client_config_set_onread(config, handler); } +void wfp_client_config_enable_authentication( + struct wfp_client_config * config, + wfp_get_credentials_fn * get_credentials) +{ + wfp_impl_client_config_enable_authentication(config, get_credentials); +} + // protocol @@ -240,3 +248,20 @@ void wfp_dirbuffer_add( { wfp_impl_dirbuffer_add(buffer, name, inode); } + +// credentials + +void wfp_credentials_set_type( + struct wfp_credentials * credentials, + char const * type) +{ + wfp_impl_credentials_set_type(credentials, type); +} + +void wfp_credentials_add( + struct wfp_credentials * credentials, + char const * key, + char const * value) +{ + wfp_impl_credentials_add(credentials, key, value); +} diff --git a/lib/webfuse/provider/impl/client_config.c b/lib/webfuse/provider/impl/client_config.c index 7d121da..0e8afc6 100644 --- a/lib/webfuse/provider/impl/client_config.c +++ b/lib/webfuse/provider/impl/client_config.c @@ -110,3 +110,10 @@ void wfp_impl_client_config_set_onread( { config->provider.read = handler; } + +void wfp_impl_client_config_enable_authentication( + struct wfp_client_config * config, + wfp_get_credentials_fn * get_credentials) +{ + config->provider.get_credentials = get_credentials; +} diff --git a/lib/webfuse/provider/impl/client_config.h b/lib/webfuse/provider/impl/client_config.h index 190a3cb..f8d5b9b 100644 --- a/lib/webfuse/provider/impl/client_config.h +++ b/lib/webfuse/provider/impl/client_config.h @@ -70,6 +70,10 @@ extern void wfp_impl_client_config_set_onread( struct wfp_client_config * config, wfp_read_fn * handler); +extern void wfp_impl_client_config_enable_authentication( + struct wfp_client_config * config, + wfp_get_credentials_fn * get_credentials); + #ifdef __cplusplus } #endif diff --git a/lib/webfuse/provider/impl/client_protocol.c b/lib/webfuse/provider/impl/client_protocol.c index 59945bd..4f61b8a 100644 --- a/lib/webfuse/provider/impl/client_protocol.c +++ b/lib/webfuse/provider/impl/client_protocol.c @@ -8,6 +8,7 @@ #include "webfuse/provider/impl/client_config.h" #include "webfuse/provider/impl/provider.h" +#include "webfuse/provider/impl/credentials.h" #include "webfuse/core/util.h" #include "webfuse/core/message.h" #include "webfuse/core/message_queue.h" @@ -15,6 +16,14 @@ #include "webfuse/provider/impl/url.h" #include "webfuse/core/protocol_names.h" +#include "wf/timer/manager.h" + +#include "wf/jsonrpc/response.h" +#include "wf/jsonrpc/request.h" +#include "wf/jsonrpc/proxy.h" + +#define WF_DEFAULT_TIMEOUT (10 * 1000) + static void wfp_impl_client_protocol_respond( json_t * response, void * user_data) @@ -29,54 +38,122 @@ static void wfp_impl_client_protocol_respond( } } -static void wfp_impl_client_protocol_process_request( +static void wfp_impl_client_protocol_process( struct wfp_client_protocol * protocol, - char const * message, + char const * data, size_t length) { - json_t * request = json_loadb(message, length, 0, NULL); - if (NULL != request) + json_t * message = json_loadb(data, length, 0, NULL); + if (NULL != message) { - // FIXME: is_connected should be invoked, when filesystem added - if ((!protocol->is_connected) && (NULL != json_object_get(request, "result"))) + if (wf_jsonrpc_is_response(message)) { - protocol->is_connected = true; - protocol->provider.connected(protocol->user_data); + wf_jsonrpc_proxy_onresult(protocol->proxy, message); } + if (wf_jsonrpc_is_request(message)) + { + struct wfp_impl_invokation_context context = + { + .provider = &protocol->provider, + .user_data = protocol->user_data, + .request = &protocol->request + }; + wfp_impl_provider_invoke(&context, message); + } - struct wfp_impl_invokation_context context = - { - .provider = &protocol->provider, - .user_data = protocol->user_data, - .request = &protocol->request - }; + json_decref(message); + } +} + +static void +wfp_impl_client_protocol_on_add_filesystem_finished( + void * user_data, + json_t const * result, + json_t const * WF_UNUSED_PARAM(error)) +{ + struct wfp_client_protocol * protocol = user_data; + if (NULL == protocol->wsi) { return; } - wfp_impl_provider_invoke(&context, request); - json_decref(request); + if (NULL != result) + { + protocol->is_connected = true; + protocol->provider.connected(protocol->user_data); } + else + { + protocol->is_shutdown_requested = true; + lws_callback_on_writable(protocol->wsi); + } } static void wfp_impl_client_protocol_add_filesystem( struct wfp_client_protocol * protocol) { - json_t * params = json_array(); - json_array_append_new(params, json_string("cprovider")); + wf_jsonrpc_proxy_invoke( + protocol->proxy, + &wfp_impl_client_protocol_on_add_filesystem_finished, + protocol, + "add_filesystem", + "s", + "cprovider"); +} - json_t * request = json_object(); - json_object_set_new(request, "method", json_string("add_filesystem")); - json_object_set_new(request, "params", params); - json_object_set_new(request, "id", json_integer(42)); +static void +wfp_impl_client_protocol_on_authenticate_finished( + void * user_data, + json_t const * result, + json_t const * WF_UNUSED_PARAM(error)) +{ + struct wfp_client_protocol * protocol = user_data; + if (NULL == protocol->wsi) { return; } - struct wf_message * message = wf_message_create(request); - if (NULL != message) + if (NULL != result) { - wf_slist_append(&protocol->messages, &message->item); - lws_callback_on_writable(protocol->wsi); + wfp_impl_client_protocol_add_filesystem(protocol); } + else + { + protocol->is_shutdown_requested = true; + lws_callback_on_writable(protocol->wsi); + } +} + +static void wfp_impl_client_protocol_authenticate( + struct wfp_client_protocol * protocol) +{ + struct wfp_credentials credentials; + wfp_impl_credentials_init(&credentials); - json_decref(request); + protocol->provider.get_credentials(&credentials, protocol->user_data); + + char const * cred_type = wfp_impl_credentials_get_type(&credentials); + json_t * creds = wfp_impl_credentials_get(&credentials); + json_incref(creds); + + wf_jsonrpc_proxy_invoke( + protocol->proxy, + &wfp_impl_client_protocol_on_authenticate_finished, + protocol, + "authenticate", + "sj", + cred_type, creds); + + wfp_impl_credentials_cleanup(&credentials); +} + +static void wfp_impl_client_protocol_handshake( + struct wfp_client_protocol * protocol) +{ + if (wfp_impl_provider_is_authentication_enabled(&protocol->provider)) + { + wfp_impl_client_protocol_authenticate(protocol); + } + else + { + wfp_impl_client_protocol_add_filesystem(protocol); + } } static int wfp_impl_client_protocol_callback( @@ -86,16 +163,18 @@ static int wfp_impl_client_protocol_callback( void * in, size_t len) { + int result = 0; struct lws_protocols const * ws_protocol = lws_get_protocol(wsi); struct wfp_client_protocol * protocol = (NULL != ws_protocol) ? ws_protocol->user: NULL; if (NULL != protocol) { + wf_timer_manager_check(protocol->timer_manager); + switch (reason) { case LWS_CALLBACK_CLIENT_ESTABLISHED: - wfp_impl_client_protocol_add_filesystem(protocol); - // Defer is_connected until response received + wfp_impl_client_protocol_handshake(protocol); break; case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: protocol->is_connected = false; @@ -103,36 +182,60 @@ static int wfp_impl_client_protocol_callback( break; case LWS_CALLBACK_CLIENT_CLOSED: protocol->is_connected = false; - protocol->provider.disconnected(protocol->user_data); + protocol->provider.disconnected(protocol->user_data); + protocol->wsi = NULL; break; case LWS_CALLBACK_CLIENT_RECEIVE: - wfp_impl_client_protocol_process_request(protocol, in, len); + wfp_impl_client_protocol_process(protocol, in, len); break; case LWS_CALLBACK_SERVER_WRITEABLE: // fall-through case LWS_CALLBACK_CLIENT_WRITEABLE: - if ((wsi == protocol->wsi) && (!wf_slist_empty(&protocol->messages))) + if (wsi == protocol->wsi) { - struct wf_slist_item * item = wf_slist_remove_first(&protocol->messages); - struct wf_message * message = wf_container_of(item, struct wf_message, item); - lws_write(wsi, (unsigned char*) message->data, message->length, LWS_WRITE_TEXT); - wf_message_dispose(message); - - if (!wf_slist_empty(&protocol->messages)) + if (protocol->is_shutdown_requested) { - lws_callback_on_writable(wsi); - + result = 1; } - } + else if (!wf_slist_empty(&protocol->messages)) + { + struct wf_slist_item * item = wf_slist_remove_first(&protocol->messages); + struct wf_message * message = wf_container_of(item, struct wf_message, item); + lws_write(wsi, (unsigned char*) message->data, message->length, LWS_WRITE_TEXT); + wf_message_dispose(message); + + if (!wf_slist_empty(&protocol->messages)) + { + lws_callback_on_writable(wsi); + } + } + } break; default: break; } } - return 0; + return result; } +static bool wfp_impl_client_protocol_send( + json_t * request, + void * user_data) +{ + bool result = false; + struct wfp_client_protocol * protocol = user_data; + + struct wf_message * message = wf_message_create(request); + if (NULL != message) + { + wf_slist_append(&protocol->messages, &message->item); + lws_callback_on_writable(protocol->wsi); + result = true; + } + + return result; +} void wfp_impl_client_protocol_init( struct wfp_client_protocol * protocol, @@ -140,6 +243,7 @@ void wfp_impl_client_protocol_init( void * user_data) { protocol->is_connected = false; + protocol->is_shutdown_requested = false; wf_slist_init(&protocol->messages); protocol->wsi = NULL; @@ -147,6 +251,9 @@ void wfp_impl_client_protocol_init( protocol->request.respond = &wfp_impl_client_protocol_respond; protocol->request.user_data = protocol; + protocol->timer_manager = wf_timer_manager_create(); + protocol->proxy = wf_jsonrpc_proxy_create(protocol->timer_manager, WF_DEFAULT_TIMEOUT, &wfp_impl_client_protocol_send, protocol); + protocol->user_data = user_data; wfp_impl_provider_init_from_prototype(&protocol->provider, provider); } @@ -154,6 +261,8 @@ void wfp_impl_client_protocol_init( void wfp_impl_client_protocol_cleanup( struct wfp_client_protocol * protocol) { + wf_jsonrpc_proxy_dispose(protocol->proxy); + wf_timer_manager_dispose(protocol->timer_manager); wf_message_queue_cleanup(&protocol->messages); } diff --git a/lib/webfuse/provider/impl/client_protocol.h b/lib/webfuse/provider/impl/client_protocol.h index d6f537d..af5c74b 100644 --- a/lib/webfuse/provider/impl/client_protocol.h +++ b/lib/webfuse/provider/impl/client_protocol.h @@ -14,14 +14,19 @@ extern "C" struct wfp_client_config; struct lws_protocols; struct lws_context; +struct wf_jsonrpc_proxy; +struct wf_timer_manager; struct wfp_client_protocol { bool is_connected; + bool is_shutdown_requested; struct wfp_request request; struct wfp_provider provider; void * user_data; struct lws * wsi; + struct wf_timer_manager * timer_manager; + struct wf_jsonrpc_proxy * proxy; struct wf_slist messages; }; diff --git a/lib/webfuse/provider/impl/credentials.c b/lib/webfuse/provider/impl/credentials.c new file mode 100644 index 0000000..f2d254f --- /dev/null +++ b/lib/webfuse/provider/impl/credentials.c @@ -0,0 +1,46 @@ +#include "webfuse/provider/impl/credentials.h" + +#include +#include + +void wfp_impl_credentials_init( + struct wfp_credentials * credentials) +{ + credentials->type = NULL; + credentials->contents = json_object(); +} + +void wfp_impl_credentials_cleanup( + struct wfp_credentials * credentials) +{ + free(credentials->type); + json_decref(credentials->contents); +} + +void wfp_impl_credentials_set_type( + struct wfp_credentials * credentials, + char const * type) +{ + free(credentials->type); + credentials->type = strdup(type); +} + +void wfp_impl_credentials_add( + struct wfp_credentials * credentials, + char const * key, + char const * value) +{ + json_object_set_new(credentials->contents, key, json_string(value)); +} + +char const * wfp_impl_credentials_get_type( + struct wfp_credentials * credentials) +{ + return credentials->type; +} + +json_t * wfp_impl_credentials_get( + struct wfp_credentials * credentials) +{ + return credentials->contents; +} diff --git a/lib/webfuse/provider/impl/credentials.h b/lib/webfuse/provider/impl/credentials.h new file mode 100644 index 0000000..304b067 --- /dev/null +++ b/lib/webfuse/provider/impl/credentials.h @@ -0,0 +1,43 @@ +#ifndef WF_PROVIDER_IMPL_CREDENTIALS_H +#define WF_PROVIDER_IMPL_CREDENTIALS_H + +#include "webfuse/provider/credentials.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wfp_credentials +{ + char * type; + json_t * contents; +}; + +extern void wfp_impl_credentials_init( + struct wfp_credentials * credentials); + +extern void wfp_impl_credentials_cleanup( + struct wfp_credentials * credentials); + +extern void wfp_impl_credentials_set_type( + struct wfp_credentials * credentials, + char const * type); + +extern void wfp_impl_credentials_add( + struct wfp_credentials * credentials, + char const * key, + char const * value); + +extern char const * wfp_impl_credentials_get_type( + struct wfp_credentials * credentials); + +extern json_t * wfp_impl_credentials_get( + struct wfp_credentials * credentials); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse/provider/impl/provider.c b/lib/webfuse/provider/impl/provider.c index def9e4a..14282d2 100644 --- a/lib/webfuse/provider/impl/provider.c +++ b/lib/webfuse/provider/impl/provider.c @@ -67,6 +67,7 @@ void wfp_impl_provider_init( provider->connected = &wfp_impl_connected_default; provider->disconnected = &wfp_impl_disconnected_default; provider->ontimer = &wfp_impl_ontimer_default; + provider->get_credentials = NULL; } void wfp_impl_provider_init_from_prototype( @@ -82,6 +83,7 @@ void wfp_impl_provider_init_from_prototype( provider->connected = prototype->connected; provider->disconnected = prototype->disconnected; provider->ontimer = prototype->ontimer; + provider->get_credentials = prototype->get_credentials; } void wfp_impl_provider_invoke( @@ -124,4 +126,11 @@ void wfp_impl_ontimer_default( (void) user_data; // empty -} \ No newline at end of file +} + + bool wfp_impl_provider_is_authentication_enabled( + struct wfp_provider * provider) +{ + return (NULL != provider->get_credentials); +} + diff --git a/lib/webfuse/provider/impl/provider.h b/lib/webfuse/provider/impl/provider.h index ddee453..a9b814d 100644 --- a/lib/webfuse/provider/impl/provider.h +++ b/lib/webfuse/provider/impl/provider.h @@ -1,9 +1,14 @@ #ifndef WF_PROVIDER_IMPL_PROVIDER_H #define WF_PROVIDER_IMPL_PROVIDER_H +#ifndef __cplusplus +#include +#endif + #include #include "webfuse/provider/client_config.h" + #ifdef __cplusplus extern "C" { @@ -20,6 +25,7 @@ struct wfp_provider wfp_open_fn * open; wfp_close_fn * close; wfp_read_fn * read; + wfp_get_credentials_fn * get_credentials; }; struct wfp_impl_invokation_context @@ -41,6 +47,9 @@ extern void wfp_impl_provider_invoke( struct wfp_impl_invokation_context * context, json_t * request); +extern bool wfp_impl_provider_is_authentication_enabled( + struct wfp_provider * provider); + extern void wfp_impl_connected_default( void * user_data); diff --git a/lib/wf/jsonrpc/include/wf/jsonrpc.h b/lib/wf/jsonrpc/include/wf/jsonrpc.h new file mode 100644 index 0000000..ab7f1dc --- /dev/null +++ b/lib/wf/jsonrpc/include/wf/jsonrpc.h @@ -0,0 +1,14 @@ +#ifndef WF_JSONRPC_H +#define WF_JSONRPC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/lib/wf/jsonrpc/include/wf/jsonrpc/api.h b/lib/wf/jsonrpc/include/wf/jsonrpc/api.h new file mode 100644 index 0000000..648bf0f --- /dev/null +++ b/lib/wf/jsonrpc/include/wf/jsonrpc/api.h @@ -0,0 +1,8 @@ +#ifndef WF_JSONRPC_API_H +#define WF_JSONRPC_API_H + +#ifndef WF_JSONRPC_API +#define WF_JSONRPC_API +#endif + +#endif diff --git a/lib/wf/jsonrpc/include/wf/jsonrpc/method_invoke_fn.h b/lib/wf/jsonrpc/include/wf/jsonrpc/method_invoke_fn.h new file mode 100644 index 0000000..d7a9cc8 --- /dev/null +++ b/lib/wf/jsonrpc/include/wf/jsonrpc/method_invoke_fn.h @@ -0,0 +1,26 @@ +#ifndef WF_JSONRPC_METHOD_INVOKE_FN_H +#define WF_JSONRPC_METHOD_INVOKE_FN_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_jsonrpc_request; + +typedef void wf_jsonrpc_method_invoke_fn( + struct wf_jsonrpc_request * request, + char const * method_name, + json_t * params, + void * user_data); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/lib/wf/jsonrpc/include/wf/jsonrpc/proxy.h b/lib/wf/jsonrpc/include/wf/jsonrpc/proxy.h new file mode 100644 index 0000000..66fd1a5 --- /dev/null +++ b/lib/wf/jsonrpc/include/wf/jsonrpc/proxy.h @@ -0,0 +1,75 @@ +#ifndef WF_JSONRPC_PROXY_H +#define WF_JSONRPC_PROXY_H + +#ifndef __cplusplus +#include +#include +#include +#else +#include +#include +using std::size_t; +#endif + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct wf_jsonrpc_proxy; +struct wf_timer_manager; + +extern WF_JSONRPC_API struct wf_jsonrpc_proxy * +wf_jsonrpc_proxy_create( + struct wf_timer_manager * manager, + int timeout, + wf_jsonrpc_send_fn * send, + void * user_data); + +extern WF_JSONRPC_API void wf_jsonrpc_proxy_dispose( + struct wf_jsonrpc_proxy * proxy); + +//------------------------------------------------------------------------------ +/// \brief Invokes a method. +/// +/// Creates a method an sends it using the send function. +/// Proxy keeps track of method invokation. If no response is returned within +/// timeout, an error is propagated. +/// +/// \param proxy pointer to proxy instance +/// \param finished function which is called exactly once, either on success or +/// on failure. +/// \param method_name name of the method to invoke +/// \param param_info types of the param (s = string, i = integer, j = json) +/// \param ... params +//------------------------------------------------------------------------------ +extern WF_JSONRPC_API void wf_jsonrpc_proxy_invoke( + struct wf_jsonrpc_proxy * proxy, + wf_jsonrpc_proxy_finished_fn * finished, + void * user_data, + char const * method_name, + char const * param_info, + ... +); + +extern WF_JSONRPC_API void wf_jsonrpc_proxy_notify( + struct wf_jsonrpc_proxy * proxy, + char const * method_name, + char const * param_info, + ... +); + +extern WF_JSONRPC_API void wf_jsonrpc_proxy_onresult( + struct wf_jsonrpc_proxy * proxy, + json_t * message); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/lib/wf/jsonrpc/include/wf/jsonrpc/proxy_finished_fn.h b/lib/wf/jsonrpc/include/wf/jsonrpc/proxy_finished_fn.h new file mode 100644 index 0000000..cd59c87 --- /dev/null +++ b/lib/wf/jsonrpc/include/wf/jsonrpc/proxy_finished_fn.h @@ -0,0 +1,20 @@ +#ifndef WF_JSONRPC_PROXY_FINISHED_FN_H +#define WF_JSONRPC_PROXY_FINISHED_FN_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef void wf_jsonrpc_proxy_finished_fn( + void * user_data, + json_t const * result, + json_t const * error); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/wf/jsonrpc/include/wf/jsonrpc/request.h b/lib/wf/jsonrpc/include/wf/jsonrpc/request.h new file mode 100644 index 0000000..73295e6 --- /dev/null +++ b/lib/wf/jsonrpc/include/wf/jsonrpc/request.h @@ -0,0 +1,54 @@ +#ifndef WF_JSONRPC_REQUEST_H +#define WF_JSONRPC_REQUEST_H + +#ifndef __cplusplus +#include +#include +#include +#else +#include +#include +using std::size_t; +#endif + +#include +#include +#include "wf/jsonrpc/send_fn.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_jsonrpc_request; + +extern WF_JSONRPC_API bool wf_jsonrpc_is_request( + json_t * message); + +extern WF_JSONRPC_API struct wf_jsonrpc_request * +wf_jsonrpc_request_create( + int id, + wf_jsonrpc_send_fn * send, + void * user_data); + +extern WF_JSONRPC_API void wf_jsonrpc_request_dispose( + struct wf_jsonrpc_request * request); + +extern WF_JSONRPC_API void * wf_jsonrpc_request_get_userdata( + struct wf_jsonrpc_request * request); + +extern WF_JSONRPC_API void wf_jsonrpc_respond( + struct wf_jsonrpc_request * request, + json_t * result); + +extern WF_JSONRPC_API void wf_jsonrpc_respond_error( + struct wf_jsonrpc_request * request, + int code, + char const * message); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/wf/jsonrpc/include/wf/jsonrpc/response.h b/lib/wf/jsonrpc/include/wf/jsonrpc/response.h new file mode 100644 index 0000000..abe2011 --- /dev/null +++ b/lib/wf/jsonrpc/include/wf/jsonrpc/response.h @@ -0,0 +1,23 @@ +#ifndef WF_JSONRPC_RESPONSE_H +#define WF_JSONRPC_RESPONSE_H + +#ifndef __cplusplus +#include +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern WF_JSONRPC_API bool wf_jsonrpc_is_response( + json_t * message); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse/adapter/impl/jsonrpc/send_fn.h b/lib/wf/jsonrpc/include/wf/jsonrpc/send_fn.h similarity index 61% rename from lib/webfuse/adapter/impl/jsonrpc/send_fn.h rename to lib/wf/jsonrpc/include/wf/jsonrpc/send_fn.h index baeedf7..9ea9ef4 100644 --- a/lib/webfuse/adapter/impl/jsonrpc/send_fn.h +++ b/lib/wf/jsonrpc/include/wf/jsonrpc/send_fn.h @@ -1,18 +1,19 @@ -#ifndef WF_ADAPTER_IMPL_JSONRPC_SEND_FN_H -#define WF_ADAPTER_IMPL_JSONRPC_SEND_FN_H +#ifndef WF_JSONRPC_SEND_FN_H +#define WF_JSONRPC_SEND_FN_H #ifndef __cplusplus #include #endif #include +#include #ifdef __cplusplus extern "C" { #endif -typedef bool wf_impl_jsonrpc_send_fn( +typedef bool wf_jsonrpc_send_fn( json_t * request, void * user_data); diff --git a/lib/wf/jsonrpc/include/wf/jsonrpc/server.h b/lib/wf/jsonrpc/include/wf/jsonrpc/server.h new file mode 100644 index 0000000..c4850a5 --- /dev/null +++ b/lib/wf/jsonrpc/include/wf/jsonrpc/server.h @@ -0,0 +1,46 @@ +#ifndef WF_JSONRPC_SERVER_H +#define WF_JSONRPC_SERVER_H + +#ifndef __cplusplus +#include +#include +#else +#include +#endif + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_jsonrpc_server; + +extern WF_JSONRPC_API struct wf_jsonrpc_server * +wf_jsonrpc_server_create(void); + +extern WF_JSONRPC_API void +wf_jsonrpc_server_dispose( + struct wf_jsonrpc_server * server); + +extern WF_JSONRPC_API void wf_jsonrpc_server_add( + struct wf_jsonrpc_server * server, + char const * method_name, + wf_jsonrpc_method_invoke_fn * invoke, + void * user_data); + +extern WF_JSONRPC_API void wf_jsonrpc_server_process( + struct wf_jsonrpc_server * server, + json_t * request, + wf_jsonrpc_send_fn * send, + void * user_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/wf/jsonrpc/include/wf/jsonrpc/status.h b/lib/wf/jsonrpc/include/wf/jsonrpc/status.h new file mode 100644 index 0000000..85da73d --- /dev/null +++ b/lib/wf/jsonrpc/include/wf/jsonrpc/status.h @@ -0,0 +1,11 @@ +#ifndef WF_JSONRPC_STATUS_H +#define WF_JSONRPC_STATUS_H + +#define WF_JSONRPC_GOOD 0 +#define WF_JSONRPC_BAD -1 +#define WF_JSONRPC_BAD_NOTIMPLEMENTED -2 +#define WF_JSONRPC_BAD_TIMEOUT -3 +#define WF_JSONRPC_BAD_BUSY -4 +#define WF_JSONRPC_BAD_FORMAT -5 + +#endif diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/api.c b/lib/wf/jsonrpc/src/wf/jsonrpc/api.c new file mode 100644 index 0000000..891bcce --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/api.c @@ -0,0 +1,144 @@ +#include "wf/jsonrpc.h" + +#include "wf/jsonrpc/impl/proxy.h" +#include "wf/jsonrpc/impl/request.h" +#include "wf/jsonrpc/impl/response.h" +#include "wf/jsonrpc/impl/server.h" + +// proxy + +struct wf_jsonrpc_proxy * +wf_jsonrpc_proxy_create( + struct wf_timer_manager * manager, + int timeout, + wf_jsonrpc_send_fn * send, + void * user_data) +{ + return wf_jsonrpc_impl_proxy_create(manager, timeout, send, user_data); +} + +void wf_jsonrpc_proxy_dispose( + struct wf_jsonrpc_proxy * proxy) +{ + wf_jsonrpc_impl_proxy_dispose(proxy); +} + +void wf_jsonrpc_proxy_invoke( + struct wf_jsonrpc_proxy * proxy, + wf_jsonrpc_proxy_finished_fn * finished, + void * user_data, + char const * method_name, + char const * param_info, + ... +) +{ + va_list args; + va_start(args, param_info); + wf_jsonrpc_impl_proxy_invoke(proxy, finished, user_data, method_name, param_info, args); + va_end(args); +} + +void wf_jsonrpc_proxy_notify( + struct wf_jsonrpc_proxy * proxy, + char const * method_name, + char const * param_info, + ... +) +{ + va_list args; + va_start(args, param_info); + wf_jsonrpc_impl_proxy_notify(proxy, method_name, param_info, args); + va_end(args); +} + +void wf_jsonrpc_proxy_onresult( + struct wf_jsonrpc_proxy * proxy, + json_t * message) +{ + wf_jsonrpc_impl_proxy_onresult(proxy, message); +} + + +// request + +bool wf_jsonrpc_is_request( + json_t * message) +{ + return wf_jsonrpc_impl_is_request(message); +} + +struct wf_jsonrpc_request * wf_jsonrpc_request_create( + int id, + wf_jsonrpc_send_fn * send, + void * user_data) +{ + return wf_jsonrpc_impl_request_create(id, send, user_data); +} + +void wf_jsonrpc_request_dispose( + struct wf_jsonrpc_request * request) +{ + wf_jsonrpc_impl_request_dispose(request); +} + +void * wf_jsonrpc_request_get_userdata( + struct wf_jsonrpc_request * request) +{ + return wf_jsonrpc_impl_request_get_userdata(request); +} + +void wf_jsonrpc_respond( + struct wf_jsonrpc_request * request, + json_t * result) +{ + wf_jsonrpc_impl_respond(request, result); +} + +void wf_jsonrpc_respond_error( + struct wf_jsonrpc_request * request, + int code, + char const * message) +{ + wf_jsonrpc_impl_respond_error(request, code, message); +} + +// response + +bool wf_jsonrpc_is_response( + json_t * message) +{ + return wf_jsonrpc_impl_is_response(message); +} + +// server + +struct wf_jsonrpc_server * +wf_jsonrpc_server_create(void) +{ + return wf_jsonrpc_impl_server_create(); +} + +void +wf_jsonrpc_server_dispose( + struct wf_jsonrpc_server * server) +{ + wf_jsonrpc_impl_server_dispose(server); +} + +void wf_jsonrpc_server_add( + struct wf_jsonrpc_server * server, + char const * method_name, + wf_jsonrpc_method_invoke_fn * invoke, + void * user_data) +{ + wf_jsonrpc_impl_server_add(server, method_name, invoke, user_data); +} + +void wf_jsonrpc_server_process( + struct wf_jsonrpc_server * server, + json_t * request, + wf_jsonrpc_send_fn * send, + void * user_data) +{ + wf_jsonrpc_impl_server_process(server, request, send, user_data); +} diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/impl/error.c b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/error.c new file mode 100644 index 0000000..eba2e86 --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/error.c @@ -0,0 +1,27 @@ +#include "wf/jsonrpc/impl/error.h" + +json_t * +wf_jsonrpc_impl_error( + int code, + char const * message) +{ + json_t * error = json_object(); + json_object_set_new(error, "code", json_integer(code)); + json_object_set_new(error, "message", json_string(message)); + + return error; +} + +void +wf_jsonrpc_impl_propate_error( + wf_jsonrpc_proxy_finished_fn * finised, + void * user_data, + int code, + char const * message) +{ + json_t * error = wf_jsonrpc_impl_error(code, message); + finised(user_data, NULL, error); + + json_decref(error); +} + diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/impl/error.h b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/error.h new file mode 100644 index 0000000..fda0f89 --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/error.h @@ -0,0 +1,29 @@ +#ifndef WF_JSONRPC_IMPL_ERROR_H +#define WF_JSONRPC_IMPL_ERROR_H + +#include +#include "wf/jsonrpc/proxy_finished_fn.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern json_t * +wf_jsonrpc_impl_error( + int code, + char const * message); + +extern void +wf_jsonrpc_impl_propate_error( + wf_jsonrpc_proxy_finished_fn * finised, + void * user_data, + int code, + char const * message); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/lib/webfuse/adapter/impl/jsonrpc/method.c b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/method.c similarity index 50% rename from lib/webfuse/adapter/impl/jsonrpc/method.c rename to lib/wf/jsonrpc/src/wf/jsonrpc/impl/method.c index 8485471..87b3ff1 100644 --- a/lib/webfuse/adapter/impl/jsonrpc/method.c +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/method.c @@ -1,13 +1,13 @@ -#include "webfuse/adapter/impl/jsonrpc/method.h" +#include "wf/jsonrpc/impl/method.h" #include #include -struct wf_impl_jsonrpc_method * wf_impl_jsonrpc_method_create( +struct wf_jsonrpc_method * wf_jsonrpc_impl_method_create( char const * method_name, - wf_impl_jsonrpc_method_invoke_fn * invoke, + wf_jsonrpc_method_invoke_fn * invoke, void * user_data) { - struct wf_impl_jsonrpc_method * method = malloc(sizeof(struct wf_impl_jsonrpc_method)); + struct wf_jsonrpc_method * method = malloc(sizeof(struct wf_jsonrpc_method)); if (NULL != method) { method->next = NULL; @@ -19,8 +19,8 @@ struct wf_impl_jsonrpc_method * wf_impl_jsonrpc_method_create( return method; } -void wf_impl_jsonrpc_method_dispose( - struct wf_impl_jsonrpc_method * method) +void wf_jsonrpc_impl_method_dispose( + struct wf_jsonrpc_method * method) { free(method->name); free(method); diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/impl/method.h b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/method.h new file mode 100644 index 0000000..d0e42f0 --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/method.h @@ -0,0 +1,34 @@ +#ifndef WF_JSONRPC_IMPL_METHOD_H +#define WF_JSONRPC_IMPL_METHOD_H + +#include "wf/jsonrpc/method_invoke_fn.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_jsonrpc_method +{ + struct wf_jsonrpc_method * next; + char * name; + wf_jsonrpc_method_invoke_fn * invoke; + void * user_data; +}; + +extern struct wf_jsonrpc_method * +wf_jsonrpc_impl_method_create( + char const * method_name, + wf_jsonrpc_method_invoke_fn * invoke, + void * user_data); + +extern void +wf_jsonrpc_impl_method_dispose( + struct wf_jsonrpc_method * method); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/impl/proxy.c b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/proxy.c new file mode 100644 index 0000000..a2b9816 --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/proxy.c @@ -0,0 +1,220 @@ +#include "wf/jsonrpc/impl/proxy.h" +#include "wf/jsonrpc/impl/response.h" +#include "wf/jsonrpc/impl/error.h" +#include "wf/jsonrpc/status.h" + +#include + +#include +#include + +struct wf_jsonrpc_proxy * +wf_jsonrpc_impl_proxy_create( + struct wf_timer_manager * manager, + int timeout, + wf_jsonrpc_send_fn * send, + void * user_data) +{ + struct wf_jsonrpc_proxy * proxy = malloc(sizeof(struct wf_jsonrpc_proxy)); + if (NULL != proxy) + { + wf_jsonrpc_impl_proxy_init(proxy, manager, timeout, send, user_data); + } + + return proxy; +} + +void wf_jsonrpc_impl_proxy_dispose( + struct wf_jsonrpc_proxy * proxy) +{ + wf_jsonrpc_impl_proxy_cleanup(proxy); + free(proxy); +} + +static void wf_jsonrpc_impl_proxy_on_timeout( + struct wf_timer * timer, void * proxy_ptr) +{ + struct wf_jsonrpc_proxy * proxy = proxy_ptr; + + if (proxy->request.is_pending) + { + wf_jsonrpc_proxy_finished_fn * finished = proxy->request.finished; + void * user_data = proxy->request.user_data; + + proxy->request.is_pending = false; + proxy->request.id = 0; + proxy->request.user_data = NULL; + proxy->request.finished = NULL; + wf_timer_cancel(timer); + + wf_jsonrpc_impl_propate_error(finished, user_data, WF_JSONRPC_BAD_TIMEOUT, "Timeout"); + } +} + +static json_t * wf_jsonrpc_impl_request_create( + char const * method, + int id, + char const * param_info, + va_list args) +{ + json_t * request = json_object(); + json_object_set_new(request, "method", json_string(method)); + json_t * params = json_array(); + + for (char const * param_type = param_info; '\0' != *param_type; param_type++) + { + switch(*param_type) + { + case 's': + { + char const * const value = va_arg(args, char const *); + json_array_append_new(params, json_string(value)); + } + break; + case 'i': + { + int const value = va_arg(args, int); + json_array_append_new(params, json_integer(value)); + } + break; + case 'j': + { + json_t * const value = va_arg(args, json_t *); + json_array_append_new(params, value); + } + break; + default: + fprintf(stderr, "fatal: unknown param_type '%c'\n", *param_type); + json_decref(params); + json_decref(request); + return NULL; + } + } + + + json_object_set_new(request, "params", params); + if (0 != id) + { + json_object_set_new(request, "id", json_integer(id)); + } + + return request; +} + +void wf_jsonrpc_impl_proxy_init( + struct wf_jsonrpc_proxy * proxy, + struct wf_timer_manager * timeout_manager, + int timeout, + wf_jsonrpc_send_fn * send, + void * user_data) +{ + proxy->send = send; + proxy->timeout = timeout; + proxy->user_data = user_data; + proxy->request.is_pending = false; + proxy->request.timer = wf_timer_create(timeout_manager, + &wf_jsonrpc_impl_proxy_on_timeout, proxy); +} + +void wf_jsonrpc_impl_proxy_cleanup( + struct wf_jsonrpc_proxy * proxy) +{ + if (proxy->request.is_pending) + { + void * user_data = proxy->request.user_data; + wf_jsonrpc_proxy_finished_fn * finished = proxy->request.finished; + + proxy->request.is_pending = false; + proxy->request.finished = NULL; + proxy->request.user_data = NULL; + proxy->request.id = 0; + wf_timer_cancel(proxy->request.timer); + + wf_jsonrpc_impl_propate_error(finished, user_data, WF_JSONRPC_BAD, "Bad: cancelled pending request during shutdown"); + } + + wf_timer_dispose(proxy->request.timer); +} + +void wf_jsonrpc_impl_proxy_invoke( + struct wf_jsonrpc_proxy * proxy, + wf_jsonrpc_proxy_finished_fn * finished, + void * user_data, + char const * method_name, + char const * param_info, + va_list args +) +{ + if (!proxy->request.is_pending) + { + proxy->request.is_pending = true; + proxy->request.finished = finished; + proxy->request.user_data = user_data; + proxy->request.id = 42; + wf_timer_start(proxy->request.timer, proxy->timeout); + + json_t * request = wf_jsonrpc_impl_request_create(method_name, proxy->request.id, param_info, args); + + bool const is_send = ((NULL != request) && (proxy->send(request, proxy->user_data))); + if (!is_send) + { + proxy->request.is_pending = false; + proxy->request.finished = NULL; + proxy->request.user_data = NULL; + proxy->request.id = 0; + wf_timer_cancel(proxy->request.timer); + + wf_jsonrpc_impl_propate_error(finished, user_data, WF_JSONRPC_BAD, "Bad: requenst is not sent"); + } + + if (NULL != request) + { + json_decref(request); + } + } + else + { + wf_jsonrpc_impl_propate_error(finished, user_data, WF_JSONRPC_BAD_BUSY, "Busy"); + } +} + +extern void wf_jsonrpc_impl_proxy_notify( + struct wf_jsonrpc_proxy * proxy, + char const * method_name, + char const * param_info, + va_list args +) +{ + json_t * request = wf_jsonrpc_impl_request_create(method_name, 0, param_info, args); + if (NULL != request) + { + proxy->send(request, proxy->user_data); + json_decref(request); + } +} + + +void wf_jsonrpc_impl_proxy_onresult( + struct wf_jsonrpc_proxy * proxy, + json_t * message) +{ + struct wf_jsonrpc_response response; + wf_jsonrpc_impl_response_init(&response, message); + + if ((proxy->request.is_pending) && (response.id == proxy->request.id)) + { + wf_jsonrpc_proxy_finished_fn * finished = proxy->request.finished; + void * user_data = proxy->request.user_data; + + proxy->request.is_pending = false; + proxy->request.id = 0; + proxy->request.user_data = NULL; + proxy->request.finished = NULL; + wf_timer_cancel(proxy->request.timer); + + finished(user_data, response.result, response.error); + } + + wf_jsonrpc_impl_response_cleanup(&response); +} + diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/impl/proxy.h b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/proxy.h new file mode 100644 index 0000000..60d2f7a --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/proxy.h @@ -0,0 +1,84 @@ +#ifndef WF_JSONRPC_IMPL_PROXY_H +#define WF_JSONRPC_IMPL_PROXY_H + +#include "wf/jsonrpc/proxy_finished_fn.h" +#include "wf/jsonrpc/send_fn.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_timer_manager; +struct wf_timer; + +struct wf_jsonrpc_request +{ + bool is_pending; + wf_jsonrpc_proxy_finished_fn * finished; + void * user_data; + int id; + struct wf_timer * timer; +}; + +struct wf_jsonrpc_proxy +{ + struct wf_jsonrpc_request request; + int timeout; + wf_jsonrpc_send_fn * send; + void * user_data; +}; + +extern void +wf_jsonrpc_impl_proxy_init( + struct wf_jsonrpc_proxy * proxy, + struct wf_timer_manager * manager, + int timeout, + wf_jsonrpc_send_fn * send, + void * user_data); + +extern void +wf_jsonrpc_impl_proxy_cleanup( + struct wf_jsonrpc_proxy * proxy); + +extern struct wf_jsonrpc_proxy * +wf_jsonrpc_impl_proxy_create( + struct wf_timer_manager * manager, + int timeout, + wf_jsonrpc_send_fn * send, + void * user_data); + +extern void +wf_jsonrpc_impl_proxy_dispose( + struct wf_jsonrpc_proxy * proxy); + + +extern void +wf_jsonrpc_impl_proxy_invoke( + struct wf_jsonrpc_proxy * proxy, + wf_jsonrpc_proxy_finished_fn * finished, + void * user_data, + char const * method_name, + char const * param_info, + va_list args +); + +extern void +wf_jsonrpc_impl_proxy_notify( + struct wf_jsonrpc_proxy * proxy, + char const * method_name, + char const * param_info, + va_list args +); + +extern void +wf_jsonrpc_impl_proxy_onresult( + struct wf_jsonrpc_proxy * proxy, + json_t * message); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse/adapter/impl/jsonrpc/request.c b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/request.c similarity index 50% rename from lib/webfuse/adapter/impl/jsonrpc/request.c rename to lib/wf/jsonrpc/src/wf/jsonrpc/impl/request.c index e016e1c..e46f19e 100644 --- a/lib/webfuse/adapter/impl/jsonrpc/request.c +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/request.c @@ -1,15 +1,16 @@ -#include "webfuse/adapter/impl/jsonrpc/request.h" -#include "webfuse/core/status_intern.h" +#include "wf/jsonrpc/impl/request.h" +#include "wf/jsonrpc/impl/error.h" #include -struct wf_impl_jsonrpc_request +struct wf_jsonrpc_request { int id; - wf_impl_jsonrpc_send_fn * send; + wf_jsonrpc_send_fn * send; void * user_data; }; -bool wf_impl_jsonrpc_is_request( +bool +wf_jsonrpc_impl_is_request( json_t * message) { json_t * id = json_object_get(message, "id"); @@ -21,12 +22,13 @@ bool wf_impl_jsonrpc_is_request( } -struct wf_impl_jsonrpc_request * wf_impl_jsonrpc_request_create( +struct wf_jsonrpc_request * +wf_jsonrpc_impl_request_create( int id, - wf_impl_jsonrpc_send_fn * send, + wf_jsonrpc_send_fn * send, void * user_data) { - struct wf_impl_jsonrpc_request * request = malloc(sizeof(struct wf_impl_jsonrpc_request)); + struct wf_jsonrpc_request * request = malloc(sizeof(struct wf_jsonrpc_request)); if (NULL != request) { request->id = id; @@ -37,21 +39,24 @@ struct wf_impl_jsonrpc_request * wf_impl_jsonrpc_request_create( return request; } -void wf_impl_jsonrpc_request_dispose( - struct wf_impl_jsonrpc_request * request) +void +wf_jsonrpc_impl_request_dispose( + struct wf_jsonrpc_request * request) { free(request); } -void * wf_impl_jsonrpc_request_get_userdata( - struct wf_impl_jsonrpc_request * request) +void * +wf_jsonrpc_impl_request_get_userdata( + struct wf_jsonrpc_request * request) { return request->user_data; } -void wf_impl_jsonrpc_respond( - struct wf_impl_jsonrpc_request * request, +void +wf_jsonrpc_impl_respond( + struct wf_jsonrpc_request * request, json_t * result) { json_t * response = json_object(); @@ -60,23 +65,20 @@ void wf_impl_jsonrpc_respond( request->send(response, request->user_data); json_decref(response); - wf_impl_jsonrpc_request_dispose(request); + wf_jsonrpc_impl_request_dispose(request); } -void wf_impl_jsonrpc_respond_error( - struct wf_impl_jsonrpc_request * request, - wf_status status) +void wf_jsonrpc_impl_respond_error( + struct wf_jsonrpc_request * request, + int code, + char const * message) { - json_t * err = json_object(); - json_object_set_new(err, "code", json_integer(status)); - json_object_set_new(err, "message", json_string(wf_status_tostring(status))); - json_t * response = json_object(); - json_object_set_new(response, "error", err); + json_object_set_new(response, "error", wf_jsonrpc_impl_error(code, message)); json_object_set_new(response, "id", json_integer(request->id)); request->send(response, request->user_data); json_decref(response); - wf_impl_jsonrpc_request_dispose(request); + wf_jsonrpc_impl_request_dispose(request); } diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/impl/request.h b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/request.h new file mode 100644 index 0000000..0d510e9 --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/request.h @@ -0,0 +1,53 @@ +#ifndef WF_JSONRPC_IMPL_REQUEST_H +#define WF_JSONRPC_IMPL_REQUEST_H + +#ifndef __cplusplus +#include +#include +#include +#else +#include +#include +using std::size_t; +#endif + +#include +#include +#include "wf/jsonrpc/send_fn.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_jsonrpc_request; + +extern bool wf_jsonrpc_impl_is_request( + json_t * message); + +extern struct wf_jsonrpc_request * wf_jsonrpc_impl_request_create( + int id, + wf_jsonrpc_send_fn * send, + void * user_data); + +extern void wf_jsonrpc_impl_request_dispose( + struct wf_jsonrpc_request * request); + +extern void * wf_jsonrpc_impl_request_get_userdata( + struct wf_jsonrpc_request * request); + +extern void wf_jsonrpc_impl_respond( + struct wf_jsonrpc_request * request, + json_t * result); + +extern void wf_jsonrpc_impl_respond_error( + struct wf_jsonrpc_request * request, + int code, + char const * message); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse/adapter/impl/jsonrpc/response.c b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/response.c similarity index 51% rename from lib/webfuse/adapter/impl/jsonrpc/response.c rename to lib/wf/jsonrpc/src/wf/jsonrpc/impl/response.c index 00eb396..07171fb 100644 --- a/lib/webfuse/adapter/impl/jsonrpc/response.c +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/response.c @@ -1,6 +1,9 @@ -#include "webfuse/adapter/impl/jsonrpc/response.h" +#include "wf/jsonrpc/impl/response.h" +#include "wf/jsonrpc/impl/error.h" +#include "wf/jsonrpc/status.h" -extern bool wf_impl_jsonrpc_is_response( +bool +wf_jsonrpc_impl_is_response( json_t * message) { json_t * id = json_object_get(message, "id"); @@ -12,22 +15,22 @@ extern bool wf_impl_jsonrpc_is_response( } -void wf_impl_jsonrpc_response_init( - struct wf_impl_jsonrpc_response * result, +void +wf_jsonrpc_impl_response_init( + struct wf_jsonrpc_response * result, json_t * response) { - result->status = WF_BAD; result->id = -1; result->result = NULL; + result->error = NULL; json_t * id_holder = json_object_get(response, "id"); if ((NULL == id_holder) || (!json_is_integer(id_holder))) { - result->status = WF_BAD_FORMAT; + result->error = wf_jsonrpc_impl_error(WF_JSONRPC_BAD_FORMAT, "invalid format: missing id"); return; } - result->status = WF_GOOD; result->id = json_integer_value(id_holder); result->result = json_object_get(response, "result"); if (NULL != result->result) @@ -36,25 +39,30 @@ void wf_impl_jsonrpc_response_init( } else { - result->status = WF_BAD_FORMAT; - json_t * error = json_object_get(response, "error"); - if (NULL != error) + if ((json_is_object(error)) && (json_is_integer(json_object_get(error, "code")))) + { + result->error = error; + json_incref(result->error); + } + else { - json_t * error_code = json_object_get(error, "code"); - if ((NULL != error_code) && (json_is_integer(error_code))) - { - result->status = json_integer_value(error_code); - } + result->error = wf_jsonrpc_impl_error(WF_JSONRPC_BAD_FORMAT, "invalid format: invalid error object"); } } } -void wf_impl_jsonrpc_response_cleanup( - struct wf_impl_jsonrpc_response * response) +void +wf_jsonrpc_impl_response_cleanup( + struct wf_jsonrpc_response * response) { if (NULL != response->result) { json_decref(response->result); } + + if (NULL != response->error) + { + json_decref(response->error); + } } diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/impl/response.h b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/response.h new file mode 100644 index 0000000..3e1e02e --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/response.h @@ -0,0 +1,40 @@ +#ifndef WF_JSONRPC_IMPL_RESPONSE_H +#define WF_JSONRPC_IMPL_RESPONSE_H + +#ifndef __cplusplus +#include +#include +#else +#include +using std::size_t; +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct wf_jsonrpc_response +{ + json_t * result; + json_t * error; + int id; +}; + +extern bool wf_jsonrpc_impl_is_response( + json_t * message); + +extern void wf_jsonrpc_impl_response_init( + struct wf_jsonrpc_response * response, + json_t * message); + +extern void wf_jsonrpc_impl_response_cleanup( + struct wf_jsonrpc_response * response); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/impl/server.c b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/server.c new file mode 100644 index 0000000..e510daa --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/server.c @@ -0,0 +1,132 @@ +#include "wf/jsonrpc/impl/server.h" +#include "wf/jsonrpc/impl/method.h" +#include "wf/jsonrpc/impl/request.h" +#include "wf/jsonrpc/impl/unused_param.h" +#include "wf/jsonrpc/status.h" + +#include +#include + +struct wf_jsonrpc_server +{ + struct wf_jsonrpc_method * methods; +}; + +static void +wf_jsonrpc_impl_server_init( + struct wf_jsonrpc_server * server); + +static void +wf_jsonrpc_impl_server_cleanup( + struct wf_jsonrpc_server * server); + +struct wf_jsonrpc_server * +wf_jsonrpc_impl_server_create(void) +{ + struct wf_jsonrpc_server * server = malloc(sizeof(struct wf_jsonrpc_server)); + if (NULL != server) + { + wf_jsonrpc_impl_server_init(server); + } + + return server; +} + +void +wf_jsonrpc_impl_server_dispose( + struct wf_jsonrpc_server * server) +{ + wf_jsonrpc_impl_server_cleanup(server); + free(server); +} + + +static void wf_jsonrpc_impl_server_init( + struct wf_jsonrpc_server * server) +{ + server->methods = NULL; +} + +static void wf_jsonrpc_impl_server_cleanup( + struct wf_jsonrpc_server * server) +{ + struct wf_jsonrpc_method * current = server->methods; + while (NULL != current) + { + struct wf_jsonrpc_method * next = current->next; + wf_jsonrpc_impl_method_dispose(current); + current = next; + } + server->methods = NULL; +} + +void wf_jsonrpc_impl_server_add( + struct wf_jsonrpc_server * server, + char const * method_name, + wf_jsonrpc_method_invoke_fn * invoke, + void * user_data) +{ + struct wf_jsonrpc_method * method = wf_jsonrpc_impl_method_create(method_name, invoke, user_data); + method->next = server->methods; + server->methods = method; +} + +static void wf_jsonrpc_impl_server_invalid_method_invoke( + struct wf_jsonrpc_request * request, + char const * WF_JSONRPC_UNUSED_PARAM(method_name), + json_t * WF_JSONRPC_UNUSED_PARAM(params), + void * WF_JSONRPC_UNUSED_PARAM(user_data)) +{ + wf_jsonrpc_impl_respond_error(request, WF_JSONRPC_BAD_NOTIMPLEMENTED, "not implemented"); +} + +static struct wf_jsonrpc_method const wf_jsonrpc_impl_server_invalid_method = +{ + .next = NULL, + .name = "", + .invoke = &wf_jsonrpc_impl_server_invalid_method_invoke, + .user_data = NULL +}; + +static struct wf_jsonrpc_method const * +wf_jsonrpc_impl_server_get_method( + struct wf_jsonrpc_server * server, + char const * method_name) +{ + struct wf_jsonrpc_method const * current = server->methods; + while (NULL != current) + { + if (0 == strcmp(method_name, current->name)) + { + return current; + } + + current = current->next; + } + + return &wf_jsonrpc_impl_server_invalid_method; +} + +void wf_jsonrpc_impl_server_process( + struct wf_jsonrpc_server * server, + json_t * request_data, + wf_jsonrpc_send_fn * send, + void * user_data) +{ + json_t * method_holder = json_object_get(request_data, "method"); + json_t * params = json_object_get(request_data, "params"); + json_t * id_holder = json_object_get(request_data, "id"); + + if (json_is_string(method_holder) && + (json_is_array(params) || (json_is_object(params))) && + json_is_integer(id_holder)) + { + char const * method_name = json_string_value(method_holder); + int id = json_integer_value(id_holder); + struct wf_jsonrpc_request * request = wf_jsonrpc_impl_request_create(id, send, user_data); + struct wf_jsonrpc_method const * method = wf_jsonrpc_impl_server_get_method(server, method_name); + + method->invoke(request, method_name, params, method->user_data); + } +} + diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/impl/server.h b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/server.h new file mode 100644 index 0000000..82c7421 --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/server.h @@ -0,0 +1,41 @@ +#ifndef WF_JSONRPC_IMPL_SERVER_H +#define WF_JSONRPC_IMPL_SERVER_H + +#include +#include "wf/jsonrpc/method_invoke_fn.h" +#include "wf/jsonrpc/send_fn.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_jsonrpc_server; + +extern struct wf_jsonrpc_server * +wf_jsonrpc_impl_server_create(void); + +extern void +wf_jsonrpc_impl_server_dispose( + struct wf_jsonrpc_server * server); + +extern void +wf_jsonrpc_impl_server_add( + struct wf_jsonrpc_server * server, + char const * method_name, + wf_jsonrpc_method_invoke_fn * invoke, + void * user_data); + +extern void +wf_jsonrpc_impl_server_process( + struct wf_jsonrpc_server * server, + json_t * request, + wf_jsonrpc_send_fn * send, + void * user_data); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/lib/wf/jsonrpc/src/wf/jsonrpc/impl/unused_param.h b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/unused_param.h new file mode 100644 index 0000000..41323c8 --- /dev/null +++ b/lib/wf/jsonrpc/src/wf/jsonrpc/impl/unused_param.h @@ -0,0 +1,10 @@ +#ifndef WF_JSONRPC_UTIL_H +#define WF_JSONRPC_UTIL_H + +#ifdef __GNUC__ +#define WF_JSONRPC_UNUSED_PARAM(param) param __attribute__((unused)) +#else +#define WF_JSONRPC_UNUSED_PARAM(param) +#endif + +#endif diff --git a/test/webfuse/tests/adapter/jsonrpc/test_is_request.cc b/lib/wf/jsonrpc/test/wf/jsonrpc/test_is_request.cc similarity index 65% rename from test/webfuse/tests/adapter/jsonrpc/test_is_request.cc rename to lib/wf/jsonrpc/test/wf/jsonrpc/test_is_request.cc index 5fef81e..55e40c6 100644 --- a/test/webfuse/tests/adapter/jsonrpc/test_is_request.cc +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/test_is_request.cc @@ -1,112 +1,112 @@ #include -#include "webfuse/adapter/impl/jsonrpc/request.h" +#include "wf/jsonrpc/request.h" -TEST(jsonrpc_is_request, request_with_object_params) +TEST(wf_jsonrpc_is_request, request_with_object_params) { json_t * request = json_object(); json_object_set_new(request, "method", json_string("method")); json_object_set_new(request, "params", json_object()); json_object_set_new(request, "id", json_integer(42)); - ASSERT_TRUE(wf_impl_jsonrpc_is_request(request)); + ASSERT_TRUE(wf_jsonrpc_is_request(request)); json_decref(request); } -TEST(jsonrpc_is_request, request_with_array_params) +TEST(wf_jsonrpc_is_request, request_with_array_params) { json_t * request = json_object(); json_object_set_new(request, "method", json_string("method")); json_object_set_new(request, "params", json_array()); json_object_set_new(request, "id", json_integer(42)); - ASSERT_TRUE(wf_impl_jsonrpc_is_request(request)); + ASSERT_TRUE(wf_jsonrpc_is_request(request)); json_decref(request); } -TEST(jsonrpc_is_request, null_request) +TEST(wf_jsonrpc_is_request, null_request) { - ASSERT_FALSE(wf_impl_jsonrpc_is_request(nullptr)); + ASSERT_FALSE(wf_jsonrpc_is_request(nullptr)); } -TEST(jsonrpc_is_request, invalid_request) +TEST(wf_jsonrpc_is_request, invalid_request) { json_t * request = json_array(); json_array_append_new(request, json_string("method")); json_array_append_new(request, json_object()); json_array_append_new(request, json_integer(42)); - ASSERT_FALSE(wf_impl_jsonrpc_is_request(request)); + ASSERT_FALSE(wf_jsonrpc_is_request(request)); json_decref(request); } -TEST(jsonrpc_is_request, invalid_request_without_id) +TEST(wf_jsonrpc_is_request, invalid_request_without_id) { json_t * request = json_object(); json_object_set_new(request, "method", json_string("method")); json_object_set_new(request, "params", json_object()); - ASSERT_FALSE(wf_impl_jsonrpc_is_request(request)); + ASSERT_FALSE(wf_jsonrpc_is_request(request)); json_decref(request); } -TEST(jsonrpc_is_request, invalid_request_due_to_invalid_id) +TEST(wf_jsonrpc_is_request, invalid_request_due_to_invalid_id) { json_t * request = json_object(); json_object_set_new(request, "method", json_string("method")); json_object_set_new(request, "params", json_object()); json_object_set_new(request, "id", json_string("42")); - ASSERT_FALSE(wf_impl_jsonrpc_is_request(request)); + ASSERT_FALSE(wf_jsonrpc_is_request(request)); json_decref(request); } -TEST(jsonrpc_is_request, invalid_request_without_method) +TEST(wf_jsonrpc_is_request, invalid_request_without_method) { json_t * request = json_object(); json_object_set_new(request, "params", json_object()); json_object_set_new(request, "id", json_integer(42)); - ASSERT_FALSE(wf_impl_jsonrpc_is_request(request)); + ASSERT_FALSE(wf_jsonrpc_is_request(request)); json_decref(request); } -TEST(jsonrpc_is_request, invalid_request_due_to_invalid_method) +TEST(wf_jsonrpc_is_request, invalid_request_due_to_invalid_method) { json_t * request = json_object(); json_object_set_new(request, "method", json_integer(42)); json_object_set_new(request, "params", json_object()); json_object_set_new(request, "id", json_integer(42)); - ASSERT_FALSE(wf_impl_jsonrpc_is_request(request)); + ASSERT_FALSE(wf_jsonrpc_is_request(request)); json_decref(request); } -TEST(jsonrpc_is_request, invalid_request_without_params) +TEST(wf_jsonrpc_is_request, invalid_request_without_params) { json_t * request = json_object(); json_object_set_new(request, "method", json_string("method")); json_object_set_new(request, "id", json_integer(42)); - ASSERT_FALSE(wf_impl_jsonrpc_is_request(request)); + ASSERT_FALSE(wf_jsonrpc_is_request(request)); json_decref(request); } -TEST(jsonrpc_is_request, invalid_request_due_to_invalid_params) +TEST(wf_jsonrpc_is_request, invalid_request_due_to_invalid_params) { json_t * request = json_object(); json_object_set_new(request, "methdo", json_string("method")); json_object_set_new(request, "params", json_string("params")); json_object_set_new(request, "id", json_integer(42)); - ASSERT_FALSE(wf_impl_jsonrpc_is_request(request)); + ASSERT_FALSE(wf_jsonrpc_is_request(request)); json_decref(request); } diff --git a/test/webfuse/tests/adapter/jsonrpc/test_is_response.cc b/lib/wf/jsonrpc/test/wf/jsonrpc/test_is_response.cc similarity index 59% rename from test/webfuse/tests/adapter/jsonrpc/test_is_response.cc rename to lib/wf/jsonrpc/test/wf/jsonrpc/test_is_response.cc index 6182cd0..690bb6c 100644 --- a/test/webfuse/tests/adapter/jsonrpc/test_is_response.cc +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/test_is_response.cc @@ -1,94 +1,94 @@ #include -#include "webfuse/adapter/impl/jsonrpc/response.h" +#include "wf/jsonrpc/response.h" -TEST(jsonrpc_is_response, valid_result) +TEST(wf_jsonrpc_is_response, valid_result) { json_t * message = json_object(); json_object_set_new(message, "result", json_object()); json_object_set_new(message, "id", json_integer(42)); - ASSERT_TRUE(wf_impl_jsonrpc_is_response(message)); + ASSERT_TRUE(wf_jsonrpc_is_response(message)); json_decref(message); } -TEST(jsonrpc_is_response, valid_result_string) +TEST(wf_jsonrpc_is_response, valid_result_string) { json_t * message = json_object(); json_object_set_new(message, "result", json_string("also valid")); json_object_set_new(message, "id", json_integer(42)); - ASSERT_TRUE(wf_impl_jsonrpc_is_response(message)); + ASSERT_TRUE(wf_jsonrpc_is_response(message)); json_decref(message); } -TEST(jsonrpc_is_response, valid_error) +TEST(wf_jsonrpc_is_response, valid_error) { json_t * message = json_object(); json_object_set_new(message, "error", json_object()); json_object_set_new(message, "id", json_integer(42)); - ASSERT_TRUE(wf_impl_jsonrpc_is_response(message)); + ASSERT_TRUE(wf_jsonrpc_is_response(message)); json_decref(message); } -TEST(jsonrpc_is_response, invalid_null) +TEST(wf_jsonrpc_is_response, invalid_null) { - ASSERT_FALSE(wf_impl_jsonrpc_is_response(nullptr)); + ASSERT_FALSE(wf_jsonrpc_is_response(nullptr)); } -TEST(jsonrpc_is_response, invalid_message) +TEST(wf_jsonrpc_is_response, invalid_message) { json_t * message = json_array(); json_array_append_new(message, json_object()); json_array_append_new(message, json_integer(42)); - ASSERT_FALSE(wf_impl_jsonrpc_is_response(message)); + ASSERT_FALSE(wf_jsonrpc_is_response(message)); json_decref(message); } -TEST(jsonrpc_is_response, invalid_missing_id) +TEST(wf_jsonrpc_is_response, invalid_missing_id) { json_t * message = json_object(); json_object_set_new(message, "result", json_object()); - ASSERT_FALSE(wf_impl_jsonrpc_is_response(message)); + ASSERT_FALSE(wf_jsonrpc_is_response(message)); json_decref(message); } -TEST(jsonrpc_is_response, invalid_id_wrong_type) +TEST(wf_jsonrpc_is_response, invalid_id_wrong_type) { json_t * message = json_object(); json_object_set_new(message, "result", json_object()); json_object_set_new(message, "id", json_string("42")); - ASSERT_FALSE(wf_impl_jsonrpc_is_response(message)); + ASSERT_FALSE(wf_jsonrpc_is_response(message)); json_decref(message); } -TEST(jsonrpc_is_response, invalid_missing_result_and_error) +TEST(wf_jsonrpc_is_response, invalid_missing_result_and_error) { json_t * message = json_object(); json_object_set_new(message, "id", json_integer(42)); - ASSERT_FALSE(wf_impl_jsonrpc_is_response(message)); + ASSERT_FALSE(wf_jsonrpc_is_response(message)); json_decref(message); } -TEST(jsonrpc_is_response, invalid_error_wrong_type) +TEST(wf_jsonrpc_is_response, invalid_error_wrong_type) { json_t * message = json_object(); json_object_set_new(message, "error", json_array()); json_object_set_new(message, "id", json_integer(42)); - ASSERT_FALSE(wf_impl_jsonrpc_is_response(message)); + ASSERT_FALSE(wf_jsonrpc_is_response(message)); json_decref(message); } diff --git a/test/webfuse/tests/adapter/jsonrpc/test_proxy.cc b/lib/wf/jsonrpc/test/wf/jsonrpc/test_proxy.cc similarity index 53% rename from test/webfuse/tests/adapter/jsonrpc/test_proxy.cc rename to lib/wf/jsonrpc/test/wf/jsonrpc/test_proxy.cc index 8f99312..66eafa9 100644 --- a/test/webfuse/tests/adapter/jsonrpc/test_proxy.cc +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/test_proxy.cc @@ -1,14 +1,23 @@ #include -#include "webfuse/adapter/impl/jsonrpc/proxy.h" -#include "webfuse/adapter/impl/time/timeout_manager.h" -#include "webfuse/utils/msleep.hpp" +#include "wf/jsonrpc/proxy.h" +#include "wf/jsonrpc/status.h" +#include "wf/timer/manager.h" + +#include +#include + +using namespace std::chrono_literals; -using webfuse_test::msleep; #define WF_DEFAULT_TIMEOUT (10 * 1000) namespace { + int jsonrpc_get_status(json_t * error) + { + json_t * code = json_object_get(error, "code"); + return (json_is_integer(code)) ? json_integer_value(code) : WF_JSONRPC_BAD_FORMAT; + } struct SendContext { @@ -47,13 +56,13 @@ namespace struct FinishedContext { bool is_called; - wf_status status; json_t * result; + json_t * error; FinishedContext() : is_called(false) - , status(WF_BAD) , result(nullptr) + , error(nullptr) { } @@ -64,50 +73,51 @@ namespace { json_decref(result); } + + if (nullptr != error) + { + json_decref(error); + } } }; void jsonrpc_finished( void * user_data, - wf_status status, - struct json_t const * result) + json_t const * result, + json_t const * error) { FinishedContext * context = reinterpret_cast(user_data); context->is_called = true; - context->status = status; context->result = json_deep_copy(result); + context->error = json_deep_copy(error); } } -TEST(jsonrpc_proxy, init) +TEST(wf_jsonrpc_proxy, init) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext context; void * user_data = reinterpret_cast(&context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, user_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, user_data); - wf_impl_jsonrpc_proxy_cleanup(&proxy); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); ASSERT_FALSE(context.is_called); } -TEST(jsonrpc_proxy, invoke) +TEST(wf_jsonrpc_proxy, invoke) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext send_context; void * send_data = reinterpret_cast(&send_context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); FinishedContext finished_context; void * finished_data = reinterpret_cast(&finished_context); - wf_impl_jsonrpc_proxy_invoke(&proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); + wf_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); ASSERT_TRUE(json_is_object(send_context.response)); @@ -129,54 +139,50 @@ TEST(jsonrpc_proxy, invoke) ASSERT_FALSE(finished_context.is_called); - wf_impl_jsonrpc_proxy_cleanup(&proxy); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); ASSERT_TRUE(finished_context.is_called); - ASSERT_FALSE(WF_GOOD == finished_context.status); + ASSERT_FALSE(nullptr == finished_context.error); } -TEST(jsonrpc_proxy, invoke_calls_finish_if_send_fails) +TEST(wf_jsonrpc_proxy, invoke_calls_finish_if_send_fails) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext send_context(false); void * send_data = reinterpret_cast(&send_context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); FinishedContext finished_context; void * finished_data = reinterpret_cast(&finished_context); - wf_impl_jsonrpc_proxy_invoke(&proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); + wf_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); ASSERT_TRUE(json_is_object(send_context.response)); ASSERT_TRUE(finished_context.is_called); - ASSERT_FALSE(WF_GOOD == finished_context.status); + ASSERT_FALSE(nullptr == finished_context.error); - wf_impl_jsonrpc_proxy_cleanup(&proxy); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); } -TEST(jsonrpc_proxy, invoke_fails_if_another_request_is_pending) +TEST(wf_jsonrpc_proxy, invoke_fails_if_another_request_is_pending) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext send_context; void * send_data = reinterpret_cast(&send_context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); FinishedContext finished_context; void * finished_data = reinterpret_cast(&finished_context); - wf_impl_jsonrpc_proxy_invoke(&proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); + wf_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); FinishedContext finished_context2; void * finished_data2 = reinterpret_cast(&finished_context2); - wf_impl_jsonrpc_proxy_invoke(&proxy, &jsonrpc_finished, finished_data2, "foo", ""); + wf_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data2, "foo", ""); ASSERT_TRUE(send_context.is_called); ASSERT_TRUE(json_is_object(send_context.response)); @@ -184,48 +190,44 @@ TEST(jsonrpc_proxy, invoke_fails_if_another_request_is_pending) ASSERT_FALSE(finished_context.is_called); ASSERT_TRUE(finished_context2.is_called); - ASSERT_EQ(WF_BAD_BUSY, finished_context2.status); + ASSERT_EQ(WF_JSONRPC_BAD_BUSY, jsonrpc_get_status(finished_context2.error)); - wf_impl_jsonrpc_proxy_cleanup(&proxy); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); } -TEST(jsonrpc_proxy, invoke_fails_if_request_is_invalid) +TEST(wf_jsonrpc_proxy, invoke_fails_if_request_is_invalid) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext send_context; void * send_data = reinterpret_cast(&send_context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); FinishedContext finished_context; void * finished_data = reinterpret_cast(&finished_context); - wf_impl_jsonrpc_proxy_invoke(&proxy, &jsonrpc_finished, finished_data, "foo", "?", "error"); + wf_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "?", "error"); ASSERT_FALSE(send_context.is_called); ASSERT_TRUE(finished_context.is_called); - ASSERT_EQ(WF_BAD, finished_context.status); + ASSERT_EQ(WF_JSONRPC_BAD, jsonrpc_get_status(finished_context.error)); - wf_impl_jsonrpc_proxy_cleanup(&proxy); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); } -TEST(jsonrpc_proxy, on_result) +TEST(wf_jsonrpc_proxy, on_result) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext send_context; void * send_data = reinterpret_cast(&send_context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); FinishedContext finished_context; void * finished_data = reinterpret_cast(&finished_context); - wf_impl_jsonrpc_proxy_invoke(&proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); + wf_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); ASSERT_TRUE(json_is_object(send_context.response)); @@ -237,31 +239,29 @@ TEST(jsonrpc_proxy, on_result) json_object_set_new(response, "result", json_string("okay")); json_object_set(response, "id", id); - wf_impl_jsonrpc_proxy_onresult(&proxy, response); + wf_jsonrpc_proxy_onresult(proxy, response); json_decref(response); ASSERT_TRUE(finished_context.is_called); - ASSERT_EQ(WF_GOOD, finished_context.status); + ASSERT_EQ(nullptr, finished_context.error); ASSERT_TRUE(json_is_string(finished_context.result)); ASSERT_STREQ("okay", json_string_value(finished_context.result)); - wf_impl_jsonrpc_proxy_cleanup(&proxy); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); } -TEST(jsonrpc_proxy, on_result_reject_response_with_unknown_id) +TEST(wf_jsonrpc_proxy, on_result_reject_response_with_unknown_id) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext send_context; void * send_data = reinterpret_cast(&send_context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); FinishedContext finished_context; void * finished_data = reinterpret_cast(&finished_context); - wf_impl_jsonrpc_proxy_invoke(&proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); + wf_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); ASSERT_TRUE(json_is_object(send_context.response)); @@ -273,83 +273,75 @@ TEST(jsonrpc_proxy, on_result_reject_response_with_unknown_id) json_object_set_new(response, "result", json_string("okay")); json_object_set_new(response, "id", json_integer(1 + json_integer_value(id))); - wf_impl_jsonrpc_proxy_onresult(&proxy, response); + wf_jsonrpc_proxy_onresult(proxy, response); json_decref(response); ASSERT_FALSE(finished_context.is_called); - wf_impl_jsonrpc_proxy_cleanup(&proxy); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); } -TEST(jsonrpc_proxy, timeout) +TEST(wf_jsonrpc_proxy, timeout) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext send_context; void * send_data = reinterpret_cast(&send_context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, 0, &jsonrpc_send, send_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, 0, &jsonrpc_send, send_data); FinishedContext finished_context; void * finished_data = reinterpret_cast(&finished_context); - wf_impl_jsonrpc_proxy_invoke(&proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); + wf_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); ASSERT_TRUE(json_is_object(send_context.response)); - msleep(10); - wf_impl_timeout_manager_check(&timeout_manager); + std::this_thread::sleep_for(10ms); + wf_timer_manager_check(timer_manager); ASSERT_TRUE(finished_context.is_called); - ASSERT_EQ(WF_BAD_TIMEOUT, finished_context.status); + ASSERT_EQ(WF_JSONRPC_BAD_TIMEOUT, jsonrpc_get_status(finished_context.error)); - wf_impl_jsonrpc_proxy_cleanup(&proxy); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); } -TEST(jsonrpc_proxy, cleanup_pending_request) +TEST(wf_jsonrpc_proxy, cleanup_pending_request) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext send_context; void * send_data = reinterpret_cast(&send_context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, 10, &jsonrpc_send, send_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, 10, &jsonrpc_send, send_data); FinishedContext finished_context; void * finished_data = reinterpret_cast(&finished_context); - wf_impl_jsonrpc_proxy_invoke(&proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); + wf_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); ASSERT_TRUE(json_is_object(send_context.response)); ASSERT_FALSE(finished_context.is_called); - ASSERT_NE(nullptr, timeout_manager.timers); - wf_impl_jsonrpc_proxy_cleanup(&proxy); + wf_jsonrpc_proxy_dispose(proxy); ASSERT_TRUE(finished_context.is_called); - ASSERT_EQ(nullptr, timeout_manager.timers); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_timer_manager_dispose(timer_manager); } -TEST(jsonrpc_proxy, notify) +TEST(wf_jsonrpc_proxy, notify) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext send_context; void * send_data = reinterpret_cast(&send_context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); - wf_impl_jsonrpc_proxy_notify(&proxy, "foo", "si", "bar", 42); + wf_jsonrpc_proxy_notify(proxy, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); ASSERT_TRUE(json_is_object(send_context.response)); @@ -369,25 +361,22 @@ TEST(jsonrpc_proxy, notify) json_t * id = json_object_get(send_context.response, "id"); ASSERT_EQ(nullptr, id); - - wf_impl_jsonrpc_proxy_cleanup(&proxy); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); } -TEST(jsonrpc_proxy, notify_dont_send_invalid_request) +TEST(wf_jsonrpc_proxy, notify_dont_send_invalid_request) { - struct wf_impl_timeout_manager timeout_manager; - wf_impl_timeout_manager_init(&timeout_manager); + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); SendContext send_context; void * send_data = reinterpret_cast(&send_context); - struct wf_impl_jsonrpc_proxy proxy; - wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); - wf_impl_jsonrpc_proxy_notify(&proxy, "foo", "?"); + wf_jsonrpc_proxy_notify(proxy, "foo", "?"); ASSERT_FALSE(send_context.is_called); - wf_impl_jsonrpc_proxy_cleanup(&proxy); - wf_impl_timeout_manager_cleanup(&timeout_manager); + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); } diff --git a/test/webfuse/tests/adapter/jsonrpc/test_request.cc b/lib/wf/jsonrpc/test/wf/jsonrpc/test_request.cc similarity index 69% rename from test/webfuse/tests/adapter/jsonrpc/test_request.cc rename to lib/wf/jsonrpc/test/wf/jsonrpc/test_request.cc index 07c3da8..eb15e91 100644 --- a/test/webfuse/tests/adapter/jsonrpc/test_request.cc +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/test_request.cc @@ -1,5 +1,6 @@ #include -#include "webfuse/adapter/impl/jsonrpc/request.h" +#include "wf/jsonrpc/request.h" +#include "wf/jsonrpc/status.h" namespace { @@ -22,29 +23,29 @@ bool jsonrpc_send( } -TEST(jsonrpc_request, create_dispose) +TEST(wf_jsonrpc_request, create_dispose) { Context context{nullptr}; void * user_data = reinterpret_cast(&context); - struct wf_impl_jsonrpc_request * request = - wf_impl_jsonrpc_request_create(42, &jsonrpc_send, user_data); + struct wf_jsonrpc_request * request = + wf_jsonrpc_request_create(42, &jsonrpc_send, user_data); ASSERT_NE(nullptr, request); - ASSERT_EQ(user_data, wf_impl_jsonrpc_request_get_userdata(request)); + ASSERT_EQ(user_data, wf_jsonrpc_request_get_userdata(request)); - wf_impl_jsonrpc_request_dispose(request); + wf_jsonrpc_request_dispose(request); } -TEST(jsonrpc_request, respond) +TEST(wf_jsonrpc_request, respond) { Context context{nullptr}; void * user_data = reinterpret_cast(&context); - struct wf_impl_jsonrpc_request * request = - wf_impl_jsonrpc_request_create(42, &jsonrpc_send, user_data); + struct wf_jsonrpc_request * request = + wf_jsonrpc_request_create(42, &jsonrpc_send, user_data); - wf_impl_jsonrpc_respond(request, json_string("okay")); + wf_jsonrpc_respond(request, json_string("okay")); ASSERT_NE(nullptr, context.response); @@ -65,15 +66,15 @@ TEST(jsonrpc_request, respond) json_decref(response); } -TEST(jsonrpc_request, respond_error) +TEST(wf_jsonrpc_request, respond_error) { Context context{nullptr}; void * user_data = reinterpret_cast(&context); - struct wf_impl_jsonrpc_request * request = - wf_impl_jsonrpc_request_create(42, &jsonrpc_send, user_data); + struct wf_jsonrpc_request * request = + wf_jsonrpc_request_create(42, &jsonrpc_send, user_data); - wf_impl_jsonrpc_respond_error(request, WF_BAD); + wf_jsonrpc_respond_error(request, WF_JSONRPC_BAD, "Bad"); ASSERT_NE(nullptr, context.response); @@ -92,7 +93,7 @@ TEST(jsonrpc_request, respond_error) json_t * err_code = json_object_get(err, "code"); ASSERT_TRUE(json_is_integer(err_code)); - ASSERT_EQ(WF_BAD, json_integer_value(err_code)); + ASSERT_EQ(WF_JSONRPC_BAD, json_integer_value(err_code)); json_t * err_message = json_object_get(err, "message"); ASSERT_TRUE(json_is_string(err_message)); diff --git a/lib/wf/jsonrpc/test/wf/jsonrpc/test_response.cc b/lib/wf/jsonrpc/test/wf/jsonrpc/test_response.cc new file mode 100644 index 0000000..e8515aa --- /dev/null +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/test_response.cc @@ -0,0 +1,58 @@ +#include +#include "wf/jsonrpc/impl/response.h" +#include "wf/jsonrpc/status.h" + +TEST(wf_json_response, init_result) +{ + json_t * message = json_object(); + json_object_set_new(message, "result", json_integer(47)); + json_object_set_new(message, "id", json_integer(11)); + + struct wf_jsonrpc_response response; + wf_jsonrpc_impl_response_init(&response, message); + + ASSERT_EQ(nullptr, response.error); + ASSERT_TRUE(json_is_integer(response.result)); + ASSERT_EQ(47, json_integer_value(response.result)); + ASSERT_EQ(11, response.id); + + wf_jsonrpc_impl_response_cleanup(&response); + json_decref(message); +} + +TEST(wf_json_response, init_error) +{ + json_t * message = json_object(); + json_t * err = json_object(); + json_object_set_new(err, "code", json_integer(42)); + json_object_set_new(err, "message", json_string("Don't Panic!")); + json_object_set_new(message, "error", err); + json_object_set_new(message, "id", json_integer(23)); + + struct wf_jsonrpc_response response; + wf_jsonrpc_impl_response_init(&response, message); + + ASSERT_EQ(42, json_integer_value(json_object_get(response.error, "code"))); + ASSERT_STREQ("Don't Panic!", json_string_value(json_object_get(response.error, "message"))); + ASSERT_EQ(nullptr, response.result); + ASSERT_EQ(23, response.id); + + wf_jsonrpc_impl_response_cleanup(&response); + json_decref(message); +} + +TEST(wf_json_response, init_format_error) +{ + json_t * message = json_object(); + json_object_set_new(message, "id", json_integer(12)); + + struct wf_jsonrpc_response response; + wf_jsonrpc_impl_response_init(&response, message); + + ASSERT_EQ(WF_JSONRPC_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code"))); + ASSERT_EQ(nullptr, response.result); + ASSERT_EQ(12, response.id); + + wf_jsonrpc_impl_response_cleanup(&response); + json_decref(message); +} diff --git a/test/webfuse/tests/adapter/test_response_parser.cc b/lib/wf/jsonrpc/test/wf/jsonrpc/test_response_parser.cc similarity index 59% rename from test/webfuse/tests/adapter/test_response_parser.cc rename to lib/wf/jsonrpc/test/wf/jsonrpc/test_response_parser.cc index db7fe2f..e3301fa 100644 --- a/test/webfuse/tests/adapter/test_response_parser.cc +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/test_response_parser.cc @@ -1,54 +1,58 @@ #include #include -#include "webfuse/adapter/impl/jsonrpc/response.h" +#include "wf/jsonrpc/impl/response.h" static void response_parse_str( std::string const & buffer, - struct wf_impl_jsonrpc_response * response) + struct wf_jsonrpc_response * response) { json_t * message = json_loadb(buffer.c_str(), buffer.size(), 0, nullptr); if (nullptr != message) { - wf_impl_jsonrpc_response_init(response, message); + wf_jsonrpc_impl_response_init(response, message); json_decref(message); } } TEST(response_parser, test) { - struct wf_impl_jsonrpc_response response; + struct wf_jsonrpc_response response; // no object response_parse_str("[]", &response); - ASSERT_NE(WF_GOOD, response.status); + ASSERT_NE(nullptr, response.error); ASSERT_EQ(-1, response.id); ASSERT_EQ(nullptr, response.result); + wf_jsonrpc_impl_response_cleanup(&response); // empty response_parse_str("{}", &response); - ASSERT_NE(WF_GOOD, response.status); + ASSERT_NE(nullptr, response.error); ASSERT_EQ(-1, response.id); ASSERT_EQ(nullptr, response.result); + wf_jsonrpc_impl_response_cleanup(&response); // no data response_parse_str("{\"id\":42}", &response); - ASSERT_NE(WF_GOOD, response.status); + ASSERT_NE(nullptr, response.error); ASSERT_EQ(42, response.id); ASSERT_EQ(nullptr, response.result); + wf_jsonrpc_impl_response_cleanup(&response); // custom error code response_parse_str("{\"error\":{\"code\": 42}, \"id\": 42}", &response); - ASSERT_NE(WF_GOOD, response.status); - ASSERT_EQ(42, response.status); + ASSERT_NE(nullptr, response.error); + ASSERT_EQ(42, json_integer_value(json_object_get(response.error, "code"))); ASSERT_EQ(42, response.id); ASSERT_EQ(nullptr, response.result); + wf_jsonrpc_impl_response_cleanup(&response); // valid response response_parse_str("{\"result\": true, \"id\": 42}", &response); - ASSERT_EQ(WF_GOOD, response.status); + ASSERT_EQ(nullptr, response.error); ASSERT_EQ(42, response.id); ASSERT_NE(nullptr, response.result); - json_decref(response.result); + wf_jsonrpc_impl_response_cleanup(&response); } diff --git a/test/webfuse/tests/adapter/jsonrpc/test_server.cc b/lib/wf/jsonrpc/test/wf/jsonrpc/test_server.cc similarity index 70% rename from test/webfuse/tests/adapter/jsonrpc/test_server.cc rename to lib/wf/jsonrpc/test/wf/jsonrpc/test_server.cc index 20d5d0f..14f7ac5 100644 --- a/test/webfuse/tests/adapter/jsonrpc/test_server.cc +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/test_server.cc @@ -1,6 +1,7 @@ #include -#include "webfuse/adapter/impl/jsonrpc/server.h" -#include "webfuse/adapter/impl/jsonrpc/request.h" +#include "wf/jsonrpc/server.h" +#include "wf/jsonrpc/request.h" +#include "wf/jsonrpc/status.h" namespace { @@ -23,7 +24,7 @@ namespace } void sayHello( - struct wf_impl_jsonrpc_request * request, + struct wf_jsonrpc_request * request, char const * method_name, json_t * params, void * user_data) @@ -33,16 +34,15 @@ namespace (void) user_data; json_t * result = json_string("Hello"); - wf_impl_jsonrpc_respond(request, result); + wf_jsonrpc_respond(request, result); } } -TEST(jsonrpc_server, process_request) +TEST(wf_jsonrpc_server, process_request) { - struct wf_impl_jsonrpc_server server; - wf_impl_jsonrpc_server_init(&server); - wf_impl_jsonrpc_server_add(&server, "sayHello", &sayHello, nullptr); + struct wf_jsonrpc_server * server = wf_jsonrpc_server_create(); + wf_jsonrpc_server_add(server, "sayHello", &sayHello, nullptr); Context context{nullptr, false}; void * user_data = reinterpret_cast(&context); @@ -50,7 +50,7 @@ TEST(jsonrpc_server, process_request) json_object_set_new(request, "method", json_string("sayHello")); json_object_set_new(request, "params", json_array()); json_object_set_new(request, "id", json_integer(23)); - wf_impl_jsonrpc_server_process(&server, request, &jsonrpc_send, user_data); + wf_jsonrpc_server_process(server, request, &jsonrpc_send, user_data); ASSERT_TRUE(context.is_called); ASSERT_NE(nullptr, context.response); @@ -66,14 +66,13 @@ TEST(jsonrpc_server, process_request) json_decref(context.response); json_decref(request); - wf_impl_jsonrpc_server_cleanup(&server); + wf_jsonrpc_server_dispose(server); } -TEST(jsonrpc_server, invoke_unknown_method) +TEST(wf_jsonrpc_server, invoke_unknown_method) { - struct wf_impl_jsonrpc_server server; - wf_impl_jsonrpc_server_init(&server); - wf_impl_jsonrpc_server_add(&server, "sayHello", &sayHello, nullptr); + struct wf_jsonrpc_server * server = wf_jsonrpc_server_create(); + wf_jsonrpc_server_add(server, "sayHello", &sayHello, nullptr); Context context{nullptr, false}; void * user_data = reinterpret_cast(&context); @@ -81,7 +80,7 @@ TEST(jsonrpc_server, invoke_unknown_method) json_object_set_new(request, "method", json_string("greet")); json_object_set_new(request, "params", json_array()); json_object_set_new(request, "id", json_integer(42)); - wf_impl_jsonrpc_server_process(&server, request, &jsonrpc_send, user_data); + wf_jsonrpc_server_process(server, request, &jsonrpc_send, user_data); ASSERT_TRUE(context.is_called); ASSERT_NE(nullptr, context.response); @@ -96,30 +95,29 @@ TEST(jsonrpc_server, invoke_unknown_method) json_t * err_code = json_object_get(err, "code"); ASSERT_TRUE(json_is_integer(err_code)); - ASSERT_EQ(WF_BAD_NOTIMPLEMENTED, json_integer_value(err_code)); + ASSERT_EQ(WF_JSONRPC_BAD_NOTIMPLEMENTED, json_integer_value(err_code)); json_t * err_message = json_object_get(err, "message"); ASSERT_TRUE(json_is_string(err_message)); json_decref(context.response); json_decref(request); - wf_impl_jsonrpc_server_cleanup(&server); + wf_jsonrpc_server_dispose(server); } -TEST(jsonrpc_server, skip_invalid_request) +TEST(wf_jsonrpc_server, skip_invalid_request) { - struct wf_impl_jsonrpc_server server; - wf_impl_jsonrpc_server_init(&server); + struct wf_jsonrpc_server * server = wf_jsonrpc_server_create(); Context context{nullptr, false}; void * user_data = reinterpret_cast(&context); json_t * request = json_object(); json_object_set_new(request, "method", json_string("sayHello")); json_object_set_new(request, "params", json_array()); - wf_impl_jsonrpc_server_process(&server, request, &jsonrpc_send, user_data); + wf_jsonrpc_server_process(server, request, &jsonrpc_send, user_data); ASSERT_FALSE(context.is_called); json_decref(request); - wf_impl_jsonrpc_server_cleanup(&server); + wf_jsonrpc_server_dispose(server); } diff --git a/lib/wf/timer/include/wf/timer.h b/lib/wf/timer/include/wf/timer.h new file mode 100644 index 0000000..341792b --- /dev/null +++ b/lib/wf/timer/include/wf/timer.h @@ -0,0 +1,9 @@ +#ifndef WF_TIMER_H +#define WF_TIMER_H + +#include +#include +#include +#include + +#endif diff --git a/lib/wf/timer/include/wf/timer/api.h b/lib/wf/timer/include/wf/timer/api.h new file mode 100644 index 0000000..c327ba7 --- /dev/null +++ b/lib/wf/timer/include/wf/timer/api.h @@ -0,0 +1,8 @@ +#ifndef WF_TIMER_API_H +#define WF_TIMER_API_H + +#ifndef WF_TIMER_API +#define WF_TIMER_API +#endif + +#endif diff --git a/lib/wf/timer/include/wf/timer/manager.h b/lib/wf/timer/include/wf/timer/manager.h new file mode 100644 index 0000000..e0febc0 --- /dev/null +++ b/lib/wf/timer/include/wf/timer/manager.h @@ -0,0 +1,29 @@ +#ifndef WF_TIMER_MANAGER_H +#define WF_TIMER_MANAGER_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_timer_manager; + +extern WF_TIMER_API struct wf_timer_manager * +wf_timer_manager_create(void); + +extern WF_TIMER_API void +wf_timer_manager_dispose( + struct wf_timer_manager * manager); + +extern WF_TIMER_API void +wf_timer_manager_check( + struct wf_timer_manager * manager); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/lib/wf/timer/include/wf/timer/on_timer_fn.h b/lib/wf/timer/include/wf/timer/on_timer_fn.h new file mode 100644 index 0000000..d250bae --- /dev/null +++ b/lib/wf/timer/include/wf/timer/on_timer_fn.h @@ -0,0 +1,19 @@ +#ifndef WF_TIMER_ON_TIMER_FN_H +#define WF_TIMER_ON_TIMER_FN_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_timer; + +typedef void wf_timer_on_timer_fn( + struct wf_timer * timer, + void * user_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/wf/timer/include/wf/timer/timer.h b/lib/wf/timer/include/wf/timer/timer.h new file mode 100644 index 0000000..686eb89 --- /dev/null +++ b/lib/wf/timer/include/wf/timer/timer.h @@ -0,0 +1,38 @@ +#ifndef WF_TIMER_TIMER_H +#define WF_TIMER_TIMER_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_timer; +struct wf_timer_manager; + +extern WF_TIMER_API struct wf_timer * +wf_timer_create( + struct wf_timer_manager * manager, + wf_timer_on_timer_fn * on_timer, + void * user_data); + +extern WF_TIMER_API void +wf_timer_dispose( + struct wf_timer * timer); + +extern WF_TIMER_API void +wf_timer_start( + struct wf_timer * timer, + int timeout_ms); + +extern WF_TIMER_API void +wf_timer_cancel( + struct wf_timer * timer); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/wf/timer/src/wf/timer/api.c b/lib/wf/timer/src/wf/timer/api.c new file mode 100644 index 0000000..d0399a9 --- /dev/null +++ b/lib/wf/timer/src/wf/timer/api.c @@ -0,0 +1,59 @@ +#include "wf/timer.h" + +#include "wf/timer/impl/manager.h" +#include "wf/timer/impl/timer.h" + +// manager + +struct wf_timer_manager * +wf_timer_manager_create(void) +{ + return wf_timer_impl_manager_create(); +} + +void +wf_timer_manager_dispose( + struct wf_timer_manager * manager) +{ + wf_timer_impl_manager_dispose(manager); +} + +void +wf_timer_manager_check( + struct wf_timer_manager * manager) +{ + wf_timer_impl_manager_check(manager); +} + +// timer + +struct wf_timer * +wf_timer_create( + struct wf_timer_manager * manager, + wf_timer_on_timer_fn * on_timer, + void * user_data) +{ + return wf_timer_impl_create(manager, on_timer, user_data); +} + +void +wf_timer_dispose( + struct wf_timer * timer) +{ + wf_timer_impl_dispose(timer); +} + +void +wf_timer_start( + struct wf_timer * timer, + int timeout_ms) +{ + wf_timer_impl_start(timer, timeout_ms); +} + +void +wf_timer_cancel( + struct wf_timer * timer) +{ + wf_timer_impl_cancel(timer); +} diff --git a/lib/wf/timer/src/wf/timer/impl/manager.c b/lib/wf/timer/src/wf/timer/impl/manager.c new file mode 100644 index 0000000..2b00f80 --- /dev/null +++ b/lib/wf/timer/src/wf/timer/impl/manager.c @@ -0,0 +1,96 @@ +#include "wf/timer/impl/manager.h" +#include "wf/timer/impl/timer.h" +#include "wf/timer/impl/timepoint.h" + +#include +#include + +struct wf_timer_manager +{ + struct wf_timer * timers; +}; + +struct wf_timer_manager * +wf_timer_impl_manager_create(void) +{ + struct wf_timer_manager * manager = malloc(sizeof(struct wf_timer_manager)); + if (NULL != manager) + { + manager->timers = NULL; + } + + return manager; +} + +void +wf_timer_impl_manager_dispose( + struct wf_timer_manager * manager) +{ + struct wf_timer * timer = manager->timers; + while (NULL != timer) + { + struct wf_timer * next = timer->next; + + wf_timer_impl_trigger(timer); + timer = next; + } + + free(manager); +} + + +void wf_timer_impl_manager_check( + struct wf_timer_manager * manager) +{ + struct wf_timer * timer = manager->timers; + while (NULL != timer) + { + struct wf_timer * next = timer->next; + + if (wf_timer_impl_is_timeout(timer)) + { + wf_timer_impl_manager_removetimer(manager, timer); + wf_timer_impl_trigger(timer); + } + + timer = next; + } +} + +void wf_timer_impl_manager_addtimer( + struct wf_timer_manager * manager, + struct wf_timer * timer) +{ + if (NULL != manager->timers) + { + manager->timers->prev = timer; + } + + timer->next = manager->timers; + timer->prev = NULL; + manager->timers = timer; +} + +void wf_timer_impl_manager_removetimer( + struct wf_timer_manager * manager, + struct wf_timer * timer) +{ + struct wf_timer * prev = timer->prev; + struct wf_timer * next = timer->next; + + if (NULL != prev) + { + prev->next = next; + } + + if (NULL != next) + { + next->prev = prev; + } + + if (manager->timers == timer) + { + manager->timers = next; + } +} + diff --git a/lib/wf/timer/src/wf/timer/impl/manager.h b/lib/wf/timer/src/wf/timer/impl/manager.h new file mode 100644 index 0000000..c4fc64a --- /dev/null +++ b/lib/wf/timer/src/wf/timer/impl/manager.h @@ -0,0 +1,36 @@ +#ifndef WF_TIMER_IMPL_MANAGER_H +#define WF_TIMER_IMPL_MANAGER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_timer; +struct wf_timer_manager; + +extern struct wf_timer_manager * +wf_timer_impl_manager_create(void); + +extern void +wf_timer_impl_manager_dispose( + struct wf_timer_manager * manager); + +extern void +wf_timer_impl_manager_check( + struct wf_timer_manager * manager); + +extern void wf_timer_impl_manager_addtimer( + struct wf_timer_manager * manager, + struct wf_timer * timer); + +extern void wf_timer_impl_manager_removetimer( + struct wf_timer_manager * manager, + struct wf_timer * timer); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/lib/wf/timer/src/wf/timer/impl/timepoint.c b/lib/wf/timer/src/wf/timer/impl/timepoint.c new file mode 100644 index 0000000..877b9c9 --- /dev/null +++ b/lib/wf/timer/src/wf/timer/impl/timepoint.c @@ -0,0 +1,31 @@ +#include "wf/timer/impl/timepoint.h" + +#include + +#define WF_TIMER_MSEC_PER_SEC ((wf_timer_timepoint) 1000) +#define WF_TIMER_NSEC_PER_MSEC ((wf_timer_timepoint) 1000 * 1000) + +wf_timer_timepoint wf_timer_impl_timepoint_now(void) +{ + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC, &tp); + + wf_timer_timepoint const now = (tp.tv_sec * WF_TIMER_MSEC_PER_SEC) + (tp.tv_nsec / WF_TIMER_NSEC_PER_MSEC); + return now; +} + +wf_timer_timepoint wf_timer_impl_timepoint_in_msec(wf_timer_timediff value) +{ + wf_timer_timepoint const now = wf_timer_impl_timepoint_now(); + wf_timer_timepoint result = now + ((wf_timer_timepoint) value); + + return result; +} + +bool wf_timer_impl_timepoint_is_elapsed(wf_timer_timepoint tp) +{ + wf_timer_timepoint const now = wf_timer_impl_timepoint_now(); + wf_timer_timediff const diff = (wf_timer_timediff) (tp - now); + + return (0 > diff); +} diff --git a/lib/wf/timer/src/wf/timer/impl/timepoint.h b/lib/wf/timer/src/wf/timer/impl/timepoint.h new file mode 100644 index 0000000..584aa92 --- /dev/null +++ b/lib/wf/timer/src/wf/timer/impl/timepoint.h @@ -0,0 +1,31 @@ +#ifndef WF_TIMER_IMPL_TIMEPOINT_H +#define WF_TIMER_IMPL_TIMEPOINT_H + +#ifndef __cplusplus +#include +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef uint64_t wf_timer_timepoint; +typedef int64_t wf_timer_timediff; + +extern wf_timer_timepoint wf_timer_impl_timepoint_now(void); + +extern wf_timer_timepoint wf_timer_impl_timepoint_in_msec( + wf_timer_timediff value); + +extern bool wf_timer_impl_timepoint_is_elapsed( + wf_timer_timepoint timepoint); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/wf/timer/src/wf/timer/impl/timer.c b/lib/wf/timer/src/wf/timer/impl/timer.c new file mode 100644 index 0000000..5559451 --- /dev/null +++ b/lib/wf/timer/src/wf/timer/impl/timer.c @@ -0,0 +1,67 @@ +#include "wf/timer/impl/timer.h" +#include "wf/timer/impl/manager.h" +#include "wf/timer/impl/timepoint.h" + +#include +#include +#include + +struct wf_timer * +wf_timer_impl_create( + struct wf_timer_manager * manager, + wf_timer_on_timer_fn * on_timer, + void * user_data) +{ + struct wf_timer * timer = malloc(sizeof(struct wf_timer)); + timer->manager = manager; + timer->timeout = 0; + timer->on_timer = on_timer; + timer->user_data = user_data; + timer->prev = NULL; + timer->next = NULL; + + return timer; +} + +void +wf_timer_impl_dispose( + struct wf_timer * timer) +{ + free(timer); +} + +void wf_timer_impl_start( + struct wf_timer * timer, + int timeout_ms) +{ + timer->timeout = wf_timer_impl_timepoint_in_msec(timeout_ms); + + wf_timer_impl_manager_addtimer(timer->manager, timer); +} + +void wf_timer_impl_cancel( + struct wf_timer * timer) +{ + wf_timer_impl_manager_removetimer(timer->manager, timer); + + timer->timeout = 0; +} + +bool wf_timer_impl_is_timeout( + struct wf_timer * timer) +{ + return wf_timer_impl_timepoint_is_elapsed(timer->timeout); +} + + +void wf_timer_impl_trigger( + struct wf_timer * timer) +{ + if (0 != timer->on_timer) + { + timer->prev = NULL; + timer->next = NULL; + + timer->on_timer(timer, timer->user_data); + } +} diff --git a/lib/wf/timer/src/wf/timer/impl/timer.h b/lib/wf/timer/src/wf/timer/impl/timer.h new file mode 100644 index 0000000..2e18a8b --- /dev/null +++ b/lib/wf/timer/src/wf/timer/impl/timer.h @@ -0,0 +1,59 @@ +#ifndef WF_ADAPTER_IMPL_TIME_TIMER_H +#define WF_ADAPTER_IMPL_TIME_TIMER_H + +#include "wf/timer/on_timer_fn.h" +#include "wf/timer/impl/timepoint.h" + +#ifndef __cplusplus +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_timer_manager; + +struct wf_timer +{ + struct wf_timer_manager * manager; + wf_timer_timepoint timeout; + wf_timer_on_timer_fn * on_timer; + void * user_data; + struct wf_timer * next; + struct wf_timer * prev; +}; + + +struct wf_timer * +wf_timer_impl_create( + struct wf_timer_manager * manager, + wf_timer_on_timer_fn * on_timer, + void * user_data); + +void +wf_timer_impl_dispose( + struct wf_timer * timer); + +extern void wf_timer_impl_start( + struct wf_timer * timer, + int timeout_ms); + +extern void wf_timer_impl_cancel( + struct wf_timer * timer); + +extern bool wf_timer_impl_is_timeout( + struct wf_timer * timer); + +extern void wf_timer_impl_trigger( + struct wf_timer * timer); + + +#ifdef __cplusplus +} +#endif + + + +#endif diff --git a/lib/wf/timer/test/wf/timer/test_timepoint.cc b/lib/wf/timer/test/wf/timer/test_timepoint.cc new file mode 100644 index 0000000..723ff6a --- /dev/null +++ b/lib/wf/timer/test/wf/timer/test_timepoint.cc @@ -0,0 +1,38 @@ +#include + +#include "wf/timer/impl/timepoint.h" + +#include +#include + +using namespace std::chrono_literals; + +TEST(wf_timer_timepoint, now) +{ + wf_timer_timepoint start = wf_timer_impl_timepoint_now(); + std::this_thread::sleep_for(42ms); + wf_timer_timepoint end = wf_timer_impl_timepoint_now(); + + ASSERT_LT(start, end); + ASSERT_LT(end, start + 500); +} + +TEST(wf_timer_timepoint, in_msec) +{ + wf_timer_timepoint now = wf_timer_impl_timepoint_now(); + wf_timer_timepoint later = wf_timer_impl_timepoint_in_msec(42); + + ASSERT_LT(now, later); + ASSERT_LT(later, now + 500); +} + +TEST(wf_timer_timepoint, elapsed) +{ + wf_timer_timepoint now; + + now = wf_timer_impl_timepoint_now(); + ASSERT_TRUE(wf_timer_impl_timepoint_is_elapsed(now - 1)); + + now = wf_timer_impl_timepoint_now(); + ASSERT_FALSE(wf_timer_impl_timepoint_is_elapsed(now + 500)); +} diff --git a/lib/wf/timer/test/wf/timer/test_timer.cc b/lib/wf/timer/test/wf/timer/test_timer.cc new file mode 100644 index 0000000..e97c011 --- /dev/null +++ b/lib/wf/timer/test/wf/timer/test_timer.cc @@ -0,0 +1,137 @@ +#include + +#include +#include +#include + +#include "wf/timer/timer.h" +#include "wf/timer/manager.h" + +using std::size_t; +using namespace std::chrono_literals; + +extern "C" +{ + void on_timeout(struct wf_timer * timer, void * user_data) + { + (void) timer; + + bool * triggered = reinterpret_cast(user_data); + *triggered = true; + } +} + +TEST(wf_timer, init) +{ + bool triggered = false; + struct wf_timer_manager * manager = wf_timer_manager_create(); + struct wf_timer * timer = wf_timer_create(manager, &on_timeout, reinterpret_cast(&triggered)); + + wf_timer_dispose(timer); + wf_timer_manager_dispose(manager); +} + +TEST(wf_timer, trigger) +{ + bool triggered = false; + struct wf_timer_manager * manager = wf_timer_manager_create(); + struct wf_timer * timer = wf_timer_create(manager, &on_timeout, reinterpret_cast(&triggered)); + + wf_timer_start(timer, 250); + std::this_thread::sleep_for(500ms); + wf_timer_manager_check(manager); + + ASSERT_TRUE(triggered); + + wf_timer_dispose(timer); + wf_timer_manager_dispose(manager); +} + +TEST(wf_timer, trigger_on_dispose) +{ + bool triggered = false; + struct wf_timer_manager * manager = wf_timer_manager_create(); + struct wf_timer * timer = wf_timer_create(manager, &on_timeout, reinterpret_cast(&triggered)); + + wf_timer_start(timer, (5 * 60 * 1000)); + + wf_timer_manager_dispose(manager); + ASSERT_TRUE(triggered); + + wf_timer_dispose(timer); +} + +TEST(wf_timer, cancel) +{ + bool triggered = false; + struct wf_timer_manager * manager = wf_timer_manager_create(); + struct wf_timer * timer = wf_timer_create(manager, &on_timeout, reinterpret_cast(&triggered)); + + wf_timer_start(timer, 250); + std::this_thread::sleep_for(500ms); + wf_timer_cancel(timer); + wf_timer_manager_check(manager); + + ASSERT_FALSE(triggered); + + wf_timer_dispose(timer); + wf_timer_manager_dispose(manager); +} + +TEST(wf_timer, cancel_multiple_timers) +{ + static size_t const count = 5; + struct wf_timer_manager * manager = wf_timer_manager_create(); + struct wf_timer * timer[count]; + + bool triggered = false; + for(size_t i = 0; i < count; i++) + { + timer[i] = wf_timer_create(manager, &on_timeout, reinterpret_cast(&triggered)); + wf_timer_start(timer[i], 0); + } + + std::this_thread::sleep_for(10ms); + for(size_t i = 0; i < count; i++) + { + wf_timer_cancel(timer[i]); + } + + wf_timer_manager_check(manager); + ASSERT_FALSE(triggered); + + for(size_t i = 0; i < count; i++) + { + wf_timer_dispose(timer[i]); + } + wf_timer_manager_dispose(manager); +} + +TEST(wf_timer, multiple_timers) +{ + static size_t const count = 5; + struct wf_timer_manager * manager = wf_timer_manager_create(); + struct wf_timer * timer[count]; + bool triggered[count]; + + for(size_t i = 0; i < count; i++) + { + timer[i] = wf_timer_create(manager, &on_timeout, reinterpret_cast(&triggered[i])); + triggered[i] = false; + wf_timer_start(timer[i], (300 - (50 * i))); + } + + for(size_t i = 0; i < count; i++) + { + std::this_thread::sleep_for(100ms); + wf_timer_manager_check(manager); + } + + for(size_t i = 0; i < count; i++) + { + ASSERT_TRUE(triggered[i]); + wf_timer_dispose(timer[i]); + } + + wf_timer_manager_dispose(manager); +} diff --git a/test/webfuse/mocks/mock_provider_client.cc b/test/webfuse/mocks/mock_provider_client.cc index a624ba3..ff73bd9 100644 --- a/test/webfuse/mocks/mock_provider_client.cc +++ b/test/webfuse/mocks/mock_provider_client.cc @@ -167,6 +167,22 @@ static void webfuse_test_iproviderclient_onread( delete[] data; } +static void webfuse_test_iproviderclient_get_credentials( + wfp_credentials * credentials, + void * user_data) +{ + auto * self = reinterpret_cast(user_data); + + try + { + self->GetCredentials(credentials); + } + catch (...) + { + // swallow + } +} + } namespace webfuse_test @@ -185,7 +201,7 @@ wf_status ProviderClientException::GetErrorCode() } -void IProviderClient::AttachTo(wfp_client_config * config) +void IProviderClient::AttachTo(wfp_client_config * config, bool enableAuthentication) { void * self = reinterpret_cast(this); wfp_client_config_set_userdata(config, self); @@ -199,6 +215,11 @@ void IProviderClient::AttachTo(wfp_client_config * config) wfp_client_config_set_onopen(config, &webfuse_test_iproviderclient_onopen); wfp_client_config_set_onclose(config, &webfuse_test_iproviderclient_onclose); wfp_client_config_set_onread(config, &webfuse_test_iproviderclient_onread); + + if (enableAuthentication) + { + wfp_client_config_enable_authentication(config, &webfuse_test_iproviderclient_get_credentials); + } } } \ No newline at end of file diff --git a/test/webfuse/mocks/mock_provider_client.hpp b/test/webfuse/mocks/mock_provider_client.hpp index 45fdf91..57db042 100644 --- a/test/webfuse/mocks/mock_provider_client.hpp +++ b/test/webfuse/mocks/mock_provider_client.hpp @@ -16,8 +16,6 @@ namespace webfuse_test private: wf_status error_code_; }; - - class IProviderClient { @@ -32,8 +30,9 @@ namespace webfuse_test virtual void Open(ino_t inode, int flags, uint32_t * handle) = 0; virtual void Close(ino_t inode, uint32_t handle, int flags) = 0; virtual void Read(ino_t inode, uint32_t handle, size_t offset, size_t length, char * buffer, size_t * bytes_read) = 0; + virtual void GetCredentials(wfp_credentials * credentials) = 0; - void AttachTo(wfp_client_config * config); + void AttachTo(wfp_client_config * config, bool enableAuthentication = false); }; class MockProviderClient: public IProviderClient @@ -49,6 +48,7 @@ namespace webfuse_test MOCK_METHOD3( Open, void(ino_t inode, int flags, uint32_t * handle)); MOCK_METHOD3( Close, void(ino_t inode, uint32_t handle, int flags)); MOCK_METHOD6( Read, void(ino_t inode, uint32_t handle, size_t offset, size_t length, char * buffer, size_t * bytes_read)); + MOCK_METHOD1( GetCredentials, void (wfp_credentials * credentials)); }; } diff --git a/test/webfuse/tests/adapter/jsonrpc/test_response.cc b/test/webfuse/tests/adapter/jsonrpc/test_response.cc deleted file mode 100644 index 3a63d0f..0000000 --- a/test/webfuse/tests/adapter/jsonrpc/test_response.cc +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include "webfuse/adapter/impl/jsonrpc/response.h" - -TEST(json_response, init_result) -{ - json_t * message = json_object(); - json_object_set_new(message, "result", json_integer(47)); - json_object_set_new(message, "id", json_integer(11)); - - struct wf_impl_jsonrpc_response response; - wf_impl_jsonrpc_response_init(&response, message); - - ASSERT_EQ(WF_GOOD, response.status); - ASSERT_TRUE(json_is_integer(response.result)); - ASSERT_EQ(47, json_integer_value(response.result)); - ASSERT_EQ(11, response.id); - - wf_impl_jsonrpc_response_cleanup(&response); - json_decref(message); -} - -TEST(json_response, init_error) -{ - json_t * message = json_object(); - json_t * err = json_object(); - json_object_set_new(err, "code", json_integer(WF_BAD_ACCESS_DENIED)); - json_object_set_new(err, "message", json_string("access denied")); - json_object_set_new(message, "error", err); - json_object_set_new(message, "id", json_integer(23)); - - struct wf_impl_jsonrpc_response response; - wf_impl_jsonrpc_response_init(&response, message); - - ASSERT_EQ(WF_BAD_ACCESS_DENIED, response.status); - ASSERT_EQ(nullptr, response.result); - ASSERT_EQ(23, response.id); - - wf_impl_jsonrpc_response_cleanup(&response); - json_decref(message); -} - -TEST(json_response, init_format_error) -{ - json_t * message = json_object(); - json_object_set_new(message, "id", json_integer(12)); - - struct wf_impl_jsonrpc_response response; - wf_impl_jsonrpc_response_init(&response, message); - - ASSERT_EQ(WF_BAD_FORMAT, response.status); - ASSERT_EQ(nullptr, response.result); - ASSERT_EQ(12, response.id); - - wf_impl_jsonrpc_response_cleanup(&response); - json_decref(message); -} diff --git a/test/webfuse/tests/adapter/test_timepoint.cc b/test/webfuse/tests/adapter/test_timepoint.cc deleted file mode 100644 index 8b0db97..0000000 --- a/test/webfuse/tests/adapter/test_timepoint.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include - -#include "webfuse/utils/msleep.hpp" -#include "webfuse/adapter/impl/time/timepoint.h" - -using webfuse_test::msleep; - -TEST(timepoint, now) -{ - wf_impl_timepoint start = wf_impl_timepoint_now(); - msleep(42); - wf_impl_timepoint end = wf_impl_timepoint_now(); - - ASSERT_LT(start, end); - ASSERT_LT(end, start + 500); -} - -TEST(timepoint, in_msec) -{ - wf_impl_timepoint now = wf_impl_timepoint_now(); - wf_impl_timepoint later = wf_impl_timepoint_in_msec(42); - - ASSERT_LT(now, later); - ASSERT_LT(later, now + 500); -} - -TEST(wf_impl_timepoint, elapsed) -{ - wf_impl_timepoint now; - - now = wf_impl_timepoint_now(); - ASSERT_TRUE(wf_impl_timepoint_is_elapsed(now - 1)); - - now =wf_impl_timepoint_now(); - ASSERT_FALSE(wf_impl_timepoint_is_elapsed(now + 500)); -} diff --git a/test/webfuse/tests/adapter/test_timer.cc b/test/webfuse/tests/adapter/test_timer.cc deleted file mode 100644 index d554f2d..0000000 --- a/test/webfuse/tests/adapter/test_timer.cc +++ /dev/null @@ -1,149 +0,0 @@ -#include - -#include - -#include "webfuse/utils/msleep.hpp" -#include "webfuse/adapter/impl/time/timer.h" -#include "webfuse/adapter/impl/time/timeout_manager.h" - -using std::size_t; -using webfuse_test::msleep; - -namespace -{ - void on_timeout(struct wf_impl_timer * timer) - { - bool * triggered = reinterpret_cast(timer->user_data); - *triggered = true; - } -} - -TEST(timer, init) -{ - struct wf_impl_timeout_manager manager; - struct wf_impl_timer timer; - - wf_impl_timeout_manager_init(&manager); - wf_impl_timer_init(&timer, &manager); - - wf_impl_timer_cleanup(&timer); - wf_impl_timeout_manager_cleanup(&manager); -} - -TEST(timer, trigger) -{ - struct wf_impl_timeout_manager manager; - struct wf_impl_timer timer; - - wf_impl_timeout_manager_init(&manager); - wf_impl_timer_init(&timer, &manager); - - bool triggered = false; - wf_impl_timer_start(&timer, wf_impl_timepoint_in_msec(250), &on_timeout, reinterpret_cast(&triggered)); - msleep(500); - wf_impl_timeout_manager_check(&manager); - - ASSERT_TRUE(triggered); - - wf_impl_timer_cleanup(&timer); - wf_impl_timeout_manager_cleanup(&manager); -} - -TEST(timer, trigger_on_cleanup) -{ - struct wf_impl_timeout_manager manager; - struct wf_impl_timer timer; - - wf_impl_timeout_manager_init(&manager); - wf_impl_timer_init(&timer, &manager); - - bool triggered = false; - wf_impl_timer_start(&timer, wf_impl_timepoint_in_msec(5 * 60 * 1000), &on_timeout, reinterpret_cast(&triggered)); - - wf_impl_timeout_manager_cleanup(&manager); - ASSERT_TRUE(triggered); - - wf_impl_timer_cleanup(&timer); -} - -TEST(timer, cancel) -{ - struct wf_impl_timeout_manager manager; - struct wf_impl_timer timer; - - wf_impl_timeout_manager_init(&manager); - wf_impl_timer_init(&timer, &manager); - - bool triggered = false; - wf_impl_timer_start(&timer, wf_impl_timepoint_in_msec(250), &on_timeout, &triggered); - msleep(500); - wf_impl_timer_cancel(&timer); - wf_impl_timeout_manager_check(&manager); - - ASSERT_FALSE(triggered); - - wf_impl_timer_cleanup(&timer); - wf_impl_timeout_manager_cleanup(&manager); -} - -TEST(timer, cancel_multiple_timers) -{ - static size_t const count = 5; - struct wf_impl_timeout_manager manager; - struct wf_impl_timer timer[count]; - - wf_impl_timeout_manager_init(&manager); - - bool triggered = false; - for(size_t i = 0; i < count; i++) - { - wf_impl_timer_init(&timer[i], &manager); - wf_impl_timer_start(&timer[i], wf_impl_timepoint_in_msec(0), &on_timeout, &triggered); - } - - msleep(10); - for(size_t i = 0; i < count; i++) - { - wf_impl_timer_cancel(&timer[i]); - } - - wf_impl_timeout_manager_check(&manager); - ASSERT_FALSE(triggered); - - for(size_t i = 0; i < count; i++) - { - wf_impl_timer_cleanup(&timer[0]); - } - wf_impl_timeout_manager_cleanup(&manager); -} - -TEST(timer, multiple_timers) -{ - static size_t const count = 5; - struct wf_impl_timeout_manager manager; - struct wf_impl_timer timer[count]; - bool triggered[count]; - - wf_impl_timeout_manager_init(&manager); - - for(size_t i = 0; i < count; i++) - { - wf_impl_timer_init(&timer[i], &manager); - triggered[i] = false; - wf_impl_timer_start(&timer[i], wf_impl_timepoint_in_msec(300 - (50 * i)), &on_timeout, &triggered[i]); - } - - for(size_t i = 0; i < count; i++) - { - msleep(100); - wf_impl_timeout_manager_check(&manager); - } - - for(size_t i = 0; i < count; i++) - { - ASSERT_TRUE(triggered[i]); - wf_impl_timer_cleanup(&timer[i]); - } - - wf_impl_timeout_manager_cleanup(&manager); -} diff --git a/test/webfuse/tests/adapter/jsonrpc/test_util.cc b/test/webfuse/tests/core/test_util.cc similarity index 95% rename from test/webfuse/tests/adapter/jsonrpc/test_util.cc rename to test/webfuse/tests/core/test_util.cc index 562b7c4..3e4b75d 100644 --- a/test/webfuse/tests/adapter/jsonrpc/test_util.cc +++ b/test/webfuse/tests/core/test_util.cc @@ -1,5 +1,5 @@ #include -#include "webfuse/adapter/impl/jsonrpc/util.h" +#include "webfuse/core/json_util.h" TEST(jsonrpc_util, get_int) { diff --git a/test/webfuse/tests/integration/provider.cc b/test/webfuse/tests/integration/provider.cc index 5142ca8..45e331a 100644 --- a/test/webfuse/tests/integration/provider.cc +++ b/test/webfuse/tests/integration/provider.cc @@ -3,10 +3,12 @@ #include "webfuse/provider/impl/client.h" #include #include +#include #include -#include "webfuse/utils/msleep.hpp" #include "webfuse/utils/static_filesystem.h" +using namespace std::chrono_literals; + namespace webfuse_test { @@ -29,7 +31,7 @@ public: } thread = std::thread(Run, this); - webfuse_test::msleep(200); + std::this_thread::sleep_for(200ms); } ~Private() diff --git a/test/webfuse/tests/integration/server.cc b/test/webfuse/tests/integration/server.cc index 1360934..e48f074 100644 --- a/test/webfuse/tests/integration/server.cc +++ b/test/webfuse/tests/integration/server.cc @@ -6,7 +6,6 @@ #include #include "webfuse_adapter.h" #include "webfuse/adapter/impl/server.h" -#include "webfuse/utils/msleep.hpp" #define WF_PATH_MAX (100) @@ -20,7 +19,12 @@ public: : is_shutdown_requested(false) { snprintf(base_dir, WF_PATH_MAX, "%s", "/tmp/webfuse_test_integration_XXXXXX"); - mkdtemp(base_dir); + char const * result = mkdtemp(base_dir); + if (NULL == result) + { + throw std::runtime_error("unable to create temp dir"); + } + config = wf_server_config_create(); wf_server_config_set_port(config, 8080); diff --git a/test/webfuse/tests/provider/test_client_protocol.cc b/test/webfuse/tests/provider/test_client_protocol.cc index ff7be74..3563949 100644 --- a/test/webfuse/tests/provider/test_client_protocol.cc +++ b/test/webfuse/tests/provider/test_client_protocol.cc @@ -15,6 +15,7 @@ using webfuse_test::MockProviderClient; using webfuse_test::IProviderClient; using testing::_; using testing::AtMost; +using testing::Invoke; namespace { @@ -24,10 +25,10 @@ class ClientProtocolFixture ClientProtocolFixture(ClientProtocolFixture const &) = delete; ClientProtocolFixture& operator=(ClientProtocolFixture const &) = delete; public: - explicit ClientProtocolFixture(IProviderClient& client) + explicit ClientProtocolFixture(IProviderClient& client, bool enableAuthentication = false) { config = wfp_client_config_create(); - client.AttachTo(config); + client.AttachTo(config, enableAuthentication); protocol = wfp_client_protocol_create(config); @@ -61,6 +62,47 @@ public: return server->receiveMessage(); } + void AwaitAuthentication( + std::string const & expected_username, + std::string const & expected_password) + { + json_t * request = server->receiveMessage(); + ASSERT_TRUE(json_is_object(request)); + + json_t * method = json_object_get(request, "method"); + ASSERT_TRUE(json_is_string(method)); + ASSERT_STREQ("authenticate", json_string_value(method)); + + json_t * id = json_object_get(request, "id"); + ASSERT_TRUE(json_is_integer(id)); + + json_t * params = json_object_get(request, "params"); + ASSERT_TRUE(json_is_array(params)); + ASSERT_EQ(2, json_array_size(params)); + + json_t * type = json_array_get(params, 0); + ASSERT_TRUE(json_is_string(type)); + ASSERT_STREQ("username", json_string_value(type)); + + json_t * credentials = json_array_get(params, 1); + ASSERT_TRUE(json_is_object(credentials)); + + json_t * username = json_object_get(credentials, "username"); + ASSERT_TRUE(json_is_string(username)); + ASSERT_STREQ(expected_username.c_str(), json_string_value(username)); + + json_t * password = json_object_get(credentials, "password"); + ASSERT_TRUE(json_is_string(password)); + ASSERT_STREQ(expected_password.c_str(), json_string_value(password)); + + json_t * response = json_object(); + json_object_set_new(response, "result", json_object()); + json_object_set(response, "id", id); + server->sendMessage(response); + + json_decref(request); + } + void AwaitAddFilesystem(std::string& filesystemName) { json_t * addFilesystemRequest = server->receiveMessage(); @@ -91,7 +133,6 @@ public: server->sendMessage(response); json_decref(addFilesystemRequest); - } private: @@ -100,9 +141,14 @@ private: wfp_client_protocol * protocol; }; - +void GetCredentials(wfp_credentials * credentials) +{ + wfp_credentials_set_type(credentials, "username"); + wfp_credentials_add(credentials, "username", "bob"); + wfp_credentials_add(credentials, "password", "secret"); } +} TEST(client_protocol, connect) { @@ -120,6 +166,27 @@ TEST(client_protocol, connect) if (HasFatalFailure()) { return; } } +TEST(client_protocol, connect_with_username_authentication) +{ + MockProviderClient provider; + ClientProtocolFixture fixture(provider, true); + + EXPECT_CALL(provider, OnConnected()).Times(AtMost(1)); + EXPECT_CALL(provider, OnDisconnected()).Times(1); + EXPECT_CALL(provider, GetCredentials(_)).Times(1).WillOnce(Invoke(GetCredentials)); + + fixture.Connect(); + if (HasFatalFailure()) { return; } + + fixture.AwaitAuthentication("bob", "secret"); + if (HasFatalFailure()) { return; } + + std::string filesystem; + fixture.AwaitAddFilesystem(filesystem); + if (HasFatalFailure()) { return; } + +} + TEST(client_protocol, getattr) { MockProviderClient provider; diff --git a/test/webfuse/utils/msleep.cc b/test/webfuse/utils/msleep.cc deleted file mode 100644 index 659bb81..0000000 --- a/test/webfuse/utils/msleep.cc +++ /dev/null @@ -1,19 +0,0 @@ -#include "webfuse/utils/msleep.hpp" -#include - -namespace webfuse_test -{ - -void msleep(long millis) -{ - long const secs_per_msec = 1000; - long const msecs_per_nsec = (1000 * 1000); - - long const seconds = millis / secs_per_msec; - long const nanos = (millis % secs_per_msec) * msecs_per_nsec; - - struct timespec timeout = { seconds, nanos }; - while (0 != nanosleep(&timeout, &timeout)); -} - -} \ No newline at end of file diff --git a/test/webfuse/utils/msleep.hpp b/test/webfuse/utils/msleep.hpp deleted file mode 100644 index 47cb1e6..0000000 --- a/test/webfuse/utils/msleep.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef WF_TEST_MSLEEP_HPP -#define WF_TEST_MSLEEP_HPP - -namespace webfuse_test -{ - -extern void msleep(long millis); - -} - - -#endif