restd is functional.

This commit is contained in:
NADAL Jean-Baptiste
2019-12-24 14:11:51 +01:00
parent 798bea32ab
commit 0113c9eec6
4 changed files with 185 additions and 39 deletions

View File

@@ -47,8 +47,8 @@ typedef struct restd_conn_s restd_conn_t;
#define RESTD_DONE (2) /*!< We're done with this request but keep the connection open. */
#define RESTD_CLOSE (3) /*!< We're done with this request. Close as soon as we sent all data out. */
#define RESTD_NOT_ALLOWED (4)
#define RESTD_NOT_FOUND (5)
#define RESTD_ERROR_METHOD_NOT_ALLOWED (1)
#define RESTD_ERROR_PATH_NOT_FOUND (2)
/*
* These flags are used for ad_log_level();

View File

@@ -30,6 +30,9 @@
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <event2/buffer.h>
@@ -39,6 +42,108 @@
#include "macro.h"
/*--------------------------------------------------------------------------*/
struct mimetype_s
{
const char *extn;
const char *mime;
};
/*--------------------------------------------------------------------------*/
static const struct mimetype_s g_mime_types[] = {
{"txt", "text/plain"},
{"log", "text/plain"},
{"js", "text/javascript"},
{"css", "text/css"},
{"htm", "text/html"},
{"html", "text/html"},
{"diff", "text/x-patch"},
{"patch", "text/x-patch"},
{"c", "text/x-csrc"},
{"h", "text/x-chdr"},
{"o", "text/x-object"},
{"ko", "text/x-object"},
{"bmp", "image/bmp"},
{"gif", "image/gif"},
{"png", "image/png"},
{"jpg", "image/jpeg"},
{"jpeg", "image/jpeg"},
{"svg", "image/svg+xml"},
{"json", "application/json"},
{"jsonp", "application/javascript"},
{"zip", "application/zip"},
{"pdf", "application/pdf"},
{"xml", "application/xml"},
{"xsl", "application/xml"},
{"doc", "application/msword"},
{"ppt", "application/vnd.ms-powerpoint"},
{"xls", "application/vnd.ms-excel"},
{"odt", "application/vnd.oasis.opendocument.text"},
{"odp", "application/vnd.oasis.opendocument.presentation"},
{"pl", "application/x-perl"},
{"sh", "application/x-shellscript"},
{"php", "application/x-php"},
{"deb", "application/x-deb"},
{"iso", "application/x-cd-image"},
{"tar.gz", "application/x-compressed-tar"},
{"tgz", "application/x-compressed-tar"},
{"gz", "application/x-gzip"},
{"tar.bz2", "application/x-bzip-compressed-tar"},
{"tbz", "application/x-bzip-compressed-tar"},
{"bz2", "application/x-bzip"},
{"tar", "application/x-tar"},
{"rar", "application/x-rar-compressed"},
{"mp3", "audio/mpeg"},
{"ogg", "audio/x-vorbis+ogg"},
{"wav", "audio/x-wav"},
{"mpg", "video/mpeg"},
{"mpeg", "video/mpeg"},
{"avi", "video/x-msvideo"},
{"README", "text/plain"},
{"log", "text/plain"},
{"cfg", "text/plain"},
{"conf", "text/plain"},
{"pac", "application/x-ns-proxy-autoconfig"},
{"wpad.dat", "application/x-ns-proxy-autoconfig"},
{"appcache", "text/cache-manifest"},
{"manifest", "text/cache-manifest"},
{NULL, NULL}};
/*--------------------------------------------------------------------------*/
static const char *file_mime_lookup(const char *path)
{
const struct mimetype_s *m = &g_mime_types[0];
const char *e;
while (m->extn)
{
e = &path[strlen(path) - 1];
while (e >= path)
{
if ((*e == '.' || *e == '/') && !strcasecmp(&e[1], m->extn))
return m->mime;
e--;
}
m++;
}
return "application/octet-stream";
}
/*! ----------------------------------------------------------------------------
* @fn restd_rest_handler
*
@@ -46,48 +151,60 @@
*/
int restd_rest_handler(short event, restd_conn_t *conn, void *userdata)
{
bool found = false;
DEBUG("JBN call_hooks: event 0x%x", event);
int reason = RESTD_ERROR_PATH_NOT_FOUND;
// DEBUG("restd_rest_handler: event 0x%x", event);
restd_http_t *http = (restd_http_t *)restd_conn_get_extra(conn);
char *root_path;
qlist_t *hooks = conn->server->hooks;
qlist_obj_t obj;
bzero((void *)&obj, sizeof(qlist_obj_t));
while (hooks->getnext(hooks, &obj, false) == true)
{
DEBUG(">>>>>>>>>\n");
restd_hook_t *hook = (restd_hook_t *)obj.data;
if (hook->cb)
{
DEBUG("JBN call_hooks: method: %s - %s \n", hook->method, conn->method);
DEBUG("JBN call_hooks: path: %s - %s\n", hook->path, http->request.path);
if ((hook->method == NULL) || (conn->method == NULL) || (strcmp(hook->method, conn->method) != 0))
{
DEBUG("JBN - ca va pas 1 \n");
continue;
}
// DEBUG("call_hooks: method: %s - %s \n", hook->method, conn->method);
// DEBUG("call_hooks: path: %s - %s\n", hook->path, http->request.path);
if ((hook->path == NULL) || (http->request.path == NULL) || (strcmp(hook->path, http->request.path) != 0))
{
DEBUG("JBN - ca va pas 2 \n");
continue;
}
DEBUG("JBN FOUND !!!!\n");
return RESTD_OK;
//int status = hook->cb(event, conn, hook->userdata);
//if (status != RESTD_OK)
//{
// return status;
//}
}
}
if (found == false)
// DEBUG("HOOK FOUND !!!!\n");
if ((hook->method == NULL) || (conn->method == NULL) || (strcmp(hook->method, conn->method) != 0))
{
printf("Call error handler...\n");
return RESTD_NOT_ALLOWED;
// DEBUG("Hook found but method failed.\n");
reason = RESTD_ERROR_METHOD_NOT_ALLOWED;
break;
}
DEBUG("JBN call_hooks - DONE\n");
return RESTD_OK;
return hook->cb(event, conn, hook->userdata);
}
}
// No Hook Found check if it's a real file into document root.
root_path = restd_server_get_option(conn->server, "server.root_path");
if ((root_path != NULL) && (strlen(root_path) != 0))
{
FILE *file;
char buf[1024] = "";
qstrcatf(buf, "%s%s", root_path, http->request.path);
if ((file = fopen(buf, "r")))
{
long fsize;
char *file_buf;
fseek(file, 0, SEEK_END);
fsize = ftell(file);
fseek(file, 0, SEEK_SET);
file_buf = malloc(fsize + 1);
fread(file_buf, 1, fsize, file);
fclose(file);
file_buf[fsize] = 0;
printf("mime type:%s\n", file_mime_lookup(buf));
restd_http_response(conn, 200, file_mime_lookup(buf), file_buf, fsize);
return RESTD_CLOSE;
}
}
return conn->server->error_handler(reason, conn, NULL);
}

