summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_http_route.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/nxt_http_route.c144
1 files changed, 115 insertions, 29 deletions
diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c
index 28545fc9..15b85544 100644
--- a/src/nxt_http_route.c
+++ b/src/nxt_http_route.c
@@ -50,8 +50,12 @@ typedef struct {
nxt_conf_value_t *pass;
nxt_conf_value_t *ret;
nxt_str_t location;
- nxt_conf_value_t *share;
nxt_conf_value_t *proxy;
+ nxt_conf_value_t *share;
+ nxt_str_t chroot;
+ nxt_conf_value_t *follow_symlinks;
+ nxt_conf_value_t *traverse_mounts;
+ nxt_conf_value_t *types;
nxt_conf_value_t *fallback;
} nxt_http_route_action_conf_t;
@@ -112,7 +116,7 @@ typedef struct {
} nxt_http_cookie_t;
-typedef struct {
+struct nxt_http_route_rule_s {
/* The object must be the first field. */
nxt_http_route_object_t object:8;
uint32_t items;
@@ -128,7 +132,7 @@ typedef struct {
} u;
nxt_http_route_pattern_t pattern[0];
-} nxt_http_route_rule_t;
+};
typedef struct {
@@ -195,8 +199,9 @@ static nxt_http_route_t *nxt_http_route_create(nxt_task_t *task,
nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
static nxt_http_route_match_t *nxt_http_route_match_create(nxt_task_t *task,
nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
-static nxt_int_t nxt_http_route_action_create(nxt_router_temp_conf_t *tmcf,
- nxt_conf_value_t *cv, nxt_http_action_t *action);
+static nxt_int_t nxt_http_route_action_create(nxt_task_t *task,
+ nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv,
+ nxt_http_action_t *action);
static nxt_http_route_table_t *nxt_http_route_table_create(nxt_task_t *task,
nxt_mp_t *mp, nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding);
@@ -274,8 +279,6 @@ static nxt_http_name_value_t *nxt_http_route_cookie(nxt_array_t *array,
u_char *name, size_t name_length, u_char *start, u_char *end);
static nxt_int_t nxt_http_route_test_cookie(nxt_http_request_t *r,
nxt_http_route_rule_t *rule, nxt_array_t *array);
-static nxt_int_t nxt_http_route_test_rule(nxt_http_request_t *r,
- nxt_http_route_rule_t *rule, u_char *start, size_t length);
static nxt_int_t nxt_http_route_pattern(nxt_http_request_t *r,
nxt_http_route_pattern_t *pattern, u_char *start, size_t length);
static nxt_int_t nxt_http_route_memcmp(u_char *start, u_char *test,
@@ -457,7 +460,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
match_conf = nxt_conf_get_path(cv, &match_path);
n = (match_conf != NULL) ? nxt_conf_object_members_count(match_conf) : 0;
- size = sizeof(nxt_http_route_match_t) + n * sizeof(nxt_http_route_rule_t *);
+ size = sizeof(nxt_http_route_match_t) + n * sizeof(nxt_http_route_test_t *);
mp = tmcf->router_conf->mem_pool;
@@ -473,7 +476,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
return NULL;
}
- ret = nxt_http_route_action_create(tmcf, action_conf, &match->action);
+ ret = nxt_http_route_action_create(task, tmcf, action_conf, &match->action);
if (nxt_slow_path(ret != NXT_OK)) {
return NULL;
}
@@ -627,14 +630,34 @@ static nxt_conf_map_t nxt_http_route_action_conf[] = {
offsetof(nxt_http_route_action_conf_t, location)
},
{
+ nxt_string("proxy"),
+ NXT_CONF_MAP_PTR,
+ offsetof(nxt_http_route_action_conf_t, proxy)
+ },
+ {
nxt_string("share"),
NXT_CONF_MAP_PTR,
offsetof(nxt_http_route_action_conf_t, share)
},
{
- nxt_string("proxy"),
+ nxt_string("chroot"),
+ NXT_CONF_MAP_STR,
+ offsetof(nxt_http_route_action_conf_t, chroot)
+ },
+ {
+ nxt_string("follow_symlinks"),
NXT_CONF_MAP_PTR,
- offsetof(nxt_http_route_action_conf_t, proxy)
+ offsetof(nxt_http_route_action_conf_t, follow_symlinks)
+ },
+ {
+ nxt_string("traverse_mounts"),
+ NXT_CONF_MAP_PTR,
+ offsetof(nxt_http_route_action_conf_t, traverse_mounts)
+ },
+ {
+ nxt_string("types"),
+ NXT_CONF_MAP_PTR,
+ offsetof(nxt_http_route_action_conf_t, types)
},
{
nxt_string("fallback"),
@@ -645,14 +668,20 @@ static nxt_conf_map_t nxt_http_route_action_conf[] = {
static nxt_int_t
-nxt_http_route_action_create(nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv,
- nxt_http_action_t *action)
+nxt_http_route_action_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
+ nxt_conf_value_t *cv, nxt_http_action_t *action)
{
+#if (NXT_HAVE_OPENAT2)
+ u_char *p;
+ uint8_t slash;
+ nxt_str_t *chroot;
+#endif
nxt_mp_t *mp;
nxt_int_t ret;
nxt_str_t name, *string;
nxt_uint_t encode;
nxt_conf_value_t *conf;
+ nxt_http_route_rule_t *rule;
nxt_http_route_action_conf_t accf;
nxt_memzero(&accf, sizeof(accf));
@@ -700,14 +729,14 @@ nxt_http_route_action_create(nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv,
return NXT_OK;
}
- conf = accf.pass;
-
if (accf.share != NULL) {
conf = accf.share;
- action->handler = nxt_http_static_handler;
} else if (accf.proxy != NULL) {
conf = accf.proxy;
+
+ } else {
+ conf = accf.pass;
}
nxt_conf_get_string(conf, &name);
@@ -717,14 +746,70 @@ nxt_http_route_action_create(nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv,
return NXT_ERROR;
}
- if (accf.fallback != NULL) {
- action->u.fallback = nxt_mp_alloc(mp, sizeof(nxt_http_action_t));
- if (nxt_slow_path(action->u.fallback == NULL)) {
- return NXT_ERROR;
+ if (accf.share != NULL) {
+ action->handler = nxt_http_static_handler;
+
+#if (NXT_HAVE_OPENAT2)
+ string = &accf.chroot;
+ chroot = &action->u.share.chroot;
+
+ if (string->length > 0) {
+ action->u.share.resolve |= RESOLVE_IN_ROOT;
+
+ slash = (string->start[string->length - 1] != '/');
+
+ chroot->length = string->length + (slash ? 1 : 0);
+
+ chroot->start = nxt_mp_alloc(mp, chroot->length + 1);
+ if (nxt_slow_path(chroot->start == NULL)) {
+ return NXT_ERROR;
+ }
+
+ p = nxt_cpymem(chroot->start, string->start, string->length);
+
+ if (slash) {
+ *p++ = '/';
+ }
+
+ *p = '\0';
+ }
+
+ if (accf.follow_symlinks != NULL
+ && !nxt_conf_get_boolean(accf.follow_symlinks))
+ {
+ action->u.share.resolve |= RESOLVE_NO_SYMLINKS;
+ }
+
+ if (accf.traverse_mounts != NULL
+ && !nxt_conf_get_boolean(accf.traverse_mounts))
+ {
+ action->u.share.resolve |= RESOLVE_NO_XDEV;
+ }
+#endif
+
+ if (accf.types != NULL) {
+ rule = nxt_http_route_rule_create(task, mp, accf.types, 0,
+ NXT_HTTP_ROUTE_PATTERN_LOWCASE,
+ NXT_HTTP_ROUTE_ENCODING_NONE);
+ if (nxt_slow_path(rule == NULL)) {
+ return NXT_ERROR;
+ }
+
+ action->u.share.types = rule;
}
- return nxt_http_route_action_create(tmcf, accf.fallback,
- action->u.fallback);
+ if (accf.fallback != NULL) {
+ action->u.share.fallback = nxt_mp_alloc(mp,
+ sizeof(nxt_http_action_t));
+ if (nxt_slow_path(action->u.share.fallback == NULL)) {
+ return NXT_ERROR;
+ }
+
+ return nxt_http_route_action_create(task, tmcf, accf.fallback,
+ action->u.share.fallback);
+ }
+
+ return NXT_OK;
}
if (accf.proxy != NULL) {
@@ -1411,9 +1496,10 @@ nxt_http_action_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
if (action->handler != NULL) {
if (action->handler == nxt_http_static_handler
- && action->u.fallback != NULL)
+ && action->u.share.fallback != NULL)
{
- return nxt_http_action_resolve(task, tmcf, action->u.fallback);
+ return nxt_http_action_resolve(task, tmcf,
+ action->u.share.fallback);
}
return NXT_OK;
@@ -1533,14 +1619,14 @@ nxt_http_pass_find(nxt_task_t *task, nxt_mp_t *mp, nxt_router_conf_t *rtcf,
}
if (segments[2].length != 0) {
- targets = action->u.application->targets;
+ targets = action->u.app.application->targets;
for (i = 0; !nxt_strstr_eq(&segments[2], &targets[i]); i++);
- action->target = i;
+ action->u.app.target = i;
} else {
- action->target = 0;
+ action->u.app.target = 0;
}
return NXT_OK;
@@ -1678,7 +1764,7 @@ nxt_http_pass_application(nxt_task_t *task, nxt_router_conf_t *rtcf,
(void) nxt_router_listener_application(rtcf, name, action);
- action->target = 0;
+ action->u.app.target = 0;
return action;
}
@@ -2426,7 +2512,7 @@ nxt_http_route_test_cookie(nxt_http_request_t *r,
}
-static nxt_int_t
+nxt_int_t
nxt_http_route_test_rule(nxt_http_request_t *r, nxt_http_route_rule_t *rule,
u_char *start, size_t length)
{