Skip to content

Commit

Permalink
http: Add "if" option to the "match" object
Browse files Browse the repository at this point in the history
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
        }
    }
  • Loading branch information
hongzhidao committed Aug 20, 2024
1 parent 57f9395 commit debd61c
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/nxt_conf_validation.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
46 changes: 42 additions & 4 deletions src/nxt_http_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;


Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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),
},
};


Expand Down Expand Up @@ -397,14 +405,17 @@ 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;
nxt_http_route_match_t *match;
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");

Expand All @@ -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;
}
Expand All @@ -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;
}

Expand All @@ -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) {
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit debd61c

Please sign in to comment.