View File

@@ -87,6 +87,8 @@ static void *get_userdata(restd_conn_t *conn, int index);
#define RESTD_SERVER_OPTIONS { \
{"server.port", "8888"}, \
\
{"server.root_path", ""}, \
\
/* Addr format IPv4="1.2.3.4", IPv6="1:2:3:4:5:6", Unix="/path" */ \
{"server.addr", "0.0.0.0"}, \
\

View File

@@ -28,8 +28,12 @@
/*-------------------------------- INCLUDES ---------------------------------*/
#include <getopt.h>
#include <restd.h>
/*--------------------------------------------------------------------------*/
int my_http_get_handler(short event, restd_conn_t *conn, void *userdata)
{
if (event & RESTD_EVENT_READ)
@@ -43,28 +47,51 @@ int my_http_get_handler(short event, restd_conn_t *conn, void *userdata)
return RESTD_OK;
}
int my_http_default_handler(short event, restd_conn_t *conn, void *userdata)
/*--------------------------------------------------------------------------*/
int my_error_handler(short event, restd_conn_t *conn, void *userdata)
{
printf("Error Handler...\n");
if (event & RESTD_EVENT_READ)
int http_code = 500;
if (event & RESTD_ERROR_METHOD_NOT_ALLOWED)
{
if (restd_http_get_status(conn) == RESTD_HTTP_REQ_DONE)
http_code = 405;
}
else if (event & RESTD_ERROR_PATH_NOT_FOUND)
{
restd_http_response(conn, 500, "application/json", "{\"status\":\"error\"}", 18);
http_code = 404;
}
restd_http_response(conn, http_code, "application/json", "{\"status\":\"error\"}", 18);
return RESTD_CLOSE; // Close connection.
}
/*--------------------------------------------------------------------------*/
void usage(void)
{
printf("Usage : domo-iot [web server path] \n");
printf("web server path: \t root path of the Web server.\n");
}
return RESTD_OK;
}
/*--------------------------------------------------------------------------*/
int main(int argc, char **argv)
{
restd_server_t *server;
if (argc < 2)
{
usage();
return -1;
}
restd_log_level(RESTD_LOG_DEBUG);
restd_server_t *server = restd_server_new();
server = restd_server_new();
restd_server_set_option(server, "server.port", "8888");
restd_server_set_option(server, "server.root_path", argv[1]);
restd_server_register_request_handler(server, restd_rest_handler);
restd_server_register_error_handler(server, my_http_default_handler);
restd_server_register_error_handler(server, my_error_handler);
restd_server_register_hook(server, restd_http_handler, NULL);
restd_server_register_hook_on_path(server, "GET", "/api/zob", my_http_get_handler, NULL);