Mercurial > paster
diff http.c @ 12:93f0440d452e
pasterd: add siimple theme
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 06 Feb 2020 10:29:02 +0100 |
parents | 75cfe3795de3 |
children | 29033b4fe558 |
line wrap: on
line diff
--- a/http.c Wed Feb 05 17:28:53 2020 +0100 +++ b/http.c Thu Feb 06 10:29:02 2020 +0100 @@ -17,7 +17,9 @@ */ #include <sys/types.h> +#include <sys/stat.h> #include <assert.h> +#include <ctype.h> #include <limits.h> #include <stdarg.h> #include <stdint.h> @@ -27,6 +29,7 @@ #include <unistd.h> #include <kcgi.h> +#include <kcgihtml.h> #include "config.h" #include "database.h" @@ -40,6 +43,7 @@ static void page_fork(struct kreq *); static void page_paste(struct kreq *); static void page_download(struct kreq *); +static void page_static(struct kreq *); enum page { PAGE_INDEX, @@ -47,6 +51,7 @@ PAGE_FORK, PAGE_PASTE, PAGE_DOWNLOAD, + PAGE_STATIC, PAGE_LAST /* Not used. */ }; @@ -56,6 +61,7 @@ [PAGE_FORK] = "fork", [PAGE_PASTE] = "paste", [PAGE_DOWNLOAD] = "download", + [PAGE_STATIC] = "static" }; static void (*handlers[])(struct kreq *req) = { @@ -63,7 +69,8 @@ [PAGE_NEW] = page_new, [PAGE_FORK] = page_fork, [PAGE_PASTE] = page_paste, - [PAGE_DOWNLOAD] = page_download + [PAGE_DOWNLOAD] = page_download, + [PAGE_STATIC] = page_static }; struct tmpl_index { @@ -346,6 +353,22 @@ } static void +replace(char **dst, const char *s) +{ + assert(dst); + assert(s); + + /* Trim leading spaces. */ + while (*s && isspace(*s)) + s++; + + if (*s) { + free(*dst); + *dst = estrdup(s); + } +} + +static void render_languages(struct kreq *req, const struct paste *paste) { for (const char **l = languages; *l != NULL; ++l) { @@ -382,36 +405,41 @@ { struct tmpl_paste *data = arg; struct paste *paste = &data->paste; + struct khtmlreq htmlreq; + + khtml_open(&htmlreq, data->req, KHTML_PRETTY); switch (index) { case 0: - khttp_puts(data->req, paste->uuid); + khtml_puts(&htmlreq, paste->uuid); break; case 1: - khttp_puts(data->req, paste->title); + khtml_puts(&htmlreq, paste->title); break; case 2: - khttp_puts(data->req, paste->author); + khtml_puts(&htmlreq, paste->author); break; case 3: - khttp_puts(data->req, paste->language); + khtml_puts(&htmlreq, paste->language); break; case 4: - khttp_puts(data->req, paste->code); + khtml_puts(&htmlreq, paste->code); break; case 5: - khttp_puts(data->req, bstrftime("%c", localtime(&paste->timestamp))); + khtml_puts(&htmlreq, bstrftime("%c", localtime(&paste->timestamp))); break; case 6: - khttp_puts(data->req, bprintf("%s", paste->visible ? "Yes" : "No")); + khtml_puts(&htmlreq, bprintf("%s", paste->visible ? "Yes" : "No")); break; case 7: - khttp_puts(data->req, ttl(paste->timestamp, paste->duration)); + khtml_puts(&htmlreq, ttl(paste->timestamp, paste->duration)); break; default: break; } + khtml_close(&htmlreq); + return true; } @@ -420,30 +448,35 @@ { struct tmpl_index *data = arg; struct paste *paste = &data->pastes[data->current]; + struct khtmlreq htmlreq; + + khtml_open(&htmlreq, data->req, KHTML_PRETTY); switch (index) { case 0: - khttp_puts(data->req, paste->uuid); + khtml_puts(&htmlreq, paste->uuid); break; case 1: - khttp_puts(data->req, paste->title); + khtml_puts(&htmlreq, paste->title); break; case 2: - khttp_puts(data->req, paste->author); + khtml_puts(&htmlreq, paste->author); break; case 3: - khttp_puts(data->req, paste->language); + khtml_puts(&htmlreq, paste->language); break; case 4: - khttp_puts(data->req, ttl(paste->timestamp, paste->duration)); + khtml_puts(&htmlreq, ttl(paste->timestamp, paste->duration)); break; case 5: - khttp_puts(data->req, bstrftime("%c", localtime(&paste->timestamp))); + khtml_puts(&htmlreq, bstrftime("%c", localtime(&paste->timestamp))); break; default: break; } + khtml_close(&htmlreq); + return true; } @@ -451,6 +484,8 @@ tmpl_index(size_t index, void *arg) { /* No check, only one index. */ + (void)index; + struct tmpl_index *data = arg; const struct ktemplate kt = { .key = tmpl_index_pastes_keywords, @@ -472,19 +507,22 @@ { struct tmpl_paste *data = arg; struct paste *paste = &data->paste; + struct khtmlreq htmlreq; + + khtml_open(&htmlreq, data->req, KHTML_PRETTY); switch (index) { case 0: if (paste->title) - khttp_puts(data->req, paste->title); + khtml_puts(&htmlreq, paste->title); break; case 1: if (paste->author) - khttp_puts(data->req, paste->author); + khtml_puts(&htmlreq, paste->author); break; case 2: if (paste->code) - khttp_puts(data->req, paste->code); + khtml_puts(&htmlreq, paste->code); break; case 3: /* Add checked attribute to combobox. */ @@ -501,6 +539,8 @@ break; }; + khtml_close(&htmlreq); + return true; } @@ -586,7 +626,10 @@ page_new_post(struct kreq *req) { struct paste paste = { - .visible = true + .author = estrdup("Anonymous"), + .title = estrdup("Untitled"), + .language = estrdup("nohighlight"), + .visible = true }; for (size_t i = 0; i < req->fieldsz; ++i) { @@ -594,11 +637,11 @@ const char *val = req->fields[i].val; if (strcmp(key, "title") == 0) - paste.title = estrdup(val); + replace(&paste.title, val); else if (strcmp(key, "author") == 0) - paste.author = estrdup(val); + replace(&paste.author, val); else if (strcmp(key, "language") == 0) - paste.language = estrdup(val); + replace(&paste.language, val); else if (strcmp(key, "duration") == 0) paste.duration = duration(val); else if (strcmp(key, "code") == 0) @@ -607,18 +650,14 @@ paste.visible = strcmp(val, "on") != 0; } - if (!paste.title || !paste.author || !paste.language || !paste.code) - page(req, NULL, KHTTP_400, "400.html"); + if (!database_insert(&paste)) + page(req, NULL, KHTTP_500, "500.html"); else { - if (!database_insert(&paste)) - page(req, NULL, KHTTP_500, "500.html"); - else { - /* Redirect to paste details. */ - khttp_head(req, kresps[KRESP_STATUS], "%s", khttps[KHTTP_302]); - khttp_head(req, kresps[KRESP_LOCATION], "/paste/%s", paste.uuid); - khttp_body(req); - khttp_free(req); - } + /* Redirect to paste details. */ + khttp_head(req, kresps[KRESP_STATUS], "%s", khttps[KHTTP_302]); + khttp_head(req, kresps[KRESP_LOCATION], "/paste/%s", paste.uuid); + khttp_body(req); + khttp_free(req); } paste_finish(&paste); @@ -746,11 +785,48 @@ } static void +page_static_get(struct kreq *req) +{ + struct stat st; + char path[PATH_MAX]; + + snprintf(path, sizeof (path), "%s%s", config.themedir, req->fullpath); + + if (stat(path, &st) < 0) + page(req, NULL, KHTTP_404, "404.html"); + else { + khttp_head(req, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); + khttp_head(req, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[req->mime]); + khttp_head(req, kresps[KRESP_CONTENT_TYPE], + "%llu", (unsigned long long)(st.st_size)); + khttp_body(req); + khttp_template(req, NULL, path); + khttp_free(req); + } +} + +static void +page_static(struct kreq *req) +{ + switch (req->method) { + case KMETHOD_GET: + page_static_get(req); + break; + default: + page(req, NULL, KHTTP_400, "400.html"); + break; + } +} + +static void process(struct kreq *req) { assert(req); - handlers[req->page](req); + if (req->page == PAGE_LAST) + page(req, NULL, KHTTP_404, "404.html"); + else + handlers[req->page](req); } void