kore

a fork of the worlds most advanced web framework
Log | Files | Refs | README | LICENSE

commit 0726a26c0cd1d51d1ae8c49a7eee95b7ca19d795
parent 993c5d2ac23adf6554ee34324a2e63977fc94fdf
Author: Joris Vink <joris@coders.se>
Date:   Tue, 17 Jul 2018 14:23:57 +0200

Allow restriction of methods for paths.

Now Kore will automatically send a 400 bad request in case the
method was not allowed on the path.

Diffstat:
Mconf/kore.conf.example | 4++++
Minclude/kore/http.h | 18+++++++++++-------
Minclude/kore/kore.h | 1+
Msrc/config.c | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/http.c | 5+++++
Msrc/module.c | 1+
6 files changed, 78 insertions(+), 7 deletions(-)

diff --git a/conf/kore.conf.example b/conf/kore.conf.example @@ -267,6 +267,10 @@ domain localhost { static /params-test serve_params_test static /private serve_private + # Restrict some URIs to certain methods + restrict /private post + restrict /validator post get head + # Page handlers with authentication. static /private/test serve_private_test auth_example diff --git a/include/kore/http.h b/include/kore/http.h @@ -188,13 +188,17 @@ struct http_file { TAILQ_ENTRY(http_file) list; }; -#define HTTP_METHOD_GET 0 -#define HTTP_METHOD_POST 1 -#define HTTP_METHOD_PUT 2 -#define HTTP_METHOD_DELETE 3 -#define HTTP_METHOD_HEAD 4 -#define HTTP_METHOD_OPTIONS 5 -#define HTTP_METHOD_PATCH 6 +#define HTTP_METHOD_GET 0x0001 +#define HTTP_METHOD_POST 0x0002 +#define HTTP_METHOD_PUT 0x0004 +#define HTTP_METHOD_DELETE 0x0010 +#define HTTP_METHOD_HEAD 0x0020 +#define HTTP_METHOD_OPTIONS 0x0040 +#define HTTP_METHOD_PATCH 0x0080 + +#define HTTP_METHOD_ALL (HTTP_METHOD_GET | HTTP_METHOD_POST | \ + HTTP_METHOD_PUT | HTTP_METHOD_DELETE | HTTP_METHOD_HEAD | \ + HTTP_METHOD_OPTIONS | HTTP_METHOD_PATCH) #define HTTP_REQUEST_COMPLETE 0x0001 #define HTTP_REQUEST_DELETE 0x0002 diff --git a/include/kore/kore.h b/include/kore/kore.h @@ -351,6 +351,7 @@ struct kore_module_handle { struct kore_runtime_call *rcall; #if !defined(KORE_NO_HTTP) struct kore_auth *auth; + int methods; TAILQ_HEAD(, kore_handler_params) params; #endif TAILQ_ENTRY(kore_module_handle) list; diff --git a/src/config.c b/src/config.c @@ -78,6 +78,7 @@ static int configure_client_verify_depth(char *); #if !defined(KORE_NO_HTTP) static int configure_filemap(char *); +static int configure_restrict(char *); static int configure_handler(int, char *); static int configure_static_handler(char *); static int configure_dynamic_handler(char *); @@ -160,6 +161,7 @@ static struct { { "static", configure_static_handler }, { "dynamic", configure_dynamic_handler }, { "accesslog", configure_accesslog }, + { "restrict", configure_restrict }, { "http_media_type", configure_http_media_type }, { "http_header_max", configure_http_header_max }, { "http_body_max", configure_http_body_max }, @@ -715,6 +717,60 @@ configure_accesslog(char *path) } static int +configure_restrict(char *options) +{ + struct kore_module_handle *hdlr; + int i, cnt; + char *argv[10]; + + if (current_domain == NULL) { + printf("restrict not used in domain context\n"); + return (KORE_RESULT_ERROR); + } + + cnt = kore_split_string(options, " ", argv, 10); + if (cnt < 2) { + printf("bad restrict option '%s', missing methods\n", options); + return (KORE_RESULT_ERROR); + } + + hdlr = NULL; + TAILQ_FOREACH(hdlr, &(current_domain->handlers), list) { + if (!strcmp(hdlr->path, argv[0])) + break; + } + + if (hdlr == NULL) { + printf("bad restrict option handler '%s' not found", argv[0]); + return (KORE_RESULT_ERROR); + } + + hdlr->methods = 0; + + for (i = 1; i < cnt; i++) { + if (!strcasecmp(argv[i], "post")) { + hdlr->methods |= HTTP_METHOD_POST; + } else if (!strcasecmp(argv[i], "get")) { + hdlr->methods |= HTTP_METHOD_GET; + } else if (!strcasecmp(argv[i], "put")) { + hdlr->methods |= HTTP_METHOD_PUT; + } else if (!strcasecmp(argv[i], "delete")) { + hdlr->methods |= HTTP_METHOD_DELETE; + } else if (!strcasecmp(argv[i], "head")) { + hdlr->methods |= HTTP_METHOD_HEAD; + } else if (!strcasecmp(argv[i], "patch")) { + hdlr->methods |= HTTP_METHOD_PATCH; + } else { + printf("unknown method: %s in restrict for %s\n", + argv[i], argv[0]); + return (KORE_RESULT_ERROR); + } + } + + return (KORE_RESULT_OK); +} + +static int configure_filemap_ext(char *ext) { kore_free(kore_filemap_ext); diff --git a/src/http.c b/src/http.c @@ -1372,6 +1372,11 @@ http_request_new(struct connection *c, const char *host, return (NULL); } + if (!(hdlr->methods & m)) { + http_error_response(c, 400); + return (NULL); + } + req = kore_pool_get(&http_request_pool); req->end = 0; req->total = 0; diff --git a/src/module.c b/src/module.c @@ -235,6 +235,7 @@ kore_module_handler_new(const char *path, const char *domain, hdlr->type = type; hdlr->path = kore_strdup(path); hdlr->func = kore_strdup(func); + hdlr->methods = HTTP_METHOD_ALL; TAILQ_INIT(&(hdlr->params));