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:
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));