diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/endpoints.c | 90 | ||||
-rw-r--r-- | src/main.c | 24 |
2 files changed, 56 insertions, 58 deletions
diff --git a/src/endpoints.c b/src/endpoints.c index 8d1c05f..a4ac35a 100644 --- a/src/endpoints.c +++ b/src/endpoints.c @@ -8,25 +8,30 @@ #include <microhttpd.h> +#include "common.h" +#include "sql.h" #include <log.h> #define CONTAINER_IMPLEMENTATION #define JACSON_IMPLEMENTATION #define JACSON_EXPORT_RSNPRINTF #include <jacson.h> - -#include "common.h" -#include "sql.h" +#define STRINGBUILDER_IMPLEMENTATION +#include <stringbuilder.h> + +#define OUT(arg) jac_sb_append_buf(&resp, arg) + +#define REQUIRE_METHOD(methodvar, methodstr, statusp) \ +do { \ + if (strcmp((methodvar), (methodstr)) != 0) { \ + *statusp = MHD_HTTP_METHOD_NOT_ALLOWED; \ + return NULL; \ + } \ +} while (0) const char *const JSON_ERROR = "{\"error\":\"%s\"}"; const char *const HTML_ERROR = "<!DOCTYPE html><html><body>Error: %s</body></html>"; -const char *const INSUFFICIENT_ARGUMENTS = "insufficient arguments"; -const char *const INVALID_ARGUMENTS = "invalid arguments"; -const char *const OCCUPIED = "occupied"; -const char *const SERVER_ERRORMSG = "server error"; -const char *const UNKNOWN = "unknown"; -const char *const HTML_PROLOGUE = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"></head><body>"; -const char *const HTML_EPILOGUE = "</html></body>"; +const char *HTTPHOSTNAME = "http://127.0.0.1:80"; struct global_args { enum { @@ -43,19 +48,6 @@ static const struct fmt_const fmts[] = { [GA_FMT_HTML] = {HTML_ERROR,"text/html"} }; -// string builder -struct sb { - char* str; - size_t sz; - size_t ln; -}; - -size_t sbprintf(struct sb* s, const char* fmt, ...) { - va_list l; - va_start(l, fmt); - return s->ln += __jacson_vrsnprintf(&s->str, &s->sz, s->ln, fmt, l); -} - struct global_args parse_global_args(struct MHD_Connection *connection) { const char* key, *val; struct global_args ret = { .format = GA_FMT_JSON }; @@ -65,62 +57,68 @@ struct global_args parse_global_args(struct MHD_Connection *connection) { return ret; } +void init(const char *db) { + sqlite_init(db); + const char *new_httphostname = getenv("HTTPHOSTNAME"); + if (new_httphostname) HTTPHOSTNAME = new_httphostname; +} + // index, path: / struct MHD_Response *ENDP_(struct MHD_Connection* connection, int *status) { return get_from_file("www/index.html"); } enum MHD_Result arg_builder (void *cls, enum MHD_ValueKind kind, const char *key, const char *value) { - struct sb *html = cls; - html->ln += __jacson_rsnprintf(&html->str, &html->sz, html->ln, "<li><p style=\"font-style:monospace;\">%s: %s</p></li>", key, value); + jac_sb *html = cls; + jac_sb_snprintf(html, "<li><p style=\"font-style:monospace;\">%s: %s</p></li>", key, value ? value : "<none>"); return MHD_YES; } // path: /getargs -struct MHD_Response *ENDP_getargs(struct MHD_Connection *connection, int *status) { - struct sb html = {calloc(64, 1), 63, 0}; - html.ln += __jacson_rsnprintf(&html.str, &html.sz, html.ln, - "<!DOCTYPE html><html><head><meta charset=\"utf-8\"></head><body><h3>List of arguments</h3><ol>"); - MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, &arg_builder, &html); - html.ln += __jacson_rsnprintf(&html.str, &html.sz, html.ln, "</ol></body></html>"); - const char *val = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "test"); - if (val) LDEBUGVF(stderr, "test = %s\n", val); - LDEBUGVF(stderr, "test pointer = %p", val); - return MHD_create_response_from_buffer(html.ln, html.str, MHD_RESPMEM_MUST_FREE); +struct MHD_Response *ENDP_getargs(const char *method, struct MHD_Connection *connection, int *status) { + jac_sb resp = jac_sb_new(64); +# include "template/args.html" + return MHD_create_response_from_buffer(resp.size, resp.data, MHD_RESPMEM_MUST_FREE); } // API, path: /api/linkadd -struct MHD_Response *ENDP_api_linkadd(struct MHD_Connection *connection, int *status) { +struct MHD_Response *ENDP_api_linkadd(const char *method, struct MHD_Connection *connection, int *status) { + REQUIRE_METHOD(method, "GET", status); const char *url = NULL, *path = NULL; char newurl[12] = {0}, *newurlp = newurl; - struct sb resp = {malloc(64), 63, 0}; + jac_sb resp = jac_sb_new(64); struct global_args glob = parse_global_args(connection); struct MHD_Response *response; if ((url = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "url")) == NULL || *url == '\0') { *status = db_error_status(DBERROR_ARGS); - sbprintf(&resp, fmts[glob.format].error, INSUFFICIENT_ARGUMENTS); + jac_sb_snprintf(&resp, fmts[glob.format].error, db_error(DBERROR_ARGS)); goto exit; } path = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "try"); - if (*path == '\0') path = NULL; + if (path && *path == '\0') path = NULL; enum dberror err; if ((err = db_add_url(url, path, &newurlp)) != DBERROR_SUCCESS) { LWARNVF("Database write failed with error %i. Sql error: %s", err, sqlite3_errmsg(state.db)); *status = db_error_status(err); - sbprintf(&resp, fmts[glob.format].error, db_error(err)); + jac_sb_snprintf(&resp, fmts[glob.format].error, db_error(err)); goto exit; } - if (glob.format == GA_FMT_JSON) sbprintf(&resp, "{\"url\":\"%s\"}", newurlp); - else sbprintf(&resp, "%sYour URL: <a href=\"/%s\">/%s</a>%s", HTML_PROLOGUE, newurlp, newurlp, HTML_EPILOGUE); + if (glob.format == GA_FMT_JSON) + jac_sb_snprintf(&resp, "{\"url\":\"%s\"}", newurlp); + else if (glob.format == GA_FMT_HTML) { +# include "template/linkadd.html" + } exit: - response = MHD_create_response_from_buffer(resp.ln, resp.str, MHD_RESPMEM_MUST_FREE); + response = MHD_create_response_from_buffer(resp.size, resp.data, MHD_RESPMEM_MUST_FREE); MHD_add_response_header(response, "Content-Type", fmts[glob.format].content_type); return response; } // API, path: /api/linkdel -struct MHD_Response *ENDP_api_linkdel(struct MHD_Connection *connection, int *status) { - +struct MHD_Response *ENDP_api_linkdel(const char *method, struct MHD_Connection *connection, int *status) { + return MHD_create_response_from_buffer(4, "TODO", MHD_RESPMEM_PERSISTENT); } // API, path: /api/linkget -struct MHD_Response *ENDP_api_linkget(struct MHD_Connection *connection, int *status) { } +struct MHD_Response *ENDP_api_linkget(const char *method, struct MHD_Connection *connection, int *status) { + return MHD_create_response_from_buffer(4, "TODO", MHD_RESPMEM_PERSISTENT); +} @@ -49,7 +49,7 @@ enum MHD_Result process_connection(void *cls, struct MHD_Connection *connection, } else if (handler != NULL) { /* endpoint access */ LINFOF("Accessed endpoint at url %s", url); - res = handler(connection, &status); + res = handler(method, connection, &status); } else if ((newurl = arg->query(url + 1)) != NULL) { LINFOF("Redirect from %s to %s", url, newurl); response = "<!DOCTYPE html><html><body>Recirecting...</body></html>"; @@ -85,8 +85,8 @@ void reload_dylib(const char *so_path, const char *db_path) { if (!arg.dylib) LCRITVF(1, "Could not open dynamic library: %s\n", dlerror()); arg.query = dlsym(arg.dylib, "db_get_url"); if (!arg.query) LCRITVF(1, "Could not load `db_get_url` from shared library: %s", dlerror()); - arg.constructor = dlsym(arg.dylib, "sqlite_init"); - if (!arg.constructor) LCRITVF(1, "Could not load `sqlite_init` from shared library: %s", dlerror()); + arg.constructor = dlsym(arg.dylib, "init"); + if (!arg.constructor) LCRITVF(1, "Could not load `init` from shared library: %s", dlerror()); arg.constructor(db_path); arg.destructor = dlsym(arg.dylib, "sqlite_deinit"); if (!arg.destructor) LCRITVF(1, "Could not load `sqlite_deinit` from shared library: %s", dlerror()); @@ -118,15 +118,15 @@ int main(int argc, char *argv[]) { const char *dlpath = DEFAULT_ENDPOINTS_PATH; const char *dbpath = DEFAULT_DATABASE_PATH; struct MHD_Daemon *daemon = init(&sig, dlpath, dbpath); - /* while (reload_library == 0) { */ - /* sigsuspend(&sig); */ - /* if (reload_library == 1) { */ - /* reload_dylib(dlpath, dbpath); */ - /* reload_library = 0; */ - /* } */ - /* } */ - getchar(); - if (arg.destructor) arg.destructor(); + while (reload_library == 0) { + sigsuspend(&sig); + if (reload_library == 1) { + reload_dylib(dlpath, dbpath); + reload_library = 0; + } + } + getchar(); /* to be replaced with fork later */ + arg.destructor(); dlclose(arg.dylib); MHD_stop_daemon(daemon); return 0; |