summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOisin Canty <o.canty@f5.com>2021-05-06 14:22:21 +0000
committerOisin Canty <o.canty@f5.com>2021-05-06 14:22:21 +0000
commitb9d5eb285a2fca8b9b60d948acc679a5e16b3f94 (patch)
tree32dab8ccdef597e4daf50b3cffa74a3a2237607b
parente0a061955bba69aaf28022d405362c8a5e444ff6 (diff)
downloadunit-b9d5eb285a2fca8b9b60d948acc679a5e16b3f94.tar.gz
unit-b9d5eb285a2fca8b9b60d948acc679a5e16b3f94.tar.bz2
Static: implemented MIME filtering
-rw-r--r--docs/changes.xml6
-rw-r--r--src/nxt_conf_validation.c4
-rw-r--r--src/nxt_http.h6
-rw-r--r--src/nxt_http_route.c41
-rw-r--r--src/nxt_http_static.c39
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);