From 37144d68499217d086c26a2030e6e9f6f7342152 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Tue, 28 Sep 2021 23:08:26 +0800 Subject: Static: variables in the "chroot" option. --- src/nxt_http_static.c | 299 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 224 insertions(+), 75 deletions(-) (limited to 'src/nxt_http_static.c') diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index 9b79a666..263ec9db 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -8,19 +8,36 @@ typedef struct { - nxt_str_t share; - nxt_str_t chroot; - nxt_uint_t resolve; - nxt_http_route_rule_t *types; + nxt_str_t share; +#if (NXT_HAVE_OPENAT2) + nxt_var_t *chroot; + nxt_uint_t resolve; +#endif + nxt_http_route_rule_t *types; + uint8_t is_const; /* 1 bit */ } nxt_http_static_conf_t; +typedef struct { + nxt_http_action_t *action; +#if (NXT_HAVE_OPENAT2) + nxt_str_t chroot; +#endif + uint8_t need_body; /* 1 bit */ +} nxt_http_static_ctx_t; + + #define NXT_HTTP_STATIC_BUF_COUNT 2 #define NXT_HTTP_STATIC_BUF_SIZE (128 * 1024) static nxt_http_action_t *nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action); +static void nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data); +static void nxt_http_static_var_error(nxt_task_t *task, void *obj, void *data); +#if (NXT_HAVE_OPENAT2) +static u_char *nxt_http_static_chroot_match(u_char *chr, u_char *shr); +#endif static void nxt_http_static_extract_extension(nxt_str_t *path, nxt_str_t *exten); static void nxt_http_static_body_handler(nxt_task_t *task, void *obj, @@ -62,32 +79,18 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, return NXT_ERROR; } + conf->is_const = 1; + #if (NXT_HAVE_OPENAT2) if (acf->chroot.length > 0) { - u_char *p; - nxt_str_t slash; - - if (acf->chroot.start[acf->chroot.length - 1] != '/') { - nxt_str_set(&slash, "/"); - - } else { - nxt_str_set(&slash, ""); + if (nxt_is_var(&acf->chroot)) { + conf->is_const = 0; } - value.length = acf->chroot.length + slash.length; - - value.start = nxt_mp_alloc(mp, value.length + 1); - if (nxt_slow_path(value.start == NULL)) { + conf->chroot = nxt_var_compile(&acf->chroot, mp, 1); + if (nxt_slow_path(conf->chroot == NULL)) { return NXT_ERROR; } - - p = value.start; - p = nxt_cpymem(p, acf->chroot.start, acf->chroot.length); - p = nxt_cpymem(p, slash.start, slash.length); - *p = '\0'; - - conf->chroot = value; - conf->resolve |= RESOLVE_IN_ROOT; } if (acf->follow_symlinks != NULL @@ -128,26 +131,11 @@ static nxt_http_action_t * nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action) { - size_t length, encode; - u_char *p, *fname; - struct tm tm; - nxt_buf_t *fb; nxt_int_t ret; - nxt_str_t index, exten, *mtype, *chroot; - nxt_uint_t level; nxt_bool_t need_body; - nxt_file_t *f, file; - nxt_file_info_t fi; - nxt_http_field_t *field; - nxt_http_status_t status; - nxt_router_conf_t *rtcf; - nxt_work_handler_t body_handler; + nxt_http_static_ctx_t *ctx; nxt_http_static_conf_t *conf; - conf = action->u.conf; - - nxt_debug(task, "http static: \"%V\"", &conf->share); - if (nxt_slow_path(!nxt_str_eq(r->method, "GET", 3))) { if (!nxt_str_eq(r->method, "HEAD", 4)) { @@ -165,6 +153,91 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, need_body = 1; } + conf = action->u.conf; + +#if (NXT_DEBUG && NXT_HAVE_OPENAT2) + nxt_str_t chr; + + if (conf->chroot != NULL) { + nxt_var_raw(conf->chroot, &chr); + + } else { + nxt_str_set(&chr, ""); + } + + nxt_debug(task, "http static: \"%V\" (chroot: \"%V\")", &conf->share, &chr); + +#else + nxt_debug(task, "http static: \"%V\"", &conf->share); +#endif + + ctx = nxt_mp_zget(r->mem_pool, sizeof(nxt_http_static_ctx_t)); + if (nxt_slow_path(ctx == NULL)) { + goto fail; + } + + ctx->action = action; + ctx->need_body = need_body; + + if (conf->is_const) { +#if (NXT_HAVE_OPENAT2) + if (conf->chroot != NULL) { + nxt_var_raw(conf->chroot, &ctx->chroot); + } +#endif + + nxt_http_static_send_ready(task, r, ctx); + + } else { + ret = nxt_var_query_init(&r->var_query, r, r->mem_pool); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + +#if (NXT_HAVE_OPENAT2) + nxt_var_query(task, r->var_query, conf->chroot, &ctx->chroot); +#endif + + nxt_var_query_resolve(task, r->var_query, ctx, + nxt_http_static_send_ready, + nxt_http_static_var_error); + } + + return NULL; + +fail: + + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); + return NULL; +} + + +static void +nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) +{ + size_t length, encode; + u_char *p, *fname; + struct tm tm; + nxt_buf_t *fb; + nxt_int_t ret; + nxt_str_t index, exten, *mtype; + nxt_uint_t level; + nxt_file_t *f, file; + nxt_file_info_t fi; + nxt_http_field_t *field; + nxt_http_status_t status; + nxt_router_conf_t *rtcf; + nxt_http_action_t *action; + nxt_http_request_t *r; + nxt_work_handler_t body_handler; + nxt_http_static_ctx_t *ctx; + nxt_http_static_conf_t *conf; + + r = obj; + ctx = data; + action = ctx->action; + conf = action->u.conf; + if (r->path->start[r->path->length - 1] == '/') { /* TODO: dynamic index setting. */ nxt_str_set(&index, "index.html"); @@ -176,6 +249,7 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, } f = NULL; + status = NXT_HTTP_INTERNAL_SERVER_ERROR; rtcf = r->conf->socket_conf->router_conf; @@ -192,12 +266,8 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, } if (ret == 0) { - if (action->fallback != NULL) { - return action->fallback; - } - - nxt_http_request_error(task, r, NXT_HTTP_FORBIDDEN); - return NULL; + status = NXT_HTTP_FORBIDDEN; + goto fail; } } @@ -218,18 +288,21 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, file.name = fname; - chroot = &conf->chroot; - #if (NXT_HAVE_OPENAT2) - if (conf->resolve != 0) { + if (conf->resolve != 0 || ctx->chroot.length > 0) { + nxt_str_t *chr; + nxt_uint_t resolve; + + resolve = conf->resolve; + chr = &ctx->chroot; - if (chroot->length > 0) { - file.name = chroot->start; + if (chr->length > 0) { + resolve |= RESOLVE_IN_ROOT; - if (length > chroot->length - && nxt_memcmp(fname, chroot->start, chroot->length) == 0) - { - fname += chroot->length; + fname = nxt_http_static_chroot_match(chr->start, file.name); + + if (fname != NULL) { + file.name = chr->start; ret = nxt_file_open(task, &file, NXT_FILE_SEARCH, NXT_FILE_OPEN, 0); @@ -256,7 +329,7 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, file.name = fname; ret = nxt_file_openat2(task, &file, NXT_FILE_RDONLY, - NXT_FILE_OPEN, 0, af.fd, conf->resolve); + NXT_FILE_OPEN, 0, af.fd, resolve); if (af.fd != AT_FDCWD) { nxt_file_close(task, &af); @@ -309,22 +382,28 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, } if (level == NXT_LOG_ERR && action->fallback != NULL) { - return action->fallback; + goto fail; } if (status != NXT_HTTP_NOT_FOUND) { - if (chroot->length > 0) { +#if (NXT_HAVE_OPENAT2) + nxt_str_t *chr = &ctx->chroot; + + if (chr->length > 0) { nxt_log(task, level, "opening \"%s\" at \"%V\" failed %E", - fname, chroot, file.error); + fname, chr, file.error); } else { nxt_log(task, level, "opening \"%s\" failed %E", fname, file.error); } + +#else + nxt_log(task, level, "opening \"%s\" failed %E", fname, file.error); +#endif } - nxt_http_request_error(task, r, status); - return NULL; + goto fail; } f = nxt_mp_get(r->mem_pool, sizeof(nxt_file_t)); @@ -400,7 +479,7 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, field->value_length = mtype->length; } - if (need_body && nxt_file_size(&fi) > 0) { + if (ctx->need_body && nxt_file_size(&fi) > 0) { fb = nxt_mp_zget(r->mem_pool, NXT_BUF_FILE_SIZE); if (nxt_slow_path(fb == NULL)) { goto fail; @@ -421,20 +500,17 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, } else { /* Not a file. */ - nxt_file_close(task, f); - if (nxt_slow_path(!nxt_is_dir(&fi))) { - if (action->fallback != NULL) { - return action->fallback; + if (action->fallback == NULL) { + nxt_log(task, NXT_LOG_ERR, "\"%FN\" is not a regular file", + f->name); } - nxt_log(task, NXT_LOG_ERR, "\"%FN\" is not a regular file", - f->name); - - nxt_http_request_error(task, r, NXT_HTTP_NOT_FOUND); - return NULL; + status = NXT_HTTP_NOT_FOUND; + goto fail; } + nxt_file_close(task, f); f = NULL; r->status = NXT_HTTP_MOVED_PERMANENTLY; @@ -482,19 +558,92 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, nxt_http_request_header_send(task, r, body_handler, NULL); r->state = &nxt_http_static_send_state; - return NULL; + return; fail: - nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); - if (f != NULL) { nxt_file_close(task, f); } - return NULL; + if (status != NXT_HTTP_INTERNAL_SERVER_ERROR + && action->fallback != NULL) + { + nxt_http_request_action(task, r, action->fallback); + return; + } + + nxt_http_request_error(task, r, status); +} + + +static void +nxt_http_static_var_error(nxt_task_t *task, void *obj, void *data) +{ + nxt_http_request_t *r; + + r = obj; + + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); +} + + +#if (NXT_HAVE_OPENAT2) + +static u_char * +nxt_http_static_chroot_match(u_char *chr, u_char *shr) +{ + if (*chr != *shr) { + return NULL; + } + + chr++; + shr++; + + for ( ;; ) { + if (*shr == '\0') { + return NULL; + } + + if (*chr == *shr) { + chr++; + shr++; + continue; + } + + if (*chr == '\0') { + break; + } + + if (*chr == '/') { + if (chr[-1] == '/') { + chr++; + continue; + } + + } else if (*shr == '/') { + if (shr[-1] == '/') { + shr++; + continue; + } + } + + return NULL; + } + + if (shr[-1] != '/' && *shr != '/') { + return NULL; + } + + while (*shr == '/') { + shr++; + } + + return (*shr != '\0') ? shr : NULL; } +#endif + static void nxt_http_static_extract_extension(nxt_str_t *path, nxt_str_t *exten) -- cgit From c5220944d2acdb912c129fc82ac8a83d24e9845d Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 30 Sep 2021 22:17:28 +0800 Subject: Static: variables in the "share" option. This commit supports variable in the "share" option, the finding path to file serve is the value from "share". An example: { "share": "/www/data/static$uri" } --- src/nxt_http_static.c | 120 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 47 deletions(-) (limited to 'src/nxt_http_static.c') diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index 263ec9db..c610bbf7 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -8,10 +8,11 @@ typedef struct { - nxt_str_t share; + nxt_var_t *share; #if (NXT_HAVE_OPENAT2) nxt_var_t *chroot; nxt_uint_t resolve; + u_char *fname; #endif nxt_http_route_rule_t *types; uint8_t is_const; /* 1 bit */ @@ -20,6 +21,7 @@ typedef struct { typedef struct { nxt_http_action_t *action; + nxt_str_t share; #if (NXT_HAVE_OPENAT2) nxt_str_t chroot; #endif @@ -59,7 +61,7 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_http_action_t *action, nxt_http_action_conf_t *acf) { nxt_mp_t *mp; - nxt_str_t *str, value; + nxt_str_t str; nxt_http_static_conf_t *conf; mp = tmcf->router_conf->mem_pool; @@ -72,17 +74,19 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, action->handler = nxt_http_static; action->u.conf = conf; - nxt_conf_get_string(acf->share, &value); + nxt_conf_get_string(acf->share, &str); - str = nxt_str_dup(mp, &conf->share, &value); - if (nxt_slow_path(str == NULL)) { + conf->share = nxt_var_compile(&str, mp, 1); + if (nxt_slow_path(conf->share == NULL)) { return NXT_ERROR; } - conf->is_const = 1; + conf->is_const = nxt_var_is_const(conf->share); #if (NXT_HAVE_OPENAT2) if (acf->chroot.length > 0) { + nxt_str_t chr, shr; + if (nxt_is_var(&acf->chroot)) { conf->is_const = 0; } @@ -91,6 +95,13 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, if (nxt_slow_path(conf->chroot == NULL)) { return NXT_ERROR; } + + if (conf->is_const) { + nxt_var_raw(conf->chroot, &chr); + nxt_var_raw(conf->share, &shr); + + conf->fname = nxt_http_static_chroot_match(chr.start, shr.start); + } } if (acf->follow_symlinks != NULL @@ -155,7 +166,12 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, conf = action->u.conf; -#if (NXT_DEBUG && NXT_HAVE_OPENAT2) +#if (NXT_DEBUG) + nxt_str_t shr; + + nxt_var_raw(conf->share, &shr); + +#if (NXT_HAVE_OPENAT2) nxt_str_t chr; if (conf->chroot != NULL) { @@ -165,11 +181,11 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, nxt_str_set(&chr, ""); } - nxt_debug(task, "http static: \"%V\" (chroot: \"%V\")", &conf->share, &chr); - + nxt_debug(task, "http static: \"%V\" (chroot: \"%V\")", &shr, &chr); #else - nxt_debug(task, "http static: \"%V\"", &conf->share); + nxt_debug(task, "http static: \"%V\"", &shr); #endif +#endif /* NXT_DEBUG */ ctx = nxt_mp_zget(r->mem_pool, sizeof(nxt_http_static_ctx_t)); if (nxt_slow_path(ctx == NULL)) { @@ -180,6 +196,8 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, ctx->need_body = need_body; if (conf->is_const) { + nxt_var_raw(conf->share, &ctx->share); + #if (NXT_HAVE_OPENAT2) if (conf->chroot != NULL) { nxt_var_raw(conf->chroot, &ctx->chroot); @@ -194,8 +212,12 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, goto fail; } + nxt_var_query(task, r->var_query, conf->share, &ctx->share); + #if (NXT_HAVE_OPENAT2) - nxt_var_query(task, r->var_query, conf->chroot, &ctx->chroot); + if (conf->chroot != NULL) { + nxt_var_query(task, r->var_query, conf->chroot, &ctx->chroot); + } #endif nxt_var_query_resolve(task, r->var_query, ctx, @@ -220,7 +242,7 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) struct tm tm; nxt_buf_t *fb; nxt_int_t ret; - nxt_str_t index, exten, *mtype; + nxt_str_t *shr, exten, *mtype; nxt_uint_t level; nxt_file_t *f, file; nxt_file_info_t fi; @@ -233,56 +255,58 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) nxt_http_static_ctx_t *ctx; nxt_http_static_conf_t *conf; + static nxt_str_t index = nxt_string("index.html"); + r = obj; ctx = data; action = ctx->action; conf = action->u.conf; - - if (r->path->start[r->path->length - 1] == '/') { - /* TODO: dynamic index setting. */ - nxt_str_set(&index, "index.html"); - nxt_str_set(&exten, ".html"); - - } else { - nxt_str_set(&index, ""); - nxt_str_null(&exten); - } + rtcf = r->conf->socket_conf->router_conf; f = NULL; + mtype = NULL; status = NXT_HTTP_INTERNAL_SERVER_ERROR; - rtcf = r->conf->socket_conf->router_conf; + shr = &ctx->share; - mtype = NULL; + if (shr->start[shr->length - 1] == '/') { + /* TODO: dynamic index setting. */ + nxt_str_set(&exten, ".html"); - if (conf->types != NULL && exten.start == NULL) { - nxt_http_static_extract_extension(r->path, &exten); - mtype = nxt_http_static_mtype_get(&rtcf->mtypes_hash, &exten); + length = shr->length + index.length; - ret = nxt_http_route_test_rule(r, conf->types, mtype->start, - mtype->length); - if (nxt_slow_path(ret == NXT_ERROR)) { + fname = nxt_mp_nget(r->mem_pool, length + 1); + if (nxt_slow_path(fname == NULL)) { goto fail; } - if (ret == 0) { - status = NXT_HTTP_FORBIDDEN; - goto fail; - } - } + p = fname; + p = nxt_cpymem(p, shr->start, shr->length); + p = nxt_cpymem(p, index.start, index.length); + *p = '\0'; - length = conf->share.length + r->path->length + index.length; + } else { + if (conf->types == NULL) { + nxt_str_null(&exten); - fname = nxt_mp_nget(r->mem_pool, length + 1); - if (nxt_slow_path(fname == NULL)) { - goto fail; - } + } else { + nxt_http_static_extract_extension(shr, &exten); + mtype = nxt_http_static_mtype_get(&rtcf->mtypes_hash, &exten); + + ret = nxt_http_route_test_rule(r, conf->types, mtype->start, + mtype->length); + if (nxt_slow_path(ret == NXT_ERROR)) { + goto fail; + } - p = fname; - p = nxt_cpymem(p, conf->share.start, conf->share.length); - p = nxt_cpymem(p, r->path->start, r->path->length); - p = nxt_cpymem(p, index.start, index.length); - *p = '\0'; + if (ret == 0) { + status = NXT_HTTP_FORBIDDEN; + goto fail; + } + } + + fname = ctx->share.start; + } nxt_memzero(&file, sizeof(nxt_file_t)); @@ -299,7 +323,9 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) if (chr->length > 0) { resolve |= RESOLVE_IN_ROOT; - fname = nxt_http_static_chroot_match(chr->start, file.name); + fname = conf->is_const + ? conf->fname + : nxt_http_static_chroot_match(chr->start, file.name); if (fname != NULL) { file.name = chr->start; @@ -460,7 +486,7 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) - p; if (exten.start == NULL) { - nxt_http_static_extract_extension(r->path, &exten); + nxt_http_static_extract_extension(shr, &exten); } if (mtype == NULL) { -- cgit From 95e653590927bfdb6919a8652ef62824cc6c9538 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Fri, 1 Oct 2021 10:03:55 +0800 Subject: Static: multiple paths in the "share" option. --- src/nxt_http_static.c | 217 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 147 insertions(+), 70 deletions(-) (limited to 'src/nxt_http_static.c') diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index c610bbf7..06e0cab2 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -8,14 +8,22 @@ typedef struct { - nxt_var_t *share; + nxt_var_t *var; +#if (NXT_HAVE_OPENAT2) + u_char *fname; +#endif + uint8_t is_const; /* 1 bit */ +} nxt_http_static_share_t; + + +typedef struct { + nxt_uint_t nshares; + nxt_http_static_share_t *shares; #if (NXT_HAVE_OPENAT2) nxt_var_t *chroot; nxt_uint_t resolve; - u_char *fname; #endif nxt_http_route_rule_t *types; - uint8_t is_const; /* 1 bit */ } nxt_http_static_conf_t; @@ -25,6 +33,7 @@ typedef struct { #if (NXT_HAVE_OPENAT2) nxt_str_t chroot; #endif + uint32_t index; uint8_t need_body; /* 1 bit */ } nxt_http_static_ctx_t; @@ -35,8 +44,12 @@ typedef struct { static nxt_http_action_t *nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action); +static void nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_static_ctx_t *ctx); static void nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data); static void nxt_http_static_var_error(nxt_task_t *task, void *obj, void *data); +static void nxt_http_static_next(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_static_ctx_t *ctx, nxt_http_status_t status); #if (NXT_HAVE_OPENAT2) static u_char *nxt_http_static_chroot_match(u_char *chr, u_char *shr); #endif @@ -60,8 +73,12 @@ nxt_int_t nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_http_action_t *action, nxt_http_action_conf_t *acf) { + uint32_t i; nxt_mp_t *mp; nxt_str_t str; + nxt_var_t *var; + nxt_bool_t array; + nxt_conf_value_t *cv; nxt_http_static_conf_t *conf; mp = tmcf->router_conf->mem_pool; @@ -74,33 +91,63 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, action->handler = nxt_http_static; action->u.conf = conf; - nxt_conf_get_string(acf->share, &str); + array = (nxt_conf_type(acf->share) == NXT_CONF_ARRAY); + conf->nshares = array ? nxt_conf_array_elements_count(acf->share) : 1; - conf->share = nxt_var_compile(&str, mp, 1); - if (nxt_slow_path(conf->share == NULL)) { + conf->shares = nxt_mp_zget(mp, sizeof(nxt_http_static_share_t) + * conf->nshares); + if (nxt_slow_path(conf->shares == NULL)) { return NXT_ERROR; } - conf->is_const = nxt_var_is_const(conf->share); + if (array) { + for (i = 0; i < conf->nshares; i++) { + cv = nxt_conf_get_array_element(acf->share, i); + nxt_conf_get_string(cv, &str); -#if (NXT_HAVE_OPENAT2) - if (acf->chroot.length > 0) { - nxt_str_t chr, shr; + var = nxt_var_compile(&str, mp, 1); + if (nxt_slow_path(var == NULL)) { + return NXT_ERROR; + } - if (nxt_is_var(&acf->chroot)) { - conf->is_const = 0; + conf->shares[i].var = var; + conf->shares[i].is_const = nxt_var_is_const(var); } + } else { + nxt_conf_get_string(acf->share, &str); + + var = nxt_var_compile(&str, mp, 1); + if (nxt_slow_path(var == NULL)) { + return NXT_ERROR; + } + + conf->shares[0].var = var; + conf->shares[0].is_const = nxt_var_is_const(var); + } + +#if (NXT_HAVE_OPENAT2) + if (acf->chroot.length > 0) { + nxt_str_t chr, shr; + nxt_bool_t is_const; + conf->chroot = nxt_var_compile(&acf->chroot, mp, 1); if (nxt_slow_path(conf->chroot == NULL)) { return NXT_ERROR; } - if (conf->is_const) { - nxt_var_raw(conf->chroot, &chr); - nxt_var_raw(conf->share, &shr); + is_const = nxt_var_is_const(conf->chroot); + + for (i = 0; i < conf->nshares; i++) { + conf->shares[i].is_const &= is_const; + + if (conf->shares[i].is_const) { + nxt_var_raw(conf->chroot, &chr); + nxt_var_raw(conf->shares[i].var, &shr); - conf->fname = nxt_http_static_chroot_match(chr.start, shr.start); + conf->shares[i].fname = nxt_http_static_chroot_match(chr.start, + shr.start); + } } } @@ -142,10 +189,8 @@ static nxt_http_action_t * nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action) { - nxt_int_t ret; - nxt_bool_t need_body; - nxt_http_static_ctx_t *ctx; - nxt_http_static_conf_t *conf; + nxt_bool_t need_body; + nxt_http_static_ctx_t *ctx; if (nxt_slow_path(!nxt_str_eq(r->method, "GET", 3))) { @@ -164,12 +209,37 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, need_body = 1; } - conf = action->u.conf; + ctx = nxt_mp_zget(r->mem_pool, sizeof(nxt_http_static_ctx_t)); + if (nxt_slow_path(ctx == NULL)) { + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); + return NULL; + } + + ctx->action = action; + ctx->need_body = need_body; + + nxt_http_static_iterate(task, r, ctx); + + return NULL; +} + + +static void +nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_static_ctx_t *ctx) +{ + nxt_int_t ret; + nxt_http_static_conf_t *conf; + nxt_http_static_share_t *share; + + conf = ctx->action->u.conf; + + share = &conf->shares[ctx->index]; #if (NXT_DEBUG) nxt_str_t shr; - nxt_var_raw(conf->share, &shr); + nxt_var_raw(share->var, &shr); #if (NXT_HAVE_OPENAT2) nxt_str_t chr; @@ -187,19 +257,11 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, #endif #endif /* NXT_DEBUG */ - ctx = nxt_mp_zget(r->mem_pool, sizeof(nxt_http_static_ctx_t)); - if (nxt_slow_path(ctx == NULL)) { - goto fail; - } - - ctx->action = action; - ctx->need_body = need_body; - - if (conf->is_const) { - nxt_var_raw(conf->share, &ctx->share); + if (share->is_const) { + nxt_var_raw(share->var, &ctx->share); #if (NXT_HAVE_OPENAT2) - if (conf->chroot != NULL) { + if (conf->chroot != NULL && ctx->index == 0) { nxt_var_raw(conf->chroot, &ctx->chroot); } #endif @@ -209,13 +271,14 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, } else { ret = nxt_var_query_init(&r->var_query, r, r->mem_pool); if (nxt_slow_path(ret != NXT_OK)) { - goto fail; + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); + return; } - nxt_var_query(task, r->var_query, conf->share, &ctx->share); + nxt_var_query(task, r->var_query, share->var, &ctx->share); #if (NXT_HAVE_OPENAT2) - if (conf->chroot != NULL) { + if (conf->chroot != NULL && ctx->index == 0) { nxt_var_query(task, r->var_query, conf->chroot, &ctx->chroot); } #endif @@ -223,14 +286,7 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r, nxt_var_query_resolve(task, r->var_query, ctx, nxt_http_static_send_ready, nxt_http_static_var_error); - } - - return NULL; - -fail: - - nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); - return NULL; + } } @@ -255,7 +311,7 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) nxt_http_static_ctx_t *ctx; nxt_http_static_conf_t *conf; - static nxt_str_t index = nxt_string("index.html"); + static const nxt_str_t index = nxt_string("index.html"); r = obj; ctx = data; @@ -300,8 +356,8 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) } if (ret == 0) { - status = NXT_HTTP_FORBIDDEN; - goto fail; + nxt_http_static_next(task, r, ctx, NXT_HTTP_FORBIDDEN); + return; } } @@ -314,8 +370,11 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) #if (NXT_HAVE_OPENAT2) if (conf->resolve != 0 || ctx->chroot.length > 0) { - nxt_str_t *chr; - nxt_uint_t resolve; + nxt_str_t *chr; + nxt_uint_t resolve; + nxt_http_static_share_t *share; + + share = &conf->shares[ctx->index]; resolve = conf->resolve; chr = &ctx->chroot; @@ -323,8 +382,8 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) if (chr->length > 0) { resolve |= RESOLVE_IN_ROOT; - fname = conf->is_const - ? conf->fname + fname = share->is_const + ? share->fname : nxt_http_static_chroot_match(chr->start, file.name); if (fname != NULL) { @@ -407,10 +466,6 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) break; } - if (level == NXT_LOG_ERR && action->fallback != NULL) { - goto fail; - } - if (status != NXT_HTTP_NOT_FOUND) { #if (NXT_HAVE_OPENAT2) nxt_str_t *chr = &ctx->chroot; @@ -429,6 +484,11 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) #endif } + if (level == NXT_LOG_ERR) { + nxt_http_static_next(task, r, ctx, status); + return; + } + goto fail; } @@ -525,18 +585,16 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) } else { /* Not a file. */ + nxt_file_close(task, f); if (nxt_slow_path(!nxt_is_dir(&fi))) { - if (action->fallback == NULL) { - nxt_log(task, NXT_LOG_ERR, "\"%FN\" is not a regular file", - f->name); - } + nxt_log(task, NXT_LOG_ERR, "\"%FN\" is not a regular file", + f->name); - status = NXT_HTTP_NOT_FOUND; - goto fail; + nxt_http_static_next(task, r, ctx, NXT_HTTP_NOT_FOUND); + return; } - nxt_file_close(task, f); f = NULL; r->status = NXT_HTTP_MOVED_PERMANENTLY; @@ -592,14 +650,7 @@ fail: nxt_file_close(task, f); } - if (status != NXT_HTTP_INTERNAL_SERVER_ERROR - && action->fallback != NULL) - { - nxt_http_request_action(task, r, action->fallback); - return; - } - - nxt_http_request_error(task, r, status); + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); } @@ -614,6 +665,32 @@ nxt_http_static_var_error(nxt_task_t *task, void *obj, void *data) } +static void +nxt_http_static_next(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_static_ctx_t *ctx, nxt_http_status_t status) +{ + nxt_http_action_t *action; + nxt_http_static_conf_t *conf; + + action = ctx->action; + conf = action->u.conf; + + ctx->index++; + + if (ctx->index < conf->nshares) { + nxt_http_static_iterate(task, r, ctx); + return; + } + + if (action->fallback != NULL) { + nxt_http_request_action(task, r, action->fallback); + return; + } + + nxt_http_request_error(task, r, status); +} + + #if (NXT_HAVE_OPENAT2) static u_char * -- cgit From 9baf22e7bf2fe66efd85f7a402f5e71c51d6d768 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Mon, 4 Oct 2021 15:33:04 +0300 Subject: Static: fixed possible descriptor leak introduced in a946d8cd7f8c. --- src/nxt_http_static.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nxt_http_static.c') diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index 06e0cab2..5380ff23 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -494,6 +494,7 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) f = nxt_mp_get(r->mem_pool, sizeof(nxt_file_t)); if (nxt_slow_path(f == NULL)) { + nxt_file_close(task, &file); goto fail; } -- cgit From 8db8330f8428ffe98e0129b8e4b9bba2042ad00e Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Mon, 4 Oct 2021 15:33:56 +0300 Subject: Static: removed surplus assignment. It's not needed after 69d823e5710a. Found by Clang Static Analyzer. --- src/nxt_http_static.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nxt_http_static.c') diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index 5380ff23..36c1ebc9 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -321,7 +321,6 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data) f = NULL; mtype = NULL; - status = NXT_HTTP_INTERNAL_SERVER_ERROR; shr = &ctx->share; -- cgit