Static: variables in the "chroot" option.
This commit is contained in:
@@ -31,6 +31,12 @@ NGINX Unit updated to 1.26.0.
|
|||||||
date="" time=""
|
date="" time=""
|
||||||
packager="Andrei Belov <defan@nginx.com>">
|
packager="Andrei Belov <defan@nginx.com>">
|
||||||
|
|
||||||
|
<change type="feature">
|
||||||
|
<para>
|
||||||
|
variables support in the "chroot" option.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
<change type="bugfix">
|
<change type="bugfix">
|
||||||
<para>
|
<para>
|
||||||
fixed building with glibc 2.34, notably Fedora 35.
|
fixed building with glibc 2.34, notably Fedora 35.
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ typedef enum {
|
|||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NXT_CONF_VLDT_REQUIRED = 1,
|
NXT_CONF_VLDT_REQUIRED = 1 << 0,
|
||||||
|
NXT_CONF_VLDT_VAR = 1 << 1,
|
||||||
} nxt_conf_vldt_flags_t;
|
} nxt_conf_vldt_flags_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -73,8 +74,8 @@ static nxt_int_t nxt_conf_vldt_type(nxt_conf_validation_t *vldt,
|
|||||||
nxt_str_t *name, nxt_conf_value_t *value, nxt_conf_vldt_type_t type);
|
nxt_str_t *name, nxt_conf_value_t *value, nxt_conf_vldt_type_t type);
|
||||||
static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt,
|
static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
static nxt_int_t nxt_conf_vldt_var(nxt_conf_validation_t *vldt,
|
static nxt_int_t nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name,
|
||||||
const char *option, nxt_str_t *value);
|
nxt_str_t *value);
|
||||||
nxt_inline nxt_int_t nxt_conf_vldt_unsupported(nxt_conf_validation_t *vldt,
|
nxt_inline nxt_int_t nxt_conf_vldt_unsupported(nxt_conf_validation_t *vldt,
|
||||||
nxt_conf_value_t *value, void *data);
|
nxt_conf_value_t *value, void *data);
|
||||||
|
|
||||||
@@ -354,6 +355,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = {
|
|||||||
.name = nxt_string("pass"),
|
.name = nxt_string("pass"),
|
||||||
.type = NXT_CONF_VLDT_STRING,
|
.type = NXT_CONF_VLDT_STRING,
|
||||||
.validator = nxt_conf_vldt_pass,
|
.validator = nxt_conf_vldt_pass,
|
||||||
|
.flags = NXT_CONF_VLDT_VAR,
|
||||||
}, {
|
}, {
|
||||||
.name = nxt_string("application"),
|
.name = nxt_string("application"),
|
||||||
.type = NXT_CONF_VLDT_STRING,
|
.type = NXT_CONF_VLDT_STRING,
|
||||||
@@ -607,6 +609,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_pass_action_members[] = {
|
|||||||
.name = nxt_string("pass"),
|
.name = nxt_string("pass"),
|
||||||
.type = NXT_CONF_VLDT_STRING,
|
.type = NXT_CONF_VLDT_STRING,
|
||||||
.validator = nxt_conf_vldt_pass,
|
.validator = nxt_conf_vldt_pass,
|
||||||
|
.flags = NXT_CONF_VLDT_VAR,
|
||||||
},
|
},
|
||||||
|
|
||||||
NXT_CONF_VLDT_END
|
NXT_CONF_VLDT_END
|
||||||
@@ -646,6 +649,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_share_action_members[] = {
|
|||||||
.validator = nxt_conf_vldt_unsupported,
|
.validator = nxt_conf_vldt_unsupported,
|
||||||
.u.string = "chroot",
|
.u.string = "chroot",
|
||||||
#endif
|
#endif
|
||||||
|
.flags = NXT_CONF_VLDT_VAR,
|
||||||
}, {
|
}, {
|
||||||
.name = nxt_string("follow_symlinks"),
|
.name = nxt_string("follow_symlinks"),
|
||||||
.type = NXT_CONF_VLDT_BOOLEAN,
|
.type = NXT_CONF_VLDT_BOOLEAN,
|
||||||
@@ -1163,7 +1167,6 @@ nxt_conf_validate(nxt_conf_validation_t *vldt)
|
|||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
|
|
||||||
ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_VLDT_OBJECT);
|
ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_VLDT_OBJECT);
|
||||||
|
|
||||||
if (ret != NXT_OK) {
|
if (ret != NXT_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1290,14 +1293,14 @@ nxt_conf_vldt_unsupported(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
|||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_conf_vldt_var(nxt_conf_validation_t *vldt, const char *option,
|
nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name,
|
||||||
nxt_str_t *value)
|
nxt_str_t *value)
|
||||||
{
|
{
|
||||||
u_char error[NXT_MAX_ERROR_STR];
|
u_char error[NXT_MAX_ERROR_STR];
|
||||||
|
|
||||||
if (nxt_var_test(value, error) != NXT_OK) {
|
if (nxt_var_test(value, error) != NXT_OK) {
|
||||||
return nxt_conf_vldt_error(vldt, "%s in the \"%s\" value.",
|
return nxt_conf_vldt_error(vldt, "%s in the \"%V\" value.",
|
||||||
error, option);
|
error, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NXT_OK;
|
return NXT_OK;
|
||||||
@@ -1488,10 +1491,6 @@ nxt_conf_vldt_pass(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
|||||||
|
|
||||||
nxt_conf_get_string(value, &pass);
|
nxt_conf_get_string(value, &pass);
|
||||||
|
|
||||||
if (nxt_is_var(&pass)) {
|
|
||||||
return nxt_conf_vldt_var(vldt, "pass", &pass);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nxt_http_pass_segments(vldt->pool, &pass, segments, 3);
|
ret = nxt_http_pass_segments(vldt->pool, &pass, segments, 3);
|
||||||
|
|
||||||
if (ret != NXT_OK) {
|
if (ret != NXT_OK) {
|
||||||
@@ -2280,7 +2279,7 @@ nxt_conf_vldt_object(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
|||||||
{
|
{
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
nxt_str_t name;
|
nxt_str_t name, var;
|
||||||
nxt_conf_value_t *member;
|
nxt_conf_value_t *member;
|
||||||
nxt_conf_vldt_object_t *vals;
|
nxt_conf_vldt_object_t *vals;
|
||||||
|
|
||||||
@@ -2337,8 +2336,22 @@ nxt_conf_vldt_object(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nxt_conf_vldt_type(vldt, &name, member, vals->type);
|
if (vals->flags & NXT_CONF_VLDT_VAR
|
||||||
|
&& nxt_conf_type(member) == NXT_CONF_STRING)
|
||||||
|
{
|
||||||
|
nxt_conf_get_string(member, &var);
|
||||||
|
|
||||||
|
if (nxt_is_var(&var)) {
|
||||||
|
ret = nxt_conf_vldt_var(vldt, &name, &var);
|
||||||
|
if (ret != NXT_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = nxt_conf_vldt_type(vldt, &name, member, vals->type);
|
||||||
if (ret != NXT_OK) {
|
if (ret != NXT_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -679,7 +679,7 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
|
|
||||||
nxt_conf_get_string(acf.pass, &pass);
|
nxt_conf_get_string(acf.pass, &pass);
|
||||||
|
|
||||||
action->u.var = nxt_var_compile(&pass, mp);
|
action->u.var = nxt_var_compile(&pass, mp, 0);
|
||||||
if (nxt_slow_path(action->u.var == NULL)) {
|
if (nxt_slow_path(action->u.var == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1603,7 +1603,7 @@ nxt_http_action_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
action->u.var = nxt_var_compile(pass, mp);
|
action->u.var = nxt_var_compile(pass, mp, 0);
|
||||||
if (nxt_slow_path(action->u.var == NULL)) {
|
if (nxt_slow_path(action->u.var == NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,19 +8,36 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nxt_str_t share;
|
nxt_str_t share;
|
||||||
nxt_str_t chroot;
|
#if (NXT_HAVE_OPENAT2)
|
||||||
nxt_uint_t resolve;
|
nxt_var_t *chroot;
|
||||||
nxt_http_route_rule_t *types;
|
nxt_uint_t resolve;
|
||||||
|
#endif
|
||||||
|
nxt_http_route_rule_t *types;
|
||||||
|
uint8_t is_const; /* 1 bit */
|
||||||
} nxt_http_static_conf_t;
|
} 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_COUNT 2
|
||||||
#define NXT_HTTP_STATIC_BUF_SIZE (128 * 1024)
|
#define NXT_HTTP_STATIC_BUF_SIZE (128 * 1024)
|
||||||
|
|
||||||
|
|
||||||
static nxt_http_action_t *nxt_http_static(nxt_task_t *task,
|
static nxt_http_action_t *nxt_http_static(nxt_task_t *task,
|
||||||
nxt_http_request_t *r, nxt_http_action_t *action);
|
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,
|
static void nxt_http_static_extract_extension(nxt_str_t *path,
|
||||||
nxt_str_t *exten);
|
nxt_str_t *exten);
|
||||||
static void nxt_http_static_body_handler(nxt_task_t *task, void *obj,
|
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;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conf->is_const = 1;
|
||||||
|
|
||||||
#if (NXT_HAVE_OPENAT2)
|
#if (NXT_HAVE_OPENAT2)
|
||||||
if (acf->chroot.length > 0) {
|
if (acf->chroot.length > 0) {
|
||||||
u_char *p;
|
if (nxt_is_var(&acf->chroot)) {
|
||||||
nxt_str_t slash;
|
conf->is_const = 0;
|
||||||
|
|
||||||
if (acf->chroot.start[acf->chroot.length - 1] != '/') {
|
|
||||||
nxt_str_set(&slash, "/");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
nxt_str_set(&slash, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value.length = acf->chroot.length + slash.length;
|
conf->chroot = nxt_var_compile(&acf->chroot, mp, 1);
|
||||||
|
if (nxt_slow_path(conf->chroot == NULL)) {
|
||||||
value.start = nxt_mp_alloc(mp, value.length + 1);
|
|
||||||
if (nxt_slow_path(value.start == NULL)) {
|
|
||||||
return NXT_ERROR;
|
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
|
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_static(nxt_task_t *task, nxt_http_request_t *r,
|
||||||
nxt_http_action_t *action)
|
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_int_t ret;
|
||||||
nxt_str_t index, exten, *mtype, *chroot;
|
|
||||||
nxt_uint_t level;
|
|
||||||
nxt_bool_t need_body;
|
nxt_bool_t need_body;
|
||||||
nxt_file_t *f, file;
|
nxt_http_static_ctx_t *ctx;
|
||||||
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_conf_t *conf;
|
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_slow_path(!nxt_str_eq(r->method, "GET", 3))) {
|
||||||
|
|
||||||
if (!nxt_str_eq(r->method, "HEAD", 4)) {
|
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;
|
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] == '/') {
|
if (r->path->start[r->path->length - 1] == '/') {
|
||||||
/* TODO: dynamic index setting. */
|
/* TODO: dynamic index setting. */
|
||||||
nxt_str_set(&index, "index.html");
|
nxt_str_set(&index, "index.html");
|
||||||
@@ -176,6 +249,7 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r,
|
|||||||
}
|
}
|
||||||
|
|
||||||
f = NULL;
|
f = NULL;
|
||||||
|
status = NXT_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
rtcf = r->conf->socket_conf->router_conf;
|
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 (ret == 0) {
|
||||||
if (action->fallback != NULL) {
|
status = NXT_HTTP_FORBIDDEN;
|
||||||
return action->fallback;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
nxt_http_request_error(task, r, NXT_HTTP_FORBIDDEN);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,18 +288,21 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r,
|
|||||||
|
|
||||||
file.name = fname;
|
file.name = fname;
|
||||||
|
|
||||||
chroot = &conf->chroot;
|
|
||||||
|
|
||||||
#if (NXT_HAVE_OPENAT2)
|
#if (NXT_HAVE_OPENAT2)
|
||||||
if (conf->resolve != 0) {
|
if (conf->resolve != 0 || ctx->chroot.length > 0) {
|
||||||
|
nxt_str_t *chr;
|
||||||
|
nxt_uint_t resolve;
|
||||||
|
|
||||||
if (chroot->length > 0) {
|
resolve = conf->resolve;
|
||||||
file.name = chroot->start;
|
chr = &ctx->chroot;
|
||||||
|
|
||||||
if (length > chroot->length
|
if (chr->length > 0) {
|
||||||
&& nxt_memcmp(fname, chroot->start, chroot->length) == 0)
|
resolve |= RESOLVE_IN_ROOT;
|
||||||
{
|
|
||||||
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,
|
ret = nxt_file_open(task, &file, NXT_FILE_SEARCH, NXT_FILE_OPEN,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
@@ -256,7 +329,7 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r,
|
|||||||
file.name = fname;
|
file.name = fname;
|
||||||
|
|
||||||
ret = nxt_file_openat2(task, &file, NXT_FILE_RDONLY,
|
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) {
|
if (af.fd != AT_FDCWD) {
|
||||||
nxt_file_close(task, &af);
|
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) {
|
if (level == NXT_LOG_ERR && action->fallback != NULL) {
|
||||||
return action->fallback;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != NXT_HTTP_NOT_FOUND) {
|
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",
|
nxt_log(task, level, "opening \"%s\" at \"%V\" failed %E",
|
||||||
fname, chroot, file.error);
|
fname, chr, file.error);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
nxt_log(task, level, "opening \"%s\" failed %E",
|
nxt_log(task, level, "opening \"%s\" failed %E",
|
||||||
fname, file.error);
|
fname, file.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
nxt_log(task, level, "opening \"%s\" failed %E", fname, file.error);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_http_request_error(task, r, status);
|
goto fail;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f = nxt_mp_get(r->mem_pool, sizeof(nxt_file_t));
|
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;
|
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);
|
fb = nxt_mp_zget(r->mem_pool, NXT_BUF_FILE_SIZE);
|
||||||
if (nxt_slow_path(fb == NULL)) {
|
if (nxt_slow_path(fb == NULL)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -421,20 +500,17 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r,
|
|||||||
} else {
|
} else {
|
||||||
/* Not a file. */
|
/* Not a file. */
|
||||||
|
|
||||||
nxt_file_close(task, f);
|
|
||||||
|
|
||||||
if (nxt_slow_path(!nxt_is_dir(&fi))) {
|
if (nxt_slow_path(!nxt_is_dir(&fi))) {
|
||||||
if (action->fallback != NULL) {
|
if (action->fallback == NULL) {
|
||||||
return action->fallback;
|
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",
|
status = NXT_HTTP_NOT_FOUND;
|
||||||
f->name);
|
goto fail;
|
||||||
|
|
||||||
nxt_http_request_error(task, r, NXT_HTTP_NOT_FOUND);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nxt_file_close(task, f);
|
||||||
f = NULL;
|
f = NULL;
|
||||||
|
|
||||||
r->status = NXT_HTTP_MOVED_PERMANENTLY;
|
r->status = NXT_HTTP_MOVED_PERMANENTLY;
|
||||||
@@ -482,20 +558,93 @@ nxt_http_static(nxt_task_t *task, nxt_http_request_t *r,
|
|||||||
nxt_http_request_header_send(task, r, body_handler, NULL);
|
nxt_http_request_header_send(task, r, body_handler, NULL);
|
||||||
|
|
||||||
r->state = &nxt_http_static_send_state;
|
r->state = &nxt_http_static_send_state;
|
||||||
return NULL;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
|
|
||||||
|
|
||||||
if (f != NULL) {
|
if (f != NULL) {
|
||||||
nxt_file_close(task, f);
|
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
|
static void
|
||||||
nxt_http_static_extract_extension(nxt_str_t *path, nxt_str_t *exten)
|
nxt_http_static_extract_extension(nxt_str_t *path, nxt_str_t *exten)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
struct nxt_var_s {
|
struct nxt_var_s {
|
||||||
size_t length;
|
size_t length;
|
||||||
nxt_uint_t vars;
|
nxt_uint_t vars;
|
||||||
|
uint8_t strz; /* 1 bit */
|
||||||
u_char data[];
|
u_char data[];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -229,7 +230,7 @@ nxt_var_index_init(void)
|
|||||||
|
|
||||||
|
|
||||||
nxt_var_t *
|
nxt_var_t *
|
||||||
nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp)
|
nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz)
|
||||||
{
|
{
|
||||||
u_char *p, *end, *next, *src;
|
u_char *p, *end, *next, *src;
|
||||||
size_t size;
|
size_t size;
|
||||||
@@ -258,19 +259,24 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp)
|
|||||||
|
|
||||||
size = sizeof(nxt_var_t) + n * sizeof(nxt_var_sub_t) + str->length;
|
size = sizeof(nxt_var_t) + n * sizeof(nxt_var_sub_t) + str->length;
|
||||||
|
|
||||||
var = nxt_mp_get(mp, size);
|
var = nxt_mp_get(mp, size + strz);
|
||||||
if (nxt_slow_path(var == NULL)) {
|
if (nxt_slow_path(var == NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
var->length = str->length;
|
var->length = str->length;
|
||||||
var->vars = n;
|
var->vars = n;
|
||||||
|
var->strz = strz;
|
||||||
|
|
||||||
subs = nxt_var_subs(var);
|
subs = nxt_var_subs(var);
|
||||||
src = nxt_var_raw_start(var);
|
src = nxt_var_raw_start(var);
|
||||||
|
|
||||||
nxt_memcpy(src, str->start, str->length);
|
nxt_memcpy(src, str->start, str->length);
|
||||||
|
|
||||||
|
if (strz) {
|
||||||
|
src[str->length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
p = str->start;
|
p = str->start;
|
||||||
|
|
||||||
@@ -585,7 +591,7 @@ nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query)
|
|||||||
length += str->length - subs[j].length;
|
length += str->length - subs[j].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = nxt_mp_nget(query->values.mem_pool, length);
|
p = nxt_mp_nget(query->values.mem_pool, length + var->strz);
|
||||||
if (nxt_slow_path(p == NULL)) {
|
if (nxt_slow_path(p == NULL)) {
|
||||||
query->failed = 1;
|
query->failed = 1;
|
||||||
goto done;
|
goto done;
|
||||||
@@ -612,10 +618,16 @@ nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (last != var->length) {
|
if (last != var->length) {
|
||||||
nxt_memcpy(p, &src[last], var->length - last);
|
p = nxt_cpymem(p, &src[last], var->length - last);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var->strz) {
|
||||||
|
*p = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_array_reset(&query->parts);
|
nxt_array_reset(&query->parts);
|
||||||
|
|
||||||
|
nxt_debug(task, "var: \"%*s\" -> \"%V\"", length, src, val[i].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ nxt_bool_t nxt_var_is_const(nxt_var_t *var);
|
|||||||
|
|
||||||
nxt_int_t nxt_var_register(nxt_var_decl_t *decl, size_t n);
|
nxt_int_t nxt_var_register(nxt_var_decl_t *decl, size_t n);
|
||||||
nxt_int_t nxt_var_index_init(void);
|
nxt_int_t nxt_var_index_init(void);
|
||||||
nxt_var_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp);
|
nxt_var_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz);
|
||||||
nxt_int_t nxt_var_test(nxt_str_t *str, u_char *error);
|
nxt_int_t nxt_var_test(nxt_str_t *str, u_char *error);
|
||||||
|
|
||||||
nxt_int_t nxt_var_query_init(nxt_var_query_t **query_p, void *ctx,
|
nxt_int_t nxt_var_query_init(nxt_var_query_t **query_p, void *ctx,
|
||||||
|
|||||||
Reference in New Issue
Block a user