diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-07-21 01:07:57 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-07-21 01:40:55 +0200 |
| commit | 7fe639b3ba7a253627d2cd34f3b97bd95b0a90b3 (patch) | |
| tree | ab50067686bfdc87b35ddfa29112af5ca0440574 /handler.c | |
| parent | 1d4480c0f36f9d4e75c00e58c065b4c43e53b4f3 (diff) | |
| download | slcl-7fe639b3ba7a253627d2cd34f3b97bd95b0a90b3.tar.gz | |
Remove files now provided by slweb
Diffstat (limited to 'handler.c')
| -rw-r--r-- | handler.c | 315 |
1 files changed, 0 insertions, 315 deletions
diff --git a/handler.c b/handler.c deleted file mode 100644 index 1d7e922..0000000 --- a/handler.c +++ /dev/null @@ -1,315 +0,0 @@ -#define _POSIX_C_SOURCE 200809L - -#include "handler.h" -#include "http.h" -#include "server.h" -#include "wildcard_cmp.h" -#include <errno.h> -#include <stdbool.h> -#include <stddef.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -struct handler -{ - struct handler_cfg cfg; - struct elem - { - char *url; - enum http_op op; - handler_fn f; - void *user; - } *elem; - - struct server *server; - struct client - { - struct handler *h; - struct server_client *c; - struct http_ctx *http; - struct client *next; - } *clients; - - size_t n_cfg; -}; - -static int on_read(void *const buf, const size_t n, void *const user) -{ - struct client *const c = user; - - return server_read(buf, n, c->c); -} - -static int on_write(const void *const buf, const size_t n, void *const user) -{ - struct client *const c = user; - - return server_write(buf, n, c->c); -} - -static int on_payload(const struct http_payload *const p, - struct http_response *const r, void *const user) -{ - struct client *const c = user; - struct handler *const h = c->h; - - for (size_t i = 0; i < h->n_cfg; i++) - { - const struct elem *const e = &h->elem[i]; - - if (e->op == p->op && !wildcard_cmp(p->resource, e->url, true)) - return e->f(p, r, e->user); - } - - fprintf(stderr, "Not found: %s\n", p->resource); - - *r = (const struct http_response) - { - .status = HTTP_STATUS_NOT_FOUND - }; - - return 0; -} - -static int on_length(const unsigned long long len, - const struct http_cookie *const c, struct http_response *const r, - void *const user) -{ - struct client *const cl = user; - struct handler *const h = cl->h; - - if (h->cfg.length) - return h->cfg.length(len, c, r, h->cfg.user); - - return 0; -} - -static struct client *find_or_alloc_client(struct handler *const h, - struct server_client *const c) -{ - for (struct client *cl = h->clients; cl; cl = cl->next) - { - if (cl->c == c) - return cl; - } - - struct client *const ret = malloc(sizeof *ret); - - if (!ret) - { - fprintf(stderr, "%s: malloc(3): %s\n", __func__, strerror(errno)); - return NULL; - } - - const struct http_cfg cfg = - { - .read = on_read, - .write = on_write, - .payload = on_payload, - .length = on_length, - .user = ret, - .tmpdir = h->cfg.tmpdir - }; - - *ret = (const struct client) - { - .c = c, - .h = h, - .http = http_alloc(&cfg) - }; - - if (!ret->http) - { - fprintf(stderr, "%s: http_alloc failed\n", __func__); - return NULL; - } - - if (!h->clients) - h->clients = ret; - else - { - for (struct client *c = h->clients; c; c = c->next) - if (!c->next) - { - c->next = ret; - break; - } - } - - return ret; -} - -static void client_free(struct client *const c) -{ - if (c) - http_free(c->http); - - free(c); -} - -static int remove_client_from_list(struct handler *const h, - struct client *const c) -{ - int ret = -1; - - if (server_client_close(h->server, c->c)) - { - fprintf(stderr, "%s: server_client_close failed\n", - __func__); - goto end; - } - - for (struct client *cl = h->clients, *prev = NULL; cl; - prev = cl, cl = cl->next) - { - if (cl == c) - { - if (!prev) - h->clients = c->next; - else - prev->next = cl->next; - - break; - } - } - - ret = 0; - -end: - client_free(c); - return ret; -} - -int handler_listen(struct handler *const h, const short port) -{ - if (!(h->server = server_init(port))) - { - fprintf(stderr, "%s: server_init failed\n", __func__); - return -1; - } - - for (;;) - { - bool exit, io; - struct server_client *const c = server_poll(h->server, &io, &exit); - - if (exit) - { - printf("Exiting...\n"); - break; - } - else if (!c) - { - fprintf(stderr, "%s: server_poll failed\n", __func__); - return -1; - } - - struct client *const cl = find_or_alloc_client(h, c); - - if (!cl) - { - fprintf(stderr, "%s: find_or_alloc_client failed\n", __func__); - return -1; - } - else if (io) - { - bool write, close; - const int res = http_update(cl->http, &write, &close); - - if (res || close) - { - if (res < 0) - { - fprintf(stderr, "%s: http_update failed\n", __func__); - return -1; - } - else if (remove_client_from_list(h, cl)) - { - fprintf(stderr, "%s: remove_client_from_list failed\n", - __func__); - return -1; - } - } - else - server_client_write_pending(cl->c, write); - } - } - - return 0; -} - -static void free_clients(struct handler *const h) -{ - for (struct client *c = h->clients; c;) - { - struct client *const next = c->next; - - server_client_close(h->server, c->c); - client_free(c); - c = next; - } -} - -void handler_free(struct handler *const h) -{ - if (h) - { - for (size_t i = 0; i < h->n_cfg; i++) - free(h->elem[i].url); - - free(h->elem); - free_clients(h); - server_close(h->server); - } - - free(h); -} - -struct handler *handler_alloc(const struct handler_cfg *const cfg) -{ - struct handler *const h = malloc(sizeof *h); - - if (!h) - { - fprintf(stderr, "%s: malloc(3) handler: %s\n", - __func__, strerror(errno)); - return NULL; - } - - *h = (const struct handler){.cfg = *cfg}; - return h; -} - -int handler_add(struct handler *const h, const char *url, - const enum http_op op, const handler_fn f, void *const user) -{ - const size_t n = h->n_cfg + 1; - struct elem *const elem = realloc(h->elem, n * sizeof *h->elem); - - if (!elem) - { - fprintf(stderr, "%s: realloc(3): %s\n", __func__, strerror(errno)); - return -1; - } - - struct elem *const e = &elem[h->n_cfg]; - - *e = (const struct elem) - { - .url = strdup(url), - .op = op, - .f = f, - .user = user - }; - - if (!e->url) - { - fprintf(stderr, "%s: strdup(3): %s\n", __func__, strerror(errno)); - return -1; - } - - h->elem = elem; - h->n_cfg = n; - return 0; -} |
