POST support WIP
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2020-01-21 23:00:59 +01:00
parent 9acd116ab2
commit f1a4c5448b
8 changed files with 113 additions and 100 deletions

View File

@@ -104,6 +104,7 @@ extern off_t restd_http_get_content_length(restd_conn_t *conn);
extern size_t restd_http_get_content_length_stored(restd_conn_t *conn); extern size_t restd_http_get_content_length_stored(restd_conn_t *conn);
extern void *restd_http_get_content(restd_conn_t *conn, size_t maxsize, size_t *storedsize); extern void *restd_http_get_content(restd_conn_t *conn, size_t maxsize, size_t *storedsize);
extern int restd_http_is_keepalive_request(restd_conn_t *conn); extern int restd_http_is_keepalive_request(restd_conn_t *conn);
extern int http_parser(restd_http_t *http, struct evbuffer *in);
extern int restd_http_set_response_header(restd_conn_t *conn, const char *name, const char *value); extern int restd_http_set_response_header(restd_conn_t *conn, const char *name, const char *value);
extern const char *restd_http_get_response_header(restd_conn_t *conn, const char *name); extern const char *restd_http_get_response_header(restd_conn_t *conn, const char *name);

View File

@@ -28,6 +28,6 @@
/*------------------------------- INCLUDES ----------------------------------*/ /*------------------------------- INCLUDES ----------------------------------*/
extern int restd_rest_handler(short event, restd_conn_t *conn, void *userdata); extern int restd_rest_handler(short event, restd_conn_t *conn);
#endif /* _RESTD_REST_HANDLER_H */ #endif /* _RESTD_REST_HANDLER_H */

View File

@@ -70,6 +70,7 @@ enum restd_log_e
/** /**
* User callback(hook) prototype. * User callback(hook) prototype.
*/ */
typedef int (*restd_call_hook_cb)(short event, restd_conn_t *conn);
typedef int (*restd_callback)(short event, restd_conn_t *conn, void *userdata); typedef int (*restd_callback)(short event, restd_conn_t *conn, void *userdata);
typedef void (*restd_userdata_free_cb)(restd_conn_t *conn, void *userdata); typedef void (*restd_userdata_free_cb)(restd_conn_t *conn, void *userdata);
@@ -107,6 +108,8 @@ struct restd_server_s
struct event_base *evbase; /*!< event base */ struct event_base *evbase; /*!< event base */
struct bufferevent *notify_buffer; /*!< internal notification channel */ struct bufferevent *notify_buffer; /*!< internal notification channel */
restd_call_hook_cb call_hooks;
restd_callback request_handler; restd_callback request_handler;
restd_callback error_handler; restd_callback error_handler;
}; };
@@ -157,6 +160,7 @@ extern int restd_server_get_option_int(restd_server_t *server, const char *key);
extern void restd_server_register_request_handler(restd_server_t *server, restd_callback cb); extern void restd_server_register_request_handler(restd_server_t *server, restd_callback cb);
extern void restd_server_register_error_handler(restd_server_t *server, restd_callback cb); extern void restd_server_register_error_handler(restd_server_t *server, restd_callback cb);
extern void restd_server_register_call_hooks_handler(restd_server_t *server, restd_call_hook_cb cb);
extern void restd_server_register_hook(restd_server_t *server, restd_callback cb, void *userdata); extern void restd_server_register_hook(restd_server_t *server, restd_callback cb, void *userdata);
extern void restd_server_register_hook_on_method(restd_server_t *server, const char *method, extern void restd_server_register_hook_on_method(restd_server_t *server, const char *method,

View File

@@ -45,7 +45,6 @@ static void http_free(restd_http_t *http);
static size_t http_add_inbuf(struct evbuffer *buffer, restd_http_t *http, static size_t http_add_inbuf(struct evbuffer *buffer, restd_http_t *http,
size_t maxsize); size_t maxsize);
static int http_parser(restd_http_t *http, struct evbuffer *in);
static int parse_requestline(restd_http_t *http, char *line); static int parse_requestline(restd_http_t *http, char *line);
static int parse_headers(restd_http_t *http, struct evbuffer *in); static int parse_headers(restd_http_t *http, struct evbuffer *in);
static int parse_body(restd_http_t *http, struct evbuffer *in); static int parse_body(restd_http_t *http, struct evbuffer *in);
@@ -617,7 +616,7 @@ static size_t http_add_inbuf(struct evbuffer *buffer, restd_http_t *http,
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static int http_parser(restd_http_t *http, struct evbuffer *in) int http_parser(restd_http_t *http, struct evbuffer *in)
{ {
ASSERT(http != NULL && in != NULL); ASSERT(http != NULL && in != NULL);

View File

@@ -175,7 +175,7 @@ static bool contain(const char *src, const char *dest, int len)
* *
* @brief Main function to manage rest request. * @brief Main function to manage rest request.
*/ */
int restd_rest_handler(short event, restd_conn_t *conn, void *userdata) int restd_rest_handler(short event, restd_conn_t *conn)
{ {
if (event & RESTD_EVENT_INIT) if (event & RESTD_EVENT_INIT)
{ {
@@ -186,33 +186,23 @@ int restd_rest_handler(short event, restd_conn_t *conn, void *userdata)
restd_conn_set_extra(conn, http, http_free_cb); restd_conn_set_extra(conn, http, http_free_cb);
return RESTD_OK; return RESTD_OK;
} }
else if (event & RESTD_EVENT_READ)
{
DEBUG("==> HTTP READ");
return RESTD_OK;
}
else if (event & RESTD_EVENT_WRITE)
{
DEBUG("==> HTTP WRITE");
return RESTD_OK;
}
else if (event & RESTD_EVENT_CLOSE) else if (event & RESTD_EVENT_CLOSE)
{ {
DEBUG("==> HTTP CLOSE=%x (TIMEOUT=%d, SHUTDOWN=%d)", DEBUG("==> HTTP CLOSE=%x (TIMEOUT=%d, SHUTDOWN=%d)",
event, event & RESTD_EVENT_TIMEOUT, event & RESTD_EVENT_SHUTDOWN); event, event & RESTD_EVENT_TIMEOUT, event & RESTD_EVENT_SHUTDOWN);
return RESTD_OK; return RESTD_OK;
} }
else if ((event & RESTD_EVENT_READ) || (event & RESTD_EVENT_WRITE))
BUG_EXIT();
return RESTD_CLOSE;
}
int restd_rest_handler2(short event, restd_conn_t *conn, void *userdata)
{ {
restd_http_t *http = (restd_http_t *)restd_conn_get_extra(conn);
int status = http_parser(http, conn->in);
if (conn->method == NULL && http->request.method != NULL)
{
restd_conn_set_method(conn, http->request.method);
}
DEBUG("==> HTTP READ || HTTP WRITE");
int reason = RESTD_ERROR_PATH_NOT_FOUND; int reason = RESTD_ERROR_PATH_NOT_FOUND;
DEBUG("ZOB********restd_rest_handler: event 0x%x", event); DEBUG("ZOB********restd_rest_handler: event 0x%x", event);
restd_http_t *http = (restd_http_t *)restd_conn_get_extra(conn);
char *root_path; char *root_path;
qlist_t *hooks = conn->server->hooks; qlist_t *hooks = conn->server->hooks;
@@ -228,7 +218,7 @@ int restd_rest_handler2(short event, restd_conn_t *conn, void *userdata)
DEBUG("HOOK FOUND !!!!\n"); DEBUG("HOOK FOUND !!!!\n");
if ((hook->method == NULL) || (conn->method == NULL) || (strcmp(hook->method, conn->method) != 0)) if ((hook->method == NULL) || (conn->method == NULL) || (strcmp(hook->method, conn->method) != 0))
{ {
// DEBUG("Hook found but method failed.\n"); DEBUG("Hook found but method failed.\n");
reason = RESTD_ERROR_METHOD_NOT_ALLOWED; reason = RESTD_ERROR_METHOD_NOT_ALLOWED;
break; break;
} }
@@ -282,3 +272,7 @@ int restd_rest_handler2(short event, restd_conn_t *conn, void *userdata)
return conn->server->error_handler(reason, conn, NULL); return conn->server->error_handler(reason, conn, NULL);
} }
BUG_EXIT();
return RESTD_CLOSE;
}

View File

@@ -154,6 +154,7 @@ restd_server_t *restd_server_new(void)
server->options = qhashtbl(0, 0); server->options = qhashtbl(0, 0);
server->stats = qhashtbl(100, QHASHTBL_THREADSAFE); server->stats = qhashtbl(100, QHASHTBL_THREADSAFE);
server->hooks = qlist(0); server->hooks = qlist(0);
server->call_hooks = call_hooks;
if (server->options == NULL || server->stats == NULL || server->hooks == NULL) if (server->options == NULL || server->stats == NULL || server->hooks == NULL)
{ {
restd_server_free(server); restd_server_free(server);
@@ -535,7 +536,7 @@ static restd_conn_t *conn_new(restd_server_t *server, struct bufferevent *buffer
{ {
return NULL; return NULL;
} }
printf("conn_new\n");
// Create a new connection container. // Create a new connection container.
restd_conn_t *conn = NEW_OBJECT(restd_conn_t); restd_conn_t *conn = NEW_OBJECT(restd_conn_t);
if (conn == NULL) if (conn == NULL)
@@ -555,7 +556,7 @@ static restd_conn_t *conn_new(restd_server_t *server, struct bufferevent *buffer
bufferevent_enable(buffer, EV_READ); bufferevent_enable(buffer, EV_READ);
// Run callbacks with AD_EVENT_INIT event. // Run callbacks with AD_EVENT_INIT event.
conn->status = call_hooks(RESTD_EVENT_INIT | RESTD_EVENT_WRITE, conn); conn->status = conn->server->call_hooks(RESTD_EVENT_INIT | RESTD_EVENT_WRITE, conn);
// //
conn->id = -1; conn->id = -1;
@@ -600,7 +601,7 @@ static void conn_free(restd_conn_t *conn)
{ {
if (conn->status != RESTD_CLOSE) if (conn->status != RESTD_CLOSE)
{ {
call_hooks(RESTD_EVENT_CLOSE | RESTD_EVENT_SHUTDOWN, conn); conn->server->call_hooks(RESTD_EVENT_CLOSE | RESTD_EVENT_SHUTDOWN, conn);
} }
conn_reset(conn); conn_reset(conn);
if (conn->buffer) if (conn->buffer)
@@ -652,7 +653,7 @@ static void conn_cb(restd_conn_t *conn, int event)
DEBUG("conn_cb: status:0x%x, event:0x%x", conn->status, event) DEBUG("conn_cb: status:0x%x, event:0x%x", conn->status, event)
if (conn->status == RESTD_OK || conn->status == RESTD_TAKEOVER) if (conn->status == RESTD_OK || conn->status == RESTD_TAKEOVER)
{ {
int status = call_hooks(event, conn); int status = conn->server->call_hooks(event, conn);
// Update status only when it's higher then before. // Update status only when it's higher then before.
if (!(conn->status == RESTD_CLOSE || (conn->status == RESTD_DONE && conn->status >= status))) if (!(conn->status == RESTD_CLOSE || (conn->status == RESTD_DONE && conn->status >= status)))
{ {
@@ -664,9 +665,9 @@ static void conn_cb(restd_conn_t *conn, int event)
{ {
if (restd_server_get_option_int(conn->server, "server.request_pipelining")) if (restd_server_get_option_int(conn->server, "server.request_pipelining"))
{ {
call_hooks(RESTD_EVENT_CLOSE, conn); conn->server->call_hooks(RESTD_EVENT_CLOSE, conn);
conn_reset(conn); conn_reset(conn);
call_hooks(RESTD_EVENT_INIT, conn); conn->server->call_hooks(RESTD_EVENT_INIT, conn);
} }
else else
{ {
@@ -684,7 +685,7 @@ static void conn_cb(restd_conn_t *conn, int event)
if (evbuffer_get_length(conn->out) <= 0) if (evbuffer_get_length(conn->out) <= 0)
{ {
int newevent = (event & RESTD_EVENT_CLOSE) ? event : RESTD_EVENT_CLOSE; int newevent = (event & RESTD_EVENT_CLOSE) ? event : RESTD_EVENT_CLOSE;
call_hooks(newevent, conn); //conn->server->call_hooks(newevent, conn);
conn_free(conn); conn_free(conn);
DEBUG("Connection closed."); DEBUG("Connection closed.");
return; return;
@@ -708,6 +709,13 @@ void restd_server_register_error_handler(restd_server_t *server, restd_callback
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void restd_server_register_call_hooks_handler(restd_server_t *server, restd_call_hook_cb cb)
{
server->call_hooks = cb;
}
/*--------------------------------------------------------------------------*/
/** /**
* Register user hook. * Register user hook.
*/ */

View File

@@ -42,7 +42,7 @@
int outlet_create_handler(short event, restd_conn_t *conn, void *userdata) int outlet_create_handler(short event, restd_conn_t *conn, void *userdata)
{ {
printf("outlet_create_handler\n\n"); printf("outlet_create_handler\n\n");
if (event & RESTD_EVENT_CLOSE) if (event & RESTD_EVENT_WRITE)
{ {
off_t data_size; off_t data_size;
@@ -55,6 +55,9 @@ int outlet_create_handler(short event, restd_conn_t *conn, void *userdata)
data = restd_http_get_content(conn, 0, &data_size); data = restd_http_get_content(conn, 0, &data_size);
printf("2/data size: %ld\n", data_size); printf("2/data size: %ld\n", data_size);
printf("3/data size: %s\n", data);
#if 0
root_node = json_tokener_parse(data); root_node = json_tokener_parse(data);
free(data); free(data);
@@ -71,6 +74,10 @@ int outlet_create_handler(short event, restd_conn_t *conn, void *userdata)
return RESTD_CLOSE; return RESTD_CLOSE;
} }
} }
#endif
restd_http_response(conn, 204, "application/json", "{}", 2);
return RESTD_CLOSE;
} }
restd_http_response(conn, 400, "application/json", "{\"status\":\"error\"}", 18); restd_http_response(conn, 400, "application/json", "{\"status\":\"error\"}", 18);

View File

@@ -62,8 +62,8 @@ int setup_rest_server(restd_server_t *rest_server, const char *port, const char
//restd_server_register_request_handler(rest_server, restd_rest_handler); //restd_server_register_request_handler(rest_server, restd_rest_handler);
restd_server_register_error_handler(rest_server, my_error_handler); restd_server_register_error_handler(rest_server, my_error_handler);
restd_server_register_hook(rest_server, restd_rest_handler, NULL); restd_server_register_call_hooks_handler(rest_server, restd_rest_handler);
// restd_server_register_hook(rest_server, restd_http_handler, NULL);
// Capabilities. // Capabilities.
restd_server_register_hook_on_path(rest_server, "GET", "/api/v1/capabilities", NULL, dm); restd_server_register_hook_on_path(rest_server, "GET", "/api/v1/capabilities", NULL, dm);