aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c104
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;
+}