kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit db31f37ab01030e9233ce1c981b763a0c035727d
parent 9e5e698e4b74a39f601dc1610cb7fb37c4bae56c
Author: Joris Vink <joris@coders.se>
Date:   Tue,  3 Mar 2020 11:28:16 +0100

Add a "return" configuration option.

This hooks into the existing redirection framework but allows you
to quickly deny certain paths with a 403 or other status code.

The snippet below would for example declare a filemap served from 'www'
directory but denying all access to the files under the 'data' directory:

filemap		/	www
deny		/data	403

Diffstat:
src/config.c | 33+++++++++++++++++++++++++++++++++
src/http.c | 48++++++++++++++++++++++++++++++------------------
2 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/src/config.c b/src/config.c @@ -110,6 +110,7 @@ static int configure_client_verify_depth(char *); #if !defined(KORE_NO_HTTP) static int configure_route(char *); static int configure_filemap(char *); +static int configure_return(char *); static int configure_redirect(char *); static int configure_static_handler(char *); static int configure_dynamic_handler(char *); @@ -192,6 +193,7 @@ static struct { { "route", configure_route}, { "filemap", configure_filemap }, { "redirect", configure_redirect }, + { "return", configure_return }, { "static", configure_static_handler }, { "dynamic", configure_dynamic_handler }, { "accesslog", configure_accesslog }, @@ -1031,6 +1033,37 @@ configure_route(char *options) } static int +configure_return(char *options) +{ + char *argv[3]; + int elm, status, err; + + if (current_domain == NULL) { + printf("return outside of domain context\n"); + return (KORE_RESULT_ERROR); + } + + elm = kore_split_string(options, " ", argv, 3); + if (elm != 2) { + printf("missing parameters for return\n"); + return (KORE_RESULT_ERROR); + } + + status = kore_strtonum(argv[1], 10, 400, 600, &err); + if (err != KORE_RESULT_OK) { + printf("invalid status code on return (%s)\n", argv[1]); + return (KORE_RESULT_ERROR); + } + + if (!http_redirect_add(current_domain, argv[0], status, NULL)) { + printf("invalid regex on return path\n"); + return (KORE_RESULT_ERROR); + } + + return (KORE_RESULT_OK); +} + +static int configure_redirect(char *options) { char *argv[4]; diff --git a/src/http.c b/src/http.c @@ -1500,7 +1500,11 @@ http_redirect_add(struct kore_domain *dom, const char *path, int status, } rdr->status = status; - rdr->target = kore_strdup(target); + + if (target != NULL) + rdr->target = kore_strdup(target); + else + rdr->target = NULL; TAILQ_INSERT_TAIL(&dom->redirects, rdr, list); @@ -1525,34 +1529,42 @@ http_check_redirect(struct http_request *req, struct kore_domain *dom) if (rdr == NULL) return (KORE_RESULT_ERROR); + uri = NULL; kore_buf_init(&location, 128); - kore_buf_appendf(&location, "%s", rdr->target); - if (req->query_string != NULL) { - kore_buf_replace_string(&location, "$qs", - req->query_string, strlen(req->query_string)); - } + if (rdr->target) { + kore_buf_appendf(&location, "%s", rdr->target); - /* Starts at 1 to skip the full path. */ - for (idx = 1; idx < HTTP_CAPTURE_GROUPS - 1; idx++) { - if (req->cgroups[idx].rm_so == -1 || - req->cgroups[idx].rm_eo == -1) - break; + if (req->query_string != NULL) { + kore_buf_replace_string(&location, "$qs", + req->query_string, strlen(req->query_string)); + } + + /* Starts at 1 to skip the full path. */ + for (idx = 1; idx < HTTP_CAPTURE_GROUPS - 1; idx++) { + if (req->cgroups[idx].rm_so == -1 || + req->cgroups[idx].rm_eo == -1) + break; + + (void)snprintf(key, sizeof(key), "$%d", idx); - (void)snprintf(key, sizeof(key), "$%d", idx); + kore_buf_replace_string(&location, key, + req->path + req->cgroups[idx].rm_so, + req->cgroups[idx].rm_eo - req->cgroups[idx].rm_so); + } - kore_buf_replace_string(&location, key, - req->path + req->cgroups[idx].rm_so, - req->cgroups[idx].rm_eo - req->cgroups[idx].rm_so); + uri = kore_buf_stringify(&location, NULL); } - uri = kore_buf_stringify(&location, NULL); + if (uri) + http_response_header(req, "location", uri); - http_response_header(req, "location", uri); http_response(req, rdr->status, NULL, 0); - kore_buf_cleanup(&location); + if (dom->accesslog) + kore_accesslog(req); + return (KORE_RESULT_OK); }