summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorZhidao HONG <z.hong@f5.com>2024-08-16 00:29:16 +0800
committerZhidao HONG <z.hong@f5.com>2024-08-20 09:17:24 +0800
commitdebd61c3a4f7e5817bf842c2166217929ef80c88 (patch)
tree037909415bcd46a43a73ab89ca698ab74687243d /src
parent57f939569d3c3db11d8bbc7dd0b45693cbe3344e (diff)
downloadunit-debd61c3a4f7e5817bf842c2166217929ef80c88.tar.gz
unit-debd61c3a4f7e5817bf842c2166217929ef80c88.tar.bz2
http: Add "if" option to the "match" object
This feature allows users to specify conditions to check if one route is matched. It is used the same way as the "if" option in the access log. Example: { "match": { "if": "`${headers['User-Agent'].split('/')[0] == 'curl'}`" }, "action": { "return": 204 } }
Diffstat (limited to 'src')
-rw-r--r--src/nxt_conf_validation.c4
-rw-r--r--src/nxt_http_route.c46
2 files changed, 46 insertions, 4 deletions
diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c
index 8f31bd18..5d7f7c52 100644
--- a/src/nxt_conf_validation.c
+++ b/src/nxt_conf_validation.c
@@ -696,6 +696,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_match_members[] = {
.type = NXT_CONF_VLDT_OBJECT | NXT_CONF_VLDT_ARRAY,
.validator = nxt_conf_vldt_match_patterns_sets,
.u.string = "cookies"
+ }, {
+ .name = nxt_string("if"),
+ .type = NXT_CONF_VLDT_STRING,
+ .validator = nxt_conf_vldt_if,
},
NXT_CONF_VLDT_END
diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c
index a82518a4..bd0646f3 100644
--- a/src/nxt_http_route.c
+++ b/src/nxt_http_route.c
@@ -51,6 +51,7 @@ typedef struct {
nxt_conf_value_t *query;
nxt_conf_value_t *source;
nxt_conf_value_t *destination;
+ nxt_conf_value_t *condition;
} nxt_http_route_match_conf_t;
@@ -138,6 +139,7 @@ typedef union {
typedef struct {
uint32_t items;
+ nxt_tstr_cond_t condition;
nxt_http_action_t action;
nxt_http_route_test_t test[];
} nxt_http_route_match_t;
@@ -350,6 +352,12 @@ static nxt_conf_map_t nxt_http_route_match_conf[] = {
NXT_CONF_MAP_PTR,
offsetof(nxt_http_route_match_conf_t, destination),
},
+
+ {
+ nxt_string("if"),
+ NXT_CONF_MAP_PTR,
+ offsetof(nxt_http_route_match_conf_t, condition),
+ },
};
@@ -397,7 +405,9 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
uint32_t n;
nxt_mp_t *mp;
nxt_int_t ret;
- nxt_conf_value_t *match_conf, *action_conf;
+ nxt_str_t str;
+ nxt_conf_value_t *match_conf, *action_conf, *condition;
+ nxt_router_conf_t *rtcf;
nxt_http_route_test_t *test;
nxt_http_route_rule_t *rule;
nxt_http_route_table_t *table;
@@ -405,6 +415,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_http_route_addr_rule_t *addr_rule;
nxt_http_route_match_conf_t mtcf;
+ static const nxt_str_t if_path = nxt_string("/if");
static const nxt_str_t match_path = nxt_string("/match");
static const nxt_str_t action_path = nxt_string("/action");
@@ -413,9 +424,21 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
n = (match_conf != NULL) ? nxt_conf_object_members_count(match_conf) : 0;
size = sizeof(nxt_http_route_match_t) + n * sizeof(nxt_http_route_test_t *);
- mp = tmcf->router_conf->mem_pool;
+ rtcf = tmcf->router_conf;
+ mp = rtcf->mem_pool;
+
+ condition = NULL;
+
+ if (match_conf != NULL) {
+ condition = nxt_conf_get_path(match_conf, &if_path);
+
+ if (condition != NULL) {
+ n--;
+ size -= sizeof(nxt_http_route_test_t *);
+ }
+ }
- match = nxt_mp_alloc(mp, size);
+ match = nxt_mp_zalloc(mp, size);
if (nxt_slow_path(match == NULL)) {
return NULL;
}
@@ -432,7 +455,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
return NULL;
}
- if (n == 0) {
+ if (n == 0 && condition == NULL) {
return match;
}
@@ -445,6 +468,15 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
return NULL;
}
+ if (condition != NULL) {
+ nxt_conf_get_string(condition, &str);
+
+ ret = nxt_tstr_cond_compile(rtcf->tstr_state, &str, &match->condition);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return NULL;
+ }
+ }
+
test = &match->test[0];
if (mtcf.scheme != NULL) {
@@ -1596,6 +1628,12 @@ nxt_http_route_match(nxt_task_t *task, nxt_http_request_t *r,
nxt_int_t ret;
nxt_http_route_test_t *test, *end;
+ ret = nxt_http_cond_value(task, r, &match->condition);
+ if (ret <= 0) {
+ /* 0 => NULL, -1 => NXT_HTTP_ACTION_ERROR. */
+ return (nxt_http_action_t *) (intptr_t) ret;
+ }
+
test = &match->test[0];
end = test + match->items;