aboutsummaryrefslogtreecommitdiff
path: root/handler.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-07-21 01:07:57 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-07-21 01:40:55 +0200
commit7fe639b3ba7a253627d2cd34f3b97bd95b0a90b3 (patch)
treeab50067686bfdc87b35ddfa29112af5ca0440574 /handler.c
parent1d4480c0f36f9d4e75c00e58c065b4c43e53b4f3 (diff)
downloadslcl-7fe639b3ba7a253627d2cd34f3b97bd95b0a90b3.tar.gz
Remove files now provided by slweb
Diffstat (limited to 'handler.c')
-rw-r--r--handler.c315
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;
-}