From 4d3828a664b0d2efba9cb458108a399a1b2ce703 Mon Sep 17 00:00:00 2001 From: NADAL Jean-Baptiste Date: Fri, 7 Feb 2020 21:54:46 +0100 Subject: [PATCH] wip --- .vscode/settings.json | 3 + CMakeLists.txt | 1 - src/CMakeLists.txt | 3 +- src/rest/rest_devices_handlers.c | 3 +- src/rest/rest_server.c | 6 +- src/rest/restd.c | 183 +++++++++++++++++++++++++++++++ src/rest/restd.h | 114 +++++++++++++++++++ src/tests/test_rest.c | 11 +- 8 files changed, 313 insertions(+), 11 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/rest/restd.c create mode 100644 src/rest/restd.h diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..94941ce --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "C_Cpp.default.configurationProvider": "go2sh.cmake-integration" +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 08f9250..ddcf64a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,6 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libevent ${CMAKE_CURRENT_BINARY_ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../nats.c ${CMAKE_CURRENT_BINARY_DIR}/nats.c) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../json-c ${CMAKE_CURRENT_BINARY_DIR}/json-c) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src) add_custom_target (static_analysis diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d7239d2..4fe4c22 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,6 +31,7 @@ file( devices/outlet_dio.c devices/shutter.c devices/sprinkler.c + rest/restd.c rest/rest_devices_handlers.c rest/rest_server.c ) @@ -41,7 +42,6 @@ add_executable (${PROJECT_NAME} main.c ${source_files}) target_link_libraries (${PROJECT_NAME} LINK_PUBLIC nats_static - restd-static qlibc-static qlibcext-static json-c @@ -69,7 +69,6 @@ add_executable (test_device tests/test_main.c ${source_files}) target_link_libraries (test_device LINK_PUBLIC nats_static - restd-static qlibcext-static qlibc-static json-c diff --git a/src/rest/rest_devices_handlers.c b/src/rest/rest_devices_handlers.c index 3613b87..88901e9 100644 --- a/src/rest/rest_devices_handlers.c +++ b/src/rest/rest_devices_handlers.c @@ -38,7 +38,7 @@ // 400 Bad request /*--------------------------------------------------------------------------*/ - +#if 0 int outlet_create_handler(short event, restd_conn_t *conn, void *userdata) { printf("outlet_create_handler\n\n"); @@ -116,3 +116,4 @@ int outlet_remove_handler(short event, restd_conn_t *conn, void *userdata) { return 0; } +#endif diff --git a/src/rest/rest_server.c b/src/rest/rest_server.c index 49dcbaf..1bb2158 100644 --- a/src/rest/rest_server.c +++ b/src/rest/rest_server.c @@ -32,6 +32,7 @@ #include "rest_server.h" +#if 0 /*--------------------------------------------------------------------------*/ int my_error_handler(short event, restd_conn_t *conn, void *userdata) @@ -51,9 +52,10 @@ int my_error_handler(short event, restd_conn_t *conn, void *userdata) } /*--------------------------------------------------------------------------*/ - +#endif int setup_rest_server(restd_server_t *rest_server, const char *port, const char *root_path, void *dm) { +#if 0 restd_server_set_option(rest_server, "server.port", port); restd_server_set_option(rest_server, "server.root_path", root_path); @@ -77,6 +79,6 @@ int setup_rest_server(restd_server_t *rest_server, const char *port, const char // Outlets // Shutters - +#endif return 0; } diff --git a/src/rest/restd.c b/src/rest/restd.c new file mode 100644 index 0000000..113d538 --- /dev/null +++ b/src/rest/restd.c @@ -0,0 +1,183 @@ + + +/*! + * restd.h + * + * Copyright (c) 2015-2020, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 07/02/2020 + * + */ + +/*------------------------------- INCLUDES ----------------------------------*/ + +#include +#include +#include +#include + +#include "macro.h" + +#include "restd.h" +/* + * Local variables. + */ +static bool initialized = false; + +/* + * Global variables. + */ +int _restd_log_level = RESTD_LOG_WARN; + +/*--------------------------- PUBLIC FUNCTIONS -------------------------------*/ + +/** + * Set debug output level. + * + * @param debug_level debug output level. 0 to disable. + * + * @return previous debug level. + * + * @note + * debug_level: + * REST_LOG_DISABLE + * REST_LOG_ERROR + * REST_LOG_WARN (default) + * REST_LOG_INFO + * REST_LOG_DEBUG + * REST_LOG_DEBUG2 + */ +enum restd_log_e restd_log_level(enum restd_log_e log_level) +{ + int prev = _restd_log_level; + _restd_log_level = log_level; + return prev; +} + +/** + * Create a server object. + */ +restd_server_t *restd_server_new(void) +{ + if (initialized) + { + initialized = true; + } + + restd_server_t *server = NEW_OBJECT(restd_server_t); + if (server == NULL) + { + return NULL; + } + + // Initialize instance. + server->options = qhashtbl(0, 0); + server->stats = qhashtbl(100, QHASHTBL_THREADSAFE); + server->hooks = qlist(0); + //server->call_hooks = call_hooks; + if (server->options == NULL || server->stats == NULL || server->hooks == NULL) + { + restd_server_free(server); + return NULL; + } + + DEBUG("Created a server object."); + return server; +} + +/** + * Release server object and all the resources. + */ +void restd_server_free(restd_server_t *server) +{ + if (server == NULL) + return; +#if 0 + int thread = restd_server_get_option_int(server, "server.thread"); + if (thread && server->thread) + { + notify_loopexit(server); + sleep(1); + close_server(server); + } + + if (server->evbase) + { + event_base_free(server->evbase); + } + + if (server->options) + { + server->options->free(server->options); + } + if (server->stats) + { + server->stats->free(server->stats); + } + if (server->hooks) + { + qlist_t *tbl = server->hooks; + restd_hook_t *hook; + while ((hook = tbl->popfirst(tbl, NULL))) + { + if (hook->method) + free(hook->method); + if (hook->path) + free(hook->path); + free(hook); + } + server->hooks->free(server->hooks); + } +#endif + free(server); + DEBUG("Server terminated."); +} + +/** + * Start server. + * + * @return 0 if successful, otherwise -1. + */ +int restd_server_start(restd_server_t *server) +{ +} + +/*--------------------------------------------------------------------------*/ + +int restd_server_attach_event_loop(restd_server_t *server, struct event_base *ev_base) +{ + if (server == NULL) + return -1; + + server->evbase = ev_base; + return 0; +} + +/*--------------------------------------------------------------------------*/ + +void restd_server_set_option(restd_server_t *server, const char *key, const char *value) +{ +} + +void restd_server_register_hook_on_path(restd_server_t *server, const char *method, const char *path, + restd_callback cb, void *userdata) +{ +} + +/*--------------------------- LOCAL FUNCTIONS -------------------------------*/ diff --git a/src/rest/restd.h b/src/rest/restd.h new file mode 100644 index 0000000..1760128 --- /dev/null +++ b/src/rest/restd.h @@ -0,0 +1,114 @@ +/*! + * restd.h + * + * Copyright (c) 2015-2020, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 07/02/2020 + * + */ + +#ifndef _RESTD_H +#define _RESTD_H + +/*------------------------------- INCLUDES ----------------------------------*/ + +#include + +#include + +/*------------------------------- TYPEDEFS ----------------------------------*/ + +typedef struct restd_server_s restd_server_t; +typedef struct restd_hook_s restd_hook_t; + +/*------------------------------- INCLUDES ----------------------------------*/ + +extern restd_server_t *restd_server_new(void); +extern void restd_server_free(restd_server_t *server); +extern int restd_server_start(restd_server_t *server); +extern int restd_server_attach_event_loop(restd_server_t *server, struct event_base *ev_base); + +extern void restd_server_set_option(restd_server_t *server, const char *key, const char *value); +extern void restd_server_register_hook_on_path(restd_server_t *server, const char *method, const char *path, + restd_callback cb, void *userdata); + +/*------------------------------- DEFINES ------------------------------------*/ + +/* + * These flags are used for ad_log_level(); + */ +enum restd_log_e +{ + RESTD_LOG_DISABLE = 0, + RESTD_LOG_ERROR, + RESTD_LOG_WARN, + RESTD_LOG_INFO, + RESTD_LOG_DEBUG, + RESTD_LOG_DEBUG2, +}; + +/*---------------------------------------------------------------------------*\ +| USER-CALLBACK | +\*---------------------------------------------------------------------------*/ + +/** + * User callback(hook) prototype. + */ +typedef int (*restd_call_hook_cb)(short event, void *conn); +typedef int (*restd_callback)(short event, void *conn, void *userdata); +typedef void (*restd_userdata_free_cb)(void *conn, void *userdata); + +/*---------------------------------------------------------------------------*\ +| DATA STRUCTURES | +\*---------------------------------------------------------------------------*/ + +/** + * Server info container. + */ +struct restd_server_s +{ + int errcode; /*!< exit status. 0 for normal exit, non zero for error. */ + pthread_t *thread; /*!< thread object. not null if server runs as a thread */ + + qhashtbl_t *options; /*!< server options */ + qhashtbl_t *stats; /*!< internal statistics */ + qlist_t *hooks; /*!< list of registered hooks */ + struct evconnlistener *listener; /*!< listener */ + struct event_base *evbase; /*!< event base */ + + struct bufferevent *notify_buffer; /*!< internal notification channel */ + + restd_call_hook_cb call_hooks; + restd_callback request_handler; + restd_callback error_handler; +}; + +/* + * User callback hook container. + */ +struct restd_hook_s +{ + char *method; + char *path; + restd_callback cb; + void *userdata; +}; + + +#endif /*_RESTD_H */ diff --git a/src/tests/test_rest.c b/src/tests/test_rest.c index 4b44afd..5af0b67 100644 --- a/src/tests/test_rest.c +++ b/src/tests/test_rest.c @@ -41,12 +41,12 @@ int my_error_handler(short event, restd_conn_t *conn, void *userdata) { - restd_http_response(conn, 200, "application/json", "{\"status\":\"error\"}", 18); - return RESTD_CLOSE; // Close connection. + //restd_http_response(conn, 200, "application/json", "{\"status\":\"error\"}", 18); + //return RESTD_CLOSE; // Close connection. } /*--------------------------------------------------------------------------*/ - +#if 0 int my_success_http_handler(short event, restd_conn_t *conn, void *userdata) { if (event & RESTD_EVENT_READ) @@ -277,7 +277,7 @@ bool found_special_route(restd_server_t *server, const char *method, const char return false; } - +#endif /*--------------------------------------------------------------------------*/ TEST("Rest - create free\t") @@ -295,7 +295,7 @@ TEST("Rest - create free\t") } /*--------------------------------------------------------------------------*/ - +#if 0 TEST("Rest - create access regular route free\t") { restd_server_t *rest_server; @@ -433,3 +433,4 @@ TEST("Rest - create start access rest hook free\t") restd_server_free(rest_server); } +#endif \ No newline at end of file