This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"C_Cpp.default.configurationProvider": "go2sh.cmake-integration"
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
183
src/rest/restd.c
Normal file
183
src/rest/restd.c
Normal file
@@ -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 <event2/buffer.h>
|
||||
#include <event2/bufferevent.h>
|
||||
#include <event2/event.h>
|
||||
#include <event2/listener.h>
|
||||
|
||||
#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 -------------------------------*/
|
||||
114
src/rest/restd.h
Normal file
114
src/rest/restd.h
Normal file
@@ -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 <pthread.h>
|
||||
|
||||
#include <qlibc/qlibc.h>
|
||||
|
||||
/*------------------------------- 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 */
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user