parameter management WIP.

This commit is contained in:
NADAL Jean-Baptiste
2020-02-19 16:23:33 +01:00
parent 6db405df1f
commit 905d900fff
5 changed files with 147 additions and 186 deletions

View File

@@ -40,6 +40,8 @@
#include <event2/listener.h>
#include <event2/keyvalq_struct.h>
#include <qlibc/qlibc.h>
#ifdef __linux__
#include <sys/eventfd.h>
#else
@@ -181,7 +183,8 @@ void restd_http_response_from_file(struct evhttp_request *req, int code, int fd,
/*--------------------------- PUBLIC FUNCTIONS -------------------------------*/
/**
/*--------------------------------------------------------------------------
*
* Set debug output level.
*
* @param debug_level debug output level. 0 to disable.
@@ -204,7 +207,8 @@ enum restd_log_e restd_log_level(enum restd_log_e log_level)
return prev;
}
/**
/*--------------------------------------------------------------------------
*
* Create a server object.
*/
restd_server_t *restd_server_new(void)
@@ -235,7 +239,8 @@ restd_server_t *restd_server_new(void)
return server;
}
/**
/*--------------------------------------------------------------------------
*
* Release server object and all the resources.
*/
void restd_server_free(restd_server_t *server)
@@ -273,20 +278,19 @@ void restd_server_free(restd_server_t *server)
{
qlist_t *tbl = server->hooks;
restd_hook_t *hook;
while ((hook = tbl->popfirst(tbl, NULL)))
while ((hook = qlist_popfirst(tbl, NULL)))
{
if (hook->path)
free(hook->path);
free(hook);
restd_hook_free(hook);
}
server->hooks->free(server->hooks);
qlist_free(server->hooks);
}
free(server);
DEBUG("Server terminated.");
}
/**
/*--------------------------------------------------------------------------
*
* Start server.
*
* @return 0 if successful, otherwise -1.
@@ -441,14 +445,39 @@ void restd_server_set_option(restd_server_t *server, const char *key, const char
void restd_server_register_hook_on_path(restd_server_t *server, enum evhttp_cmd_type method, const char *path,
restd_callback cb, void *userdata)
{
restd_hook_t hook;
bzero((void *)&hook, sizeof(restd_hook_t));
hook.method = method;
hook.path = (path) ? strdup(path) : NULL;
hook.cb = cb;
hook.userdata = userdata;
restd_hook_t *hook;
char *fragment;
server->hooks->addlast(server->hooks, (void *)&hook, sizeof(restd_hook_t));
// Init Hook.
hook = restd_hook_new();
hook->method = method;
hook->path = (path) ? strdup(path) : NULL;
hook->cb = cb;
hook->userdata = userdata;
hook->path_fragments = qstrtokenizer(path, "/");
// Split URI and detect parameter and action.
while ((fragment = qlist_popfirst(hook->path_fragments, NULL)) != NULL)
{
char *param;
param = strchr(fragment, ':');
if (param != NULL)
{
hook->has_param = true;
hook->param_name = strdup(param + 1);
}
if (hook->has_param == true)
{
hook->action_name = strdup(fragment);
}
free(fragment);
}
server->hooks->addlast(server->hooks, (void *)hook, sizeof(restd_hook_t));
free(hook);
}
/*--------------------------------------------------------------------------*/
@@ -488,6 +517,79 @@ char *restd_http_get_body(struct evhttp_request *req)
return body;
}
/*--------------------------------------------------------------------------*/
restd_hook_t *restd_hook_new(void)
{
restd_hook_t *hook = NEW_OBJECT(restd_hook_t);
if (hook == NULL)
{
return NULL;
}
bzero((void *)hook, sizeof(restd_hook_t));
hook->has_param = false;
return hook;
}
/*--------------------------------------------------------------------------*/
void restd_hook_free(restd_hook_t *hook)
{
if (hook == NULL)
return;
qlist_free(hook->path_fragments);
if (hook->path)
free(hook->path);
if (hook->param_name)
free(hook->param_name);
if (hook->action_name)
free(hook->action_name);
free(hook);
}
/*--------------------------------------------------------------------------*/
restd_resp_t *restd_resp_new(void)
{
restd_resp_t *resp = NEW_OBJECT(restd_resp_t);
if (resp == NULL)
{
return NULL;
}
bzero((void *)resp, sizeof(restd_resp_t));
return resp;
}
/*--------------------------------------------------------------------------*/
void restd_resp_free(restd_resp_t *response)
{
if (response == NULL)
{
return;
}
if (response->parameter)
{
free(response->parameter);
}
if (response->action)
{
free(response->action);
}
free(response);
}
/*--------------------------- LOCAL FUNCTIONS -------------------------------*/
/*--------------------------------------------------------------------------*/
@@ -509,7 +611,8 @@ static int set_undefined_options(restd_server_t *server)
return newentries;
}
/**
/*--------------------------------------------------------------------------
*
* Retrieve server option.
*/
char *restd_server_get_option(restd_server_t *server, const char *key)
@@ -517,7 +620,8 @@ char *restd_server_get_option(restd_server_t *server, const char *key)
return server->options->getstr(server->options, key, false);
}
/**
/*--------------------------------------------------------------------------
*
* Retrieve server option in integer format.
*/
int restd_server_get_option_int(restd_server_t *server, const char *key)
@@ -600,7 +704,8 @@ static void libevent_log_cb(int severity, const char *msg)
}
}
/**
/*--------------------------------------------------------------------------
*
* If there's no event, loopbreak or loopexit call won't work until one more
* event arrived. So we use eventfd as a internal notification channel to let
* server get out of the loop without waiting for an event.
@@ -748,7 +853,6 @@ void rest_request_cb(struct evhttp_request *req, void *arg)
{
// TODO 404
}
}
#if 0 // TODO
if (conn->server->error_handler != NULL)
@@ -758,7 +862,7 @@ void rest_request_cb(struct evhttp_request *req, void *arg)
else
#endif
{
evhttp_send_reply(req, 500, "Internal Error", NULL);
evhttp_send_reply(req, 500, "Internal Error", NULL);
}
}