From 6155b03cf87ac946eb1f8c3b32c373945560e521 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Fri, 10 Jul 2020 23:12:35 +0200 Subject: [PATCH] refactor: fix credentials --- lib/webfuse_provider/impl/client_protocol.c | 24 ++------ lib/webfuse_provider/impl/credentials.c | 26 +++++++-- lib/webfuse_provider/impl/credentials.h | 13 ++++- lib/webfuse_provider/impl/jsonrpc/proxy.c | 62 ++++++++++++--------- lib/webfuse_provider/impl/jsonrpc/proxy.h | 6 ++ lib/webfuse_provider/impl/jsonrpc/send_fn.h | 8 ++- test/webfuse_provider/jsonrpc/test_proxy.cc | 62 +++------------------ 7 files changed, 93 insertions(+), 108 deletions(-) diff --git a/lib/webfuse_provider/impl/client_protocol.c b/lib/webfuse_provider/impl/client_protocol.c index 3024504..9379450 100644 --- a/lib/webfuse_provider/impl/client_protocol.c +++ b/lib/webfuse_provider/impl/client_protocol.c @@ -125,8 +125,6 @@ static void wfp_impl_client_protocol_authenticate( 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); wfp_jsonrpc_proxy_invoke( protocol->proxy, @@ -134,7 +132,7 @@ static void wfp_impl_client_protocol_authenticate( protocol, "authenticate", "sj", - cred_type, creds); + cred_type, &wfp_impl_credentials_write, &credentials); wfp_impl_credentials_cleanup(&credentials); } @@ -216,25 +214,15 @@ static int wfp_impl_client_protocol_callback( } static void wfp_impl_client_protocol_send( - json_t * request, + char * data, + size_t length, void * user_data) { struct wfp_client_protocol * protocol = user_data; - size_t length = json_dumpb(request, NULL, 0, JSON_COMPACT); - if (0 < length) - { - char * raw_data = malloc(LWS_PRE + length); - char * data = raw_data + LWS_PRE; - json_dumpb(request, data, length, JSON_COMPACT); - - struct wfp_message * message = wfp_message_create(data, length); - wfp_slist_append(&protocol->messages, &message->item); - lws_callback_on_writable(protocol->wsi); - } - - - // return true; + struct wfp_message * message = wfp_message_create(data, length); + wfp_slist_append(&protocol->messages, &message->item); + lws_callback_on_writable(protocol->wsi); } void wfp_impl_client_protocol_init( diff --git a/lib/webfuse_provider/impl/credentials.c b/lib/webfuse_provider/impl/credentials.c index 9c0a82c..8e42211 100644 --- a/lib/webfuse_provider/impl/credentials.c +++ b/lib/webfuse_provider/impl/credentials.c @@ -1,4 +1,5 @@ #include "webfuse_provider/impl/credentials.h" +#include "webfuse_provider/impl/json/writer.h" #include #include @@ -33,14 +34,29 @@ void wfp_impl_credentials_add( json_object_set_new(credentials->contents, key, json_string(value)); } +void +wfp_impl_credentials_write( + struct wfp_json_writer * writer, + void * data) +{ + struct wfp_credentials * credentials = (struct wfp_credentials *) data; + + wfp_impl_json_writer_object_begin(writer); + char const * key; + json_t * value; + json_t * contents = credentials->contents; + json_object_foreach(contents, key, value) + { + wfp_impl_json_writer_object_key(writer, key); + wfp_impl_json_writer_write_string(writer, json_string_value(value)); + } + + wfp_impl_json_writer_object_end(writer); +} + 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 index 521bbff..2657575 100644 --- a/lib/webfuse_provider/impl/credentials.h +++ b/lib/webfuse_provider/impl/credentials.h @@ -2,6 +2,7 @@ #define WFP_IMPL_CREDENTIALS_H #include "webfuse_provider/credentials.h" +#include "webfuse_provider/impl/jsonrpc/proxy_intern.h" #include #ifdef __cplusplus @@ -9,6 +10,8 @@ extern "C" { #endif +struct wfp_json_writer; + struct wfp_credentials { char * type; @@ -30,11 +33,15 @@ extern void wfp_impl_credentials_add( char const * key, char const * value); -extern char const * wfp_impl_credentials_get_type( +extern void +wfp_impl_credentials_write( + struct wfp_json_writer * writer, + void * data); + +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 } diff --git a/lib/webfuse_provider/impl/jsonrpc/proxy.c b/lib/webfuse_provider/impl/jsonrpc/proxy.c index 04c185c..49d5699 100644 --- a/lib/webfuse_provider/impl/jsonrpc/proxy.c +++ b/lib/webfuse_provider/impl/jsonrpc/proxy.c @@ -4,6 +4,9 @@ #include "webfuse_provider/status.h" #include "webfuse_provider/impl/timer/timer.h" +#include "webfuse_provider/impl/json/writer.h" + +#include #include #include @@ -48,16 +51,21 @@ static void wfp_jsonrpc_proxy_on_timeout( } } -static json_t * wfp_jsonrpc_request_create( +static char * wfp_jsonrpc_request_create( + size_t * length, 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(); + struct wfp_json_writer * writer = wfp_impl_json_writer_create(128, LWS_PRE); + wfp_impl_json_writer_object_begin(writer); + + wfp_impl_json_writer_object_key(writer, "method"); + wfp_impl_json_writer_write_string(writer, method); + wfp_impl_json_writer_object_key(writer, "params"); + wfp_impl_json_writer_array_begin(writer); for (char const * param_type = param_info; '\0' != *param_type; param_type++) { switch(*param_type) @@ -65,19 +73,20 @@ static json_t * wfp_jsonrpc_request_create( case 's': { char const * const value = va_arg(args, char const *); - json_array_append_new(params, json_string(value)); + wfp_impl_json_writer_write_string(writer, value); } break; case 'i': { int const value = va_arg(args, int); - json_array_append_new(params, json_integer(value)); + wfp_impl_json_writer_write_int(writer, value); } break; case 'j': { - json_t * const value = va_arg(args, json_t *); - json_array_append_new(params, value); + wfp_jsonrpc_custom_write_fn * write = va_arg(args, wfp_jsonrpc_custom_write_fn *); + void * data = va_arg(args, void *); + write(writer,data); } break; default: @@ -85,15 +94,20 @@ static json_t * wfp_jsonrpc_request_create( break; } } - + wfp_impl_json_writer_array_end(writer); - json_object_set_new(request, "params", params); - if (0 != id) - { - json_object_set_new(request, "id", json_integer(id)); - } - - return request; + if (0 != id) + { + wfp_impl_json_writer_object_key(writer, "id"); + wfp_impl_json_writer_write_int(writer, id); + } + + wfp_impl_json_writer_object_end(writer); + + char * message = wfp_impl_json_writer_take_data(writer, length); + wfp_impl_json_writer_dispose(writer); + + return message; } void wfp_jsonrpc_proxy_init( @@ -147,9 +161,10 @@ void wfp_jsonrpc_proxy_vinvoke( proxy->request.id = 42; wfp_timer_start(proxy->request.timer, proxy->timeout); - json_t * request = wfp_jsonrpc_request_create(method_name, proxy->request.id, param_info, args); - proxy->send(request, proxy->user_data); - json_decref(request); + size_t length; + char * message = wfp_jsonrpc_request_create(&length, method_name, proxy->request.id, param_info, args); + + proxy->send(message, length, proxy->user_data); } else { @@ -163,13 +178,10 @@ extern void wfp_jsonrpc_proxy_vnotify( char const * param_info, va_list args) { - json_t * request = wfp_jsonrpc_request_create(method_name, 0, param_info, args); + size_t length; + char * request = wfp_jsonrpc_request_create(&length, method_name, 0, param_info, args); - if (NULL != request) - { - proxy->send(request, proxy->user_data); - json_decref(request); - } + proxy->send(request, length, proxy->user_data); } diff --git a/lib/webfuse_provider/impl/jsonrpc/proxy.h b/lib/webfuse_provider/impl/jsonrpc/proxy.h index 0f02edf..04abdd0 100644 --- a/lib/webfuse_provider/impl/jsonrpc/proxy.h +++ b/lib/webfuse_provider/impl/jsonrpc/proxy.h @@ -21,6 +21,12 @@ extern "C" { struct wfp_jsonrpc_proxy; struct wfp_timer_manager; +struct wfp_json_writer; + +typedef void +wfp_jsonrpc_custom_write_fn( + struct wfp_json_writer * writer, + void * data); extern struct wfp_jsonrpc_proxy * wfp_jsonrpc_proxy_create( diff --git a/lib/webfuse_provider/impl/jsonrpc/send_fn.h b/lib/webfuse_provider/impl/jsonrpc/send_fn.h index 356a3f7..35277ee 100644 --- a/lib/webfuse_provider/impl/jsonrpc/send_fn.h +++ b/lib/webfuse_provider/impl/jsonrpc/send_fn.h @@ -3,17 +3,19 @@ #ifndef __cplusplus #include +#include +#else +#include #endif -#include - #ifdef __cplusplus extern "C" { #endif typedef void wfp_jsonrpc_send_fn( - json_t * request, + char * message, + size_t length, void * user_data); #ifdef __cplusplus diff --git a/test/webfuse_provider/jsonrpc/test_proxy.cc b/test/webfuse_provider/jsonrpc/test_proxy.cc index 60ac485..8065c21 100644 --- a/test/webfuse_provider/jsonrpc/test_proxy.cc +++ b/test/webfuse_provider/jsonrpc/test_proxy.cc @@ -27,32 +27,27 @@ namespace struct SendContext { - json_t * response; + std::string response; bool is_called; explicit SendContext() - : response(nullptr) - , is_called(false) + : is_called(false) { } ~SendContext() { - if (nullptr != response) - { - json_decref(response); - } } }; void jsonrpc_send( - json_t * request, + char * request, + size_t length, void * user_data) { SendContext * context = reinterpret_cast(user_data); context->is_called = true; context->response = request; - json_incref(request); } struct FinishedContext @@ -122,22 +117,7 @@ TEST(wfp_jsonrpc_proxy, invoke) wfp_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)); - - json_t * method = json_object_get(send_context.response, "method"); - ASSERT_TRUE(json_is_string(method)); - ASSERT_STREQ("foo", json_string_value(method)); - - json_t * params = json_object_get(send_context.response, "params"); - ASSERT_TRUE(json_is_array(params)); - ASSERT_EQ(2, json_array_size(params)); - ASSERT_TRUE(json_is_string(json_array_get(params, 0))); - ASSERT_STREQ("bar", json_string_value(json_array_get(params, 0))); - ASSERT_TRUE(json_is_integer(json_array_get(params, 1))); - ASSERT_EQ(42, json_integer_value(json_array_get(params, 1))); - - json_t * id = json_object_get(send_context.response, "id"); - ASSERT_TRUE(json_is_integer(id)); + ASSERT_STREQ("{\"method\":\"foo\",\"params\":[\"bar\",42],\"id\":42}", send_context.response.c_str()); ASSERT_FALSE(finished_context.is_called); @@ -165,7 +145,6 @@ TEST(wfp_jsonrpc_proxy, invoke_fails_if_another_request_is_pending) wfp_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data2, "foo", ""); ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(json_is_object(send_context.response)); ASSERT_FALSE(finished_context.is_called); @@ -209,14 +188,10 @@ TEST(wfp_jsonrpc_proxy, on_result) wfp_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)); - - json_t * id = json_object_get(send_context.response, "id"); - ASSERT_TRUE(json_is_number(id)); json_t * response = json_object(); json_object_set_new(response, "result", json_string("okay")); - json_object_set(response, "id", id); + json_object_set_new(response, "id", json_integer(42)); wfp_jsonrpc_proxy_onresult(proxy, response); json_decref(response); @@ -243,14 +218,10 @@ TEST(wfp_jsonrpc_proxy, on_result_reject_response_with_unknown_id) wfp_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)); - - json_t * id = json_object_get(send_context.response, "id"); - ASSERT_TRUE(json_is_number(id)); json_t * response = json_object(); json_object_set_new(response, "result", json_string("okay")); - json_object_set_new(response, "id", json_integer(1 + json_integer_value(id))); + json_object_set_new(response, "id", json_integer(1234)); wfp_jsonrpc_proxy_onresult(proxy, response); json_decref(response); @@ -274,7 +245,6 @@ TEST(wfp_jsonrpc_proxy, timeout) wfp_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)); std::this_thread::sleep_for(10ms); wfp_timer_manager_check(timer_manager); @@ -299,7 +269,6 @@ TEST(wfp_jsonrpc_proxy, cleanup_pending_request) wfp_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); @@ -323,22 +292,7 @@ TEST(wfp_jsonrpc_proxy, notify) wfp_jsonrpc_proxy_notify(proxy, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(json_is_object(send_context.response)); - - json_t * method = json_object_get(send_context.response, "method"); - ASSERT_TRUE(json_is_string(method)); - ASSERT_STREQ("foo", json_string_value(method)); - - json_t * params = json_object_get(send_context.response, "params"); - ASSERT_TRUE(json_is_array(params)); - ASSERT_EQ(2, json_array_size(params)); - ASSERT_TRUE(json_is_string(json_array_get(params, 0))); - ASSERT_STREQ("bar", json_string_value(json_array_get(params, 0))); - ASSERT_TRUE(json_is_integer(json_array_get(params, 1))); - ASSERT_EQ(42, json_integer_value(json_array_get(params, 1))); - - json_t * id = json_object_get(send_context.response, "id"); - ASSERT_EQ(nullptr, id); + ASSERT_STREQ("{\"method\":\"foo\",\"params\":[\"bar\",42]}", send_context.response.c_str()); wfp_jsonrpc_proxy_dispose(proxy); wfp_timer_manager_dispose(timer_manager);