diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..36df30a --- /dev/null +++ b/src/main.c @@ -0,0 +1,104 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dlfcn.h> + +#include <microhttpd.h> +#include <sqlite3.h> + +#include <log.h> +#define COMMON_IMPLEMENTATION +#include <common.h> + +/* sqlite leastunused implementation */ +struct slidid { sqlite3_int64 il, in, res; }; +void step_leastunused(sqlite3_context* ctx, int argc, sqlite3_value** argv) { + struct slidid *idx = sqlite3_aggregate_context(ctx, sizeof *idx); + if (idx->res) return; + idx->in = sqlite3_value_int64(argv[0]); + if (idx->il + 1 != idx->in) idx->res = idx->il + 1; + idx->il = idx->in; +} +void final_leastunused(sqlite3_context* ctx) { + struct slidid *idx = sqlite3_aggregate_context(ctx, 0); + sqlite3_result_int(ctx, idx->res); +} + +sqlite3 *sqlite_init(const char *db) { + sqlite3 *ret; + sqlite3_open_v2(db, &ret, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL); + if (ret == NULL) LCRIT(1, "could not open sqlite3 database"); + sqlite3_create_function(ret, "leastunused", 1, SQLITE_UTF8, NULL, NULL, step_leastunused, final_leastunused); + return ret; +} + +enum MHD_Result process_connection(void *dylib, struct MHD_Connection *connection, const char *url, + const char *method, const char *version, const char *upload_data, + size_t *upload_data_size, void **req_cls) +{ + LDEBUGF("\nurl: %s\nmethod:%s\nversion:%s\nupload_data:%s\nsize:%zu\n", + url, method, version, upload_data, *upload_data_size); + /* Load function with the name of the url from shared library */ + endpoint handler = dlsym(dylib, url); + query_func query = dlsym(dylib, "db_get_url"); + struct MHD_Response *res; + int status = MHD_HTTP_OK; + const char *response; + char *newurl; + if (query == NULL) { + response = "<!DOCTYPE html><html><body>Temporary server error: could not open database</body></html>"; + res = MHD_create_response_from_buffer(strlen(response), (void*)response, MHD_RESPMEM_PERSISTENT); + status = MHD_HTTP_INTERNAL_SERVER_ERROR; + goto response; + } + if (strcasecmp(method, "GET")) { + status = MHD_HTTP_METHOD_NOT_ALLOWED; + res = MHD_create_response_from_buffer(18, "Method not allowed", MHD_RESPMEM_PERSISTENT); + goto response; + } + if (handler != NULL) { + /* endpoint access */ + LINFOF("Accessed endpoint at url %s", url); + res = handler(connection, &status); + } else if ((newurl = query(url)) != NULL) { + LINFOF("Redirect from %s to %s", url, newurl); + /* if (newurl == NULL) { */ + /* free(newurl); */ + /* response = "<!DOCTYPE html><html><body>Page does not exist</body></html>"; */ + /* res = MHD_create_response_from_buffer(strlen(response), (void*)response, MHD_RESPMEM_PERSISTENT); */ + /* status = MHD_HTTP_NOT_FOUND; */ + /* goto response; */ + /* } */ + response = "<!DOCTYPE html><html><body>Recirecting...</body></html>"; + res = MHD_create_response_from_buffer(strlen(response), (void*)response, MHD_RESPMEM_PERSISTENT); + MHD_add_response_header(res, "Location", newurl); + status = MHD_HTTP_FOUND; + } else if ((res = get_from_file(url + 1)) != NULL) { + /* fallback file access */ + LINFOF("Accessed file at url %s", url); + } else { + /* error */ + LINFOF("Failed access to endpoint\t%s", url); + const char* error = "\"resource does not exist\""; + res = MHD_create_response_from_buffer(strlen(error), (void*)error, MHD_RESPMEM_PERSISTENT); + status = MHD_HTTP_NOT_FOUND; + } +response: + MHD_queue_response(connection, status, res); + MHD_destroy_response(res); + return MHD_YES; +} + + +int main(int argc, char *argv[]){ + void* dylib = dlopen("./endpoints.so", RTLD_NOW); + if (!dylib) LCRITF(1, "Could not open dynamic library: %s\n", dlerror()); + struct MHD_Daemon *daemon = MHD_start_daemon(MHD_USE_POLL | MHD_USE_INTERNAL_POLLING_THREAD, 8080, NULL, NULL, process_connection, dylib, MHD_OPTION_END); + if (daemon == NULL) LCRITV(1, "could not initialize daemon"); + + getchar(); + + dlclose(dylib); + MHD_stop_daemon(daemon); + return 0; +} |