Mercurial > sci
view scid/http.c @ 47:e8f24896b484
scid: add /workers page
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 16 Aug 2022 18:29:08 +0200 |
parents | 576f4b1ec79f |
children | b474f0985e39 |
line wrap: on
line source
/* * http.c -- HTTP parsing and rendering * * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <sys/types.h> #include <assert.h> #include <stdarg.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <kcgi.h> #include "http.h" #include "log.h" #include "page-api-jobresults.h" #include "page-api-jobs.h" #include "page-api-projects.h" #include "page-api-todo.h" #include "page-api-workers.h" #include "page-index.h" #include "page-jobresults.h" #include "page-static.h" #include "page-workers.h" #include "pageutil.h" #include "scid.h" enum page { PAGE_INDEX, /* Job results at index. */ PAGE_API, /* JSON API with key authentication. */ PAGE_JOBRESULTS, /* List of jobresult for one job. */ PAGE_STATIC, /* Static files delivery. */ PAGE_WORKERS, /* User view of workers. */ PAGE_LAST /* Not used. */ }; static int allowed(const struct kreq *req) { for (size_t i = 0; i < req->reqsz; ++i) if (strcmp(req->reqs[i].key, "X-Api-Key") == 0 && strcmp(req->reqs[i].val, scid.apikey) == 0) return 1; return 0; } static void dispatch_api(struct kreq *req) { static const struct { const char *prefix; void (*handler)(struct kreq *); } apis[] = { { "v1/jobresults", page_api_v1_jobresults }, { "v1/jobs", page_api_v1_jobs }, { "v1/projects", page_api_v1_projects }, { "v1/todo", page_api_v1_todo }, { "v1/workers", page_api_v1_workers }, { NULL, NULL } }; /* Any API page requires authentication key. */ if (req->method == KMETHOD_POST && !allowed(req)) { log_warn("http: client not allowed"); pageutil_status(req, KHTTP_401); } else { for (size_t i = 0; apis[i].prefix; ++i) if (strncmp(req->path, apis[i].prefix, strlen(apis[i].prefix)) == 0) return apis[i].handler(req); pageutil_status(req, KHTTP_404); } } static const char * const pages[] = { [PAGE_INDEX] = "", [PAGE_API] = "api", [PAGE_JOBRESULTS] = "jobresults", [PAGE_STATIC] = "static", [PAGE_WORKERS] = "workers" }; static void (*handlers[])(struct kreq *req) = { [PAGE_INDEX] = page_index, [PAGE_API] = dispatch_api, [PAGE_JOBRESULTS] = page_jobresults, [PAGE_STATIC] = page_static, [PAGE_WORKERS] = page_workers }; static void process(struct kreq *req) { assert(req); log_debug("http: accessing page '%s' method %d", req->fullpath, req->method); if (req->page == PAGE_LAST) pageutil_status(req, KHTTP_404); else handlers[req->page](req); } void http_fcgi_run(void) { struct kreq req; struct kfcgi *fcgi; if (khttp_fcgi_init(&fcgi, NULL, 0, pages, PAGE_LAST, 0) != KCGI_OK) return; while (khttp_fcgi_parse(fcgi, &req) == KCGI_OK) process(&req); khttp_fcgi_free(fcgi); } void http_cgi_run(void) { struct kreq req; if (khttp_parse(&req, NULL, 0, pages, PAGE_LAST, 0) == KCGI_OK) process(&req); }