From 08403b616f9dad83cb1204eec83ba1252e3eb129 Mon Sep 17 00:00:00 2001 From: justanothercatgirl Date: Mon, 31 Mar 2025 15:44:36 +0300 Subject: Early working state. TODO: * /api/linkdel, /api/linkget * finish website --- src/endpoints.c | 121 ++++++++++++-------------------------------------------- 1 file changed, 26 insertions(+), 95 deletions(-) (limited to 'src/endpoints.c') diff --git a/src/endpoints.c b/src/endpoints.c index 990ef29..8d1c05f 100644 --- a/src/endpoints.c +++ b/src/endpoints.c @@ -8,18 +8,18 @@ #include + +#include #define CONTAINER_IMPLEMENTATION #define JACSON_IMPLEMENTATION #define JACSON_EXPORT_RSNPRINTF #include - -#define COMMON_IMPLEMENTATION -#include +#include "common.h" +#include "sql.h" + const char *const JSON_ERROR = "{\"error\":\"%s\"}"; const char *const HTML_ERROR = "Error: %s"; -const char *const JSON_SERVER_ERROR = "{\"error\":\"%s\",\"what\":\"%s\"}"; -const char *const HTML_SERVER_ERROR = "Error: %s
Server error message:

%s

"; const char *const INSUFFICIENT_ARGUMENTS = "insufficient arguments"; const char *const INVALID_ARGUMENTS = "invalid arguments"; const char *const OCCUPIED = "occupied"; @@ -36,11 +36,11 @@ struct global_args { }; struct fmt_const { - const char *error, *server_error, *content_type; + const char *error, *content_type; }; -static struct fmt_const fmts[] = { - [GA_FMT_JSON] = {JSON_ERROR, JSON_SERVER_ERROR, "application/json"}, - [GA_FMT_HTML] = {HTML_ERROR, HTML_SERVER_ERROR, "text/html"} +static const struct fmt_const fmts[] = { + [GA_FMT_JSON] = {JSON_ERROR,"application/json"}, + [GA_FMT_HTML] = {HTML_ERROR,"text/html"} }; // string builder @@ -56,12 +56,6 @@ size_t sbprintf(struct sb* s, const char* fmt, ...) { return s->ln += __jacson_vrsnprintf(&s->str, &s->sz, s->ln, fmt, l); } -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, "
  • %s: %s

  • ", key, value); - return MHD_YES; -} - struct global_args parse_global_args(struct MHD_Connection *connection) { const char* key, *val; struct global_args ret = { .format = GA_FMT_JSON }; @@ -71,82 +65,16 @@ struct global_args parse_global_args(struct MHD_Connection *connection) { return ret; } -char *db_add_url(const char *url, const char *path) { - return "test"; -} - -bool db_del_url(const char *path) { - return false; -} - -// dong: output parameter -char *db_get_info(const char *path, long *dong) { - *dong = 0; - return NULL; -} - -char *db_get_url(const char *path) { - return NULL; -} - -// alphabet: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -// returns 0 if no conversion is available -static inline char itoc(register unsigned long l) { -#ifdef __GNUC__ - char add[256] = { - [0 ... 9] = '0', - [10 ... 35] = 'a' - 10, - [36 ... 61] = 'A' - 10 - 26, - }; - return (l < 62) * (l + add[l]); -#else - if (l < 10) return '0' + l; - if (l < 10 + 26) return 'a' + l - 10; - if (l < 10 + 2 * 26) return 'A' + l - 10 - 26; - return '\0'; -#endif -} -// returns negative number if conversion not available -static inline unsigned long ctoi(register char c) { -#ifdef __GNUC__ - char sub[127] = { - [0 ... '0'-1] = 128, - ['0' ... '9'] = '0', - ['A' ... 'Z'] = 'A' - 26 - 10, - ['a' ... 'z'] = 'a' - 10, - }; - return c - sub[c]; -#else - TODO; -#endif -} -// buf must be at least 12 characters (11 for strnig and 1 for termination byte) -// returns a pointer from which the string starts -static char *itou(register unsigned long i, register char *buf) { - register ssize_t ind = 11; - buf[ind] = '\0'; - buf[ind - 1] = '0'; - while (ind >= 0 && i) { - buf[--ind] = itoc(i % 62); - i /= 62; - } - return buf + ind; -} -static unsigned long utoi(const char *s) { - register unsigned long result = 0; - while (*s) { - result *= 62; - result += ctoi(*s); - ++s; - } - return result; -} - // 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, "
  • %s: %s

  • ", key, value); + return MHD_YES; +} // path: /getargs struct MHD_Response *ENDP_getargs(struct MHD_Connection *connection, int *status) { struct sb html = {calloc(64, 1), 63, 0}; @@ -155,31 +83,34 @@ struct MHD_Response *ENDP_getargs(struct MHD_Connection *connection, int *status MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, &arg_builder, &html); html.ln += __jacson_rsnprintf(&html.str, &html.sz, html.ln, ""); const char *val = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "test"); - if (val) fprintf(stderr, "test = %s\n", val); - fprintf(stderr, "test pointer = %p", val); + 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); } // API, path: /api/linkadd struct MHD_Response *ENDP_api_linkadd(struct MHD_Connection *connection, int *status) { const char *url = NULL, *path = NULL; - char *newurl; + char newurl[12] = {0}, *newurlp = newurl; struct sb resp = {malloc(64), 63, 0}; 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 = MHD_HTTP_BAD_REQUEST; + *status = db_error_status(DBERROR_ARGS); sbprintf(&resp, fmts[glob.format].error, INSUFFICIENT_ARGUMENTS); goto exit; } path = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "try"); - if ((newurl = db_add_url(url, path)) == NULL) { - *status = MHD_HTTP_INTERNAL_SERVER_ERROR; - sbprintf(&resp, fmts[glob.format].server_error, SERVER_ERRORMSG, "database write failed"); + if (*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)); goto exit; } - if (glob.format == GA_FMT_JSON) sbprintf(&resp, "{\"url\":\"%s\"}", newurl); - else sbprintf(&resp, "%sYour URL: /%s%s", HTML_PROLOGUE, newurl, newurl, HTML_EPILOGUE); + if (glob.format == GA_FMT_JSON) sbprintf(&resp, "{\"url\":\"%s\"}", newurlp); + else sbprintf(&resp, "%sYour URL: /%s%s", HTML_PROLOGUE, newurlp, newurlp, HTML_EPILOGUE); exit: response = MHD_create_response_from_buffer(resp.ln, resp.str, MHD_RESPMEM_MUST_FREE); MHD_add_response_header(response, "Content-Type", fmts[glob.format].content_type); -- cgit v1.2.3-70-g09d2