diff options
-rw-r--r-- | docs/changes.xml | 6 | ||||
-rw-r--r-- | src/nxt_conf_validation.c | 4 | ||||
-rw-r--r-- | src/nxt_http.h | 6 | ||||
-rw-r--r-- | src/nxt_http_route.c | 41 | ||||
-rw-r--r-- | src/nxt_http_static.c | 39 |
5 files changed, 79 insertions, 17 deletions
diff --git a/docs/changes.xml b/docs/changes.xml index 0858c2da..3d4fc698 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -33,6 +33,12 @@ NGINX Unit updated to 1.24.0. <change type="feature"> <para> +ability to limit serving of static files by MIME types. +</para> +</change> + +<change type="feature"> +<para> support for chrooting, rejecting symlinks, and rejecting crossing mounting points on a per-request basis during static file serving. </para> diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index ac1a81d8..1f654e53 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -457,6 +457,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_share_action_members[] = { .name = nxt_string("share"), .type = NXT_CONF_VLDT_STRING, }, { + .name = nxt_string("types"), + .type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_ARRAY, + .validator = nxt_conf_vldt_match_patterns, + }, { .name = nxt_string("fallback"), .type = NXT_CONF_VLDT_OBJECT, .validator = nxt_conf_vldt_action, diff --git a/src/nxt_http.h b/src/nxt_http.h index da1124a8..f82d837e 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -197,7 +197,8 @@ struct nxt_http_request_s { }; -typedef struct nxt_http_route_s nxt_http_route_t; +typedef struct nxt_http_route_s nxt_http_route_t; +typedef struct nxt_http_route_rule_s nxt_http_route_rule_t; struct nxt_http_action_s { @@ -219,6 +220,7 @@ struct nxt_http_action_s { struct { nxt_str_t chroot; nxt_uint_t resolve; + nxt_http_route_rule_t *types; nxt_http_action_t *fallback; } share; } u; @@ -306,6 +308,8 @@ nxt_int_t nxt_http_pass_segments(nxt_mp_t *mp, nxt_str_t *pass, nxt_str_t *segments, nxt_uint_t n); nxt_http_action_t *nxt_http_pass_application(nxt_task_t *task, nxt_router_conf_t *rtcf, nxt_str_t *name); +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); nxt_int_t nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *conf); diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index bfe5ce5f..15b85544 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -55,6 +55,7 @@ typedef struct { 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; @@ -115,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; @@ -131,7 +132,7 @@ typedef struct { } u; nxt_http_route_pattern_t pattern[0]; -} nxt_http_route_rule_t; +}; typedef struct { @@ -198,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); @@ -277,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, @@ -460,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; @@ -476,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; } @@ -655,6 +655,11 @@ static nxt_conf_map_t nxt_http_route_action_conf[] = { 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"), NXT_CONF_MAP_PTR, offsetof(nxt_http_route_action_conf_t, fallback) @@ -663,8 +668,8 @@ 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; @@ -676,6 +681,7 @@ nxt_http_route_action_create(nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv, 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)); @@ -781,6 +787,17 @@ nxt_http_route_action_create(nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv, } #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; + } + if (accf.fallback != NULL) { action->u.share.fallback = nxt_mp_alloc(mp, sizeof(nxt_http_action_t)); @@ -788,7 +805,7 @@ nxt_http_route_action_create(nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv, return NXT_ERROR; } - return nxt_http_route_action_create(tmcf, accf.fallback, + return nxt_http_route_action_create(task, tmcf, accf.fallback, action->u.share.fallback); } @@ -2495,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) { diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index e603819b..c961bb97 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -75,6 +75,37 @@ nxt_http_static_handler(nxt_task_t *task, nxt_http_request_t *r, f = NULL; + rtcf = r->conf->socket_conf->router_conf; + + mtype = NULL; + + if (action->u.share.types != NULL && extension.start == NULL) { + nxt_http_static_extract_extension(r->path, &extension); + mtype = nxt_http_static_mtypes_hash_find(&rtcf->mtypes_hash, + &extension); + + if (mtype != NULL) { + ret = nxt_http_route_test_rule(r, action->u.share.types, + mtype->start, mtype->length); + if (ret == 1) { + goto mime_ok; + } + + if (nxt_slow_path(ret == NXT_ERROR)) { + goto fail; + } + } + + if (action->u.share.fallback != NULL) { + return action->u.share.fallback; + } + + nxt_http_request_error(task, r, NXT_HTTP_FORBIDDEN); + return NULL; + } + +mime_ok: + length = action->name.length + r->path->length + index.length; fname = nxt_mp_nget(r->mem_pool, length + 1); @@ -262,10 +293,10 @@ nxt_http_static_handler(nxt_task_t *task, nxt_http_request_t *r, nxt_http_static_extract_extension(r->path, &extension); } - rtcf = r->conf->socket_conf->router_conf; - - mtype = nxt_http_static_mtypes_hash_find(&rtcf->mtypes_hash, - &extension); + if (mtype == NULL) { + mtype = nxt_http_static_mtypes_hash_find(&rtcf->mtypes_hash, + &extension); + } if (mtype != NULL) { field = nxt_list_zero_add(r->resp.fields); |