From c03ebf7ffec285c040450a1882687d762c7b1b4f Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Fri, 14 Oct 2022 14:00:02 +0800 Subject: Configuration: stopped automatic migration to the "share" behavior. This commit removed the $uri auto-append for the "share" option introduced in rev be6409cdb028. The main reason is that it causes problems when preparing Unit configurations to be loaded at startup from the state directory. E.g. Docker. A valid conf.json file with $uri references will end up with $uri$uri due to the auto-append. --- src/nxt_conf_validation.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'src/nxt_conf_validation.c') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index fe6c22e5..f8242f6e 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -1690,11 +1690,6 @@ static nxt_int_t nxt_conf_vldt_share(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data) { - u_char *p; - nxt_str_t name, temp; - - static nxt_str_t uri = nxt_string("$uri"); - if (nxt_conf_type(value) == NXT_CONF_ARRAY) { if (nxt_conf_array_elements_count(value) == 0) { return nxt_conf_vldt_error(vldt, "The \"share\" array " @@ -1707,22 +1702,6 @@ nxt_conf_vldt_share(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, /* NXT_CONF_STRING */ - if (vldt->ver < 12600) { - nxt_conf_get_string(value, &name); - - temp.length = name.length + uri.length; - - temp.start = nxt_mp_get(vldt->conf_pool, temp.length); - if (nxt_slow_path(temp.start == NULL)) { - return NXT_ERROR; - } - - p = nxt_cpymem(temp.start, name.start, name.length); - nxt_memcpy(p, uri.start, uri.length); - - nxt_conf_set_string(value, &temp); - } - return nxt_conf_vldt_share_element(vldt, value); } -- cgit From ebf02266a2cd663ad4744d3b8c07e211b8f38da1 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 2 Nov 2022 21:45:40 +0100 Subject: Removed the unsafe nxt_memchr() wrapper for memchr(3). The casts are unnecessary, since memchr(3)'s argument is 'const void *'. It might have been necessary in the times of K&R, where 'void *' didn't exist. Nowadays, it's unnecessary, and _very_ unsafe, since casts can hide all classes of bugs by silencing most compiler warnings. The changes from nxt_memchr() to memchr(3) were scripted: $ find src/ -type f \ | grep '\.[ch]$' \ | xargs sed -i 's/nxt_memchr/memchr/' Reviewed-by: Andrew Clayton Signed-off-by: Alejandro Colomar --- src/nxt_conf_validation.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/nxt_conf_validation.c') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index f8242f6e..7fbe7e29 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -2710,12 +2710,12 @@ nxt_conf_vldt_environment(nxt_conf_validation_t *vldt, nxt_str_t *name, "The environment name must not be empty."); } - if (nxt_memchr(name->start, '\0', name->length) != NULL) { + if (memchr(name->start, '\0', name->length) != NULL) { return nxt_conf_vldt_error(vldt, "The environment name must not " "contain null character."); } - if (nxt_memchr(name->start, '=', name->length) != NULL) { + if (memchr(name->start, '=', name->length) != NULL) { return nxt_conf_vldt_error(vldt, "The environment name must not " "contain '=' character."); } @@ -2727,7 +2727,7 @@ nxt_conf_vldt_environment(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_get_string(value, &str); - if (nxt_memchr(str.start, '\0', str.length) != NULL) { + if (memchr(str.start, '\0', str.length) != NULL) { return nxt_conf_vldt_error(vldt, "The \"%V\" environment value must " "not contain null character.", name); } @@ -2926,7 +2926,7 @@ nxt_conf_vldt_argument(nxt_conf_validation_t *vldt, nxt_conf_value_t *value) nxt_conf_get_string(value, &str); - if (nxt_memchr(str.start, '\0', str.length) != NULL) { + if (memchr(str.start, '\0', str.length) != NULL) { return nxt_conf_vldt_error(vldt, "The \"arguments\" array must not " "contain strings with null character."); } @@ -2985,7 +2985,7 @@ nxt_conf_vldt_java_classpath(nxt_conf_validation_t *vldt, nxt_conf_get_string(value, &str); - if (nxt_memchr(str.start, '\0', str.length) != NULL) { + if (memchr(str.start, '\0', str.length) != NULL) { return nxt_conf_vldt_error(vldt, "The \"classpath\" array must not " "contain strings with null character."); } @@ -3006,7 +3006,7 @@ nxt_conf_vldt_java_option(nxt_conf_validation_t *vldt, nxt_conf_value_t *value) nxt_conf_get_string(value, &str); - if (nxt_memchr(str.start, '\0', str.length) != NULL) { + if (memchr(str.start, '\0', str.length) != NULL) { return nxt_conf_vldt_error(vldt, "The \"options\" array must not " "contain strings with null character."); } -- cgit From 4735931ace321752c387dae04c8b217ef22897ee Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Sun, 20 Nov 2022 23:15:01 +0800 Subject: Var: separating nxt_tstr_t from nxt_var_t. It's for the introduction of njs support. For each option that supports native variable and JS template literals introduced next, it's unified as template string. No functional changes. --- src/nxt_conf_validation.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nxt_conf_validation.c') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 7fbe7e29..09b3be55 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -1227,8 +1227,8 @@ nxt_conf_validate(nxt_conf_validation_t *vldt) { nxt_int_t ret; - vldt->var_fields = nxt_array_create(vldt->pool, 4, sizeof(nxt_var_field_t)); - if (nxt_slow_path(vldt->var_fields == NULL)) { + vldt->tstr_state = nxt_tstr_state_new(vldt->pool); + if (nxt_slow_path(vldt->tstr_state == NULL)) { return NXT_ERROR; } @@ -1364,7 +1364,7 @@ nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name, { u_char error[NXT_MAX_ERROR_STR]; - if (nxt_var_test(value, vldt->var_fields, error) != NXT_OK) { + if (nxt_tstr_test(vldt->tstr_state, value, error) != NXT_OK) { return nxt_conf_vldt_error(vldt, "%s in the \"%V\" value.", error, name); } -- cgit From 4d6d146e920667a8afeacd355e4fb6a94387066e Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Sun, 20 Nov 2022 23:16:51 +0800 Subject: Basic njs support. --- src/nxt_conf_validation.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'src/nxt_conf_validation.c') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 09b3be55..e650b44d 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -34,7 +34,7 @@ typedef enum { typedef enum { NXT_CONF_VLDT_REQUIRED = 1 << 0, - NXT_CONF_VLDT_VAR = 1 << 1, + NXT_CONF_VLDT_TSTR = 1 << 1, } nxt_conf_vldt_flags_t; @@ -367,7 +367,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = { .name = nxt_string("pass"), .type = NXT_CONF_VLDT_STRING, .validator = nxt_conf_vldt_pass, - .flags = NXT_CONF_VLDT_VAR, + .flags = NXT_CONF_VLDT_TSTR, }, { .name = nxt_string("application"), .type = NXT_CONF_VLDT_STRING, @@ -652,7 +652,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_pass_action_members[] = { .name = nxt_string("pass"), .type = NXT_CONF_VLDT_STRING, .validator = nxt_conf_vldt_pass, - .flags = NXT_CONF_VLDT_VAR, + .flags = NXT_CONF_VLDT_TSTR, }, NXT_CONF_VLDT_END @@ -667,7 +667,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_return_action_members[] = { }, { .name = nxt_string("location"), .type = NXT_CONF_VLDT_STRING, - .flags = NXT_CONF_VLDT_VAR, + .flags = NXT_CONF_VLDT_TSTR, }, NXT_CONF_VLDT_END @@ -697,7 +697,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_share_action_members[] = { .validator = nxt_conf_vldt_unsupported, .u.string = "chroot", #endif - .flags = NXT_CONF_VLDT_VAR, + .flags = NXT_CONF_VLDT_TSTR, }, { .name = nxt_string("follow_symlinks"), .type = NXT_CONF_VLDT_BOOLEAN, @@ -1226,8 +1226,9 @@ nxt_int_t nxt_conf_validate(nxt_conf_validation_t *vldt) { nxt_int_t ret; + u_char error[NXT_MAX_ERROR_STR]; - vldt->tstr_state = nxt_tstr_state_new(vldt->pool); + vldt->tstr_state = nxt_tstr_state_new(vldt->pool, 1); if (nxt_slow_path(vldt->tstr_state == NULL)) { return NXT_ERROR; } @@ -1237,7 +1238,17 @@ nxt_conf_validate(nxt_conf_validation_t *vldt) return ret; } - return nxt_conf_vldt_object(vldt, vldt->conf, nxt_conf_vldt_root_members); + ret = nxt_conf_vldt_object(vldt, vldt->conf, nxt_conf_vldt_root_members); + if (ret != NXT_OK) { + return ret; + } + + ret = nxt_tstr_state_done(vldt->tstr_state, error); + if (ret != NXT_OK) { + return nxt_conf_vldt_error(vldt, "%s", error); + } + + return NXT_OK; } @@ -1721,7 +1732,7 @@ nxt_conf_vldt_share_element(nxt_conf_validation_t *vldt, nxt_conf_get_string(value, &str); - if (nxt_is_var(&str)) { + if (nxt_is_tstr(&str)) { return nxt_conf_vldt_var(vldt, &share, &str); } @@ -2501,12 +2512,12 @@ nxt_conf_vldt_object(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, continue; } - if (vals->flags & NXT_CONF_VLDT_VAR + if (vals->flags & NXT_CONF_VLDT_TSTR && nxt_conf_type(member) == NXT_CONF_STRING) { nxt_conf_get_string(member, &var); - if (nxt_is_var(&var)) { + if (nxt_is_tstr(&var)) { ret = nxt_conf_vldt_var(vldt, &name, &var); if (ret != NXT_OK) { return ret; @@ -3147,7 +3158,7 @@ nxt_conf_vldt_access_log(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, "The \"path\" string must not be empty."); } - if (nxt_is_var(&conf.format)) { + if (nxt_is_tstr(&conf.format)) { return nxt_conf_vldt_var(vldt, &format_str, &conf.format); } -- cgit From f67a01b88fd7c7057767e18a3dd06c24e94c8aa8 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Mon, 24 Oct 2022 17:14:06 +0100 Subject: Isolation: wired up cgroup support to the config system. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This hooks the cgroup support up to the config system so it can actually be used. To make use of this in unit a new "cgroup" section has been added to the isolation configuration. e.g "applications": { "python": { "type": "python", "processes": 5, "path": "/opt/unit/unit-cgroup-test/", "module": "app", "isolation": { "cgroup": { "path": "app/python" } } } } Now there are two ways to specify the path, relative, like the above (without a leading '/') and absolute (with a leading '/'). In the above case the "python" application is placed into its own cgroup under CGROUP_ROOT/
/app/python. Whereas if you specified say "path": "/unit/app/python" Then the python application would be placed under CGROUP_ROOT/unit/app/python The first option allows you to easily take advantage of any resource limits that have already been configured for unit. With the second method (absolute pathname) if you know of an already existing cgroup where you'd like to place it, you can, e.g "path": "/system.slice/unit/python" Where system.slice has already been created by systemd and may already have some overall system limits applied which would also apply to unit. Limits apply down the hierarchy and lower groups can't exceed the previous group limits. So what does this actually look like? Lets take the unit-calculator application[0] and have each of its applications placed into their own cgroup. If we give each application a new section like "isolation": { "cgroup": { "path": "/unit/unit-calculator/add" } } changing the path for each one, we can visualise the result with the systemd-cgls command, e.g │ └─session-5.scope (#4561) │ ├─ 6667 sshd: andrew [priv] │ ├─ 6684 sshd: andrew@pts/0 │ ├─ 6685 -bash │ ├─ 12632 unit: main v1.28.0 [/opt/unit/sbin/unitd --control 127.0.0.1:808> │ ├─ 12634 unit: controller │ ├─ 12635 unit: router │ ├─ 13550 systemd-cgls │ └─ 13551 less ├─unit (#4759) │ └─unit-calculator (#5037) │ ├─subtract (#5069) │ │ ├─ 12650 unit: "subtract" prototype │ │ └─ 12651 unit: "subtract" application │ ├─multiply (#5085) │ │ ├─ 12653 unit: "multiply" prototype │ │ └─ 12654 unit: "multiply" application │ ├─divide (#5101) │ │ ├─ 12671 unit: "divide" prototype │ │ └─ 12672 node divide.js │ ├─sqroot (#5117) │ │ ├─ 12679 unit: "sqroot" prototype │ │ └─ 12680 /home/andrew/src/unit-calculator/sqroot/sqroot │ └─add (#5053) │ ├─ 12648 unit: "add" prototype │ └─ 12649 unit: "add" application We used an absolute path so the cgroups will be created relative to the main cgroupfs mount, e.g /sys/fs/cgroup We can see that the main unit processes are in the same cgroup as the shell from where they were started, by default child process are placed into the same cgroup as the parent. Then we can see that each application has been placed into its own cgroup under /sys/fs/cgroup Taking another example of a simple 5 process python application, with "isolation": { "cgroup": { "path": "app/python" } } Here we have specified a relative path and thus the python application will be placed below the existing cgroup that contains the main unit process. E.g │ │ │ ├─app-glib-cinnamon\x2dcustom\x2dlauncher\x2d3-43951.scope (#90951) │ │ │ │ ├─ 988 unit: main v1.28.0 [/opt/unit/sbin/unitd --no-daemon] │ │ │ │ ├─ 990 unit: controller │ │ │ │ ├─ 991 unit: router │ │ │ │ ├─ 43951 xterm -bg rgb:20/20/20 -fg white -fa DejaVu Sans Mono │ │ │ │ ├─ 43956 bash │ │ │ │ ├─ 58828 sudo -i │ │ │ │ ├─ 58831 -bash │ │ │ │ └─app (#107351) │ │ │ │ └─python (#107367) │ │ │ │ ├─ 992 unit: "python" prototype │ │ │ │ ├─ 993 unit: "python" application │ │ │ │ ├─ 994 unit: "python" application │ │ │ │ ├─ 995 unit: "python" application │ │ │ │ ├─ 996 unit: "python" application │ │ │ │ └─ 997 unit: "python" application [0]: Reviewed-by: Alejandro Colomar Signed-off-by: Andrew Clayton --- src/nxt_conf_validation.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'src/nxt_conf_validation.c') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index e650b44d..0f22c540 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -219,6 +219,11 @@ static nxt_int_t nxt_conf_vldt_clone_gidmap(nxt_conf_validation_t *vldt, nxt_conf_value_t *value); #endif +#if (NXT_HAVE_CGROUP) +static nxt_int_t nxt_conf_vldt_cgroup_path(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); +#endif + static nxt_conf_vldt_object_t nxt_conf_vldt_setting_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[]; @@ -240,6 +245,9 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_app_limits_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_app_processes_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_app_isolation_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_app_namespaces_members[]; +#if (NXT_HAVE_CGROUP) +static nxt_conf_vldt_object_t nxt_conf_vldt_app_cgroup_members[]; +#endif #if (NXT_HAVE_ISOLATION_ROOTFS) static nxt_conf_vldt_object_t nxt_conf_vldt_app_automount_members[]; #endif @@ -1094,6 +1102,15 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_app_isolation_members[] = { }, #endif +#if (NXT_HAVE_CGROUP) + { + .name = nxt_string("cgroup"), + .type = NXT_CONF_VLDT_OBJECT, + .validator = nxt_conf_vldt_object, + .u.members = nxt_conf_vldt_app_cgroup_members, + }, +#endif + NXT_CONF_VLDT_END }; @@ -1166,6 +1183,22 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_app_automount_members[] = { #endif +#if (NXT_HAVE_CGROUP) + +static nxt_conf_vldt_object_t nxt_conf_vldt_app_cgroup_members[] = { + { + .name = nxt_string("path"), + .type = NXT_CONF_VLDT_STRING, + .flags = NXT_CONF_VLDT_REQUIRED, + .validator = nxt_conf_vldt_cgroup_path, + }, + + NXT_CONF_VLDT_END +}; + +#endif + + #if (NXT_HAVE_CLONE_NEWUSER) static nxt_conf_vldt_object_t nxt_conf_vldt_app_procmap_members[] = { @@ -2798,6 +2831,35 @@ nxt_conf_vldt_target(nxt_conf_validation_t *vldt, nxt_str_t *name, } +#if (NXT_HAVE_CGROUP) + +static nxt_int_t +nxt_conf_vldt_cgroup_path(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, + void *data) +{ + char path[NXT_MAX_PATH_LEN]; + nxt_str_t cgpath; + + nxt_conf_get_string(value, &cgpath); + if (cgpath.length >= NXT_MAX_PATH_LEN - strlen(NXT_CGROUP_ROOT) - 1) { + return nxt_conf_vldt_error(vldt, "The cgroup path \"%V\" is too long.", + &cgpath); + } + + sprintf(path, "/%*s/", (int) cgpath.length, cgpath.start); + + if (cgpath.length == 0 || strstr(path, "/../") != NULL) { + return nxt_conf_vldt_error(vldt, + "The cgroup path \"%V\" is invalid.", + &cgpath); + } + + return NXT_OK; +} + +#endif + + static nxt_int_t nxt_conf_vldt_clone_namespaces(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data) -- cgit From dad7ef9a12f2cf16f2be011f167fc19b011ffe03 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Wed, 4 May 2022 16:13:19 +0100 Subject: Configuration: made large_header_buffer_size a valid setting. @JanMikes and @tagur87 on GitHub both reported issues with long URLs that were exceeding the 8192 byte large_header_buffer_size setting, which resulted in a HTTP 431 error (Request Header Fields Too Large). This can be resolved in the code by updating the following line in src/nxt_router.c::nxt_router_conf_create() skcf->large_header_buffer_size = 8192; However, requiring users to modify unit and install custom versions is less than ideal. We could increase the value, but to what? This commit takes the option of allowing the user to set this option in their config by making large_header_buffer_size a valid configuration setting. large_header_buffer_size is already set by the configuration system in nxt_router.c it just isn't set as a valid config option in nxt_conf_validation.c With this change users can set this option in their config if required by the following "settings": { "http": { "large_header_buffer_size": 16384 } }, It retains its default value of 8192 bytes if this is not set. With this commit, without the above setting or too low a value, with a long URL you get a 431 error. With the above setting set to a large enough value, the request is successful. NOTE: This setting really determines the maximum size of any single header _value_. Also, unit will try and place multiple values into a buffer _if_ they fully fit. NOTE: This is being released as undocumented and subject to change as it exposes internal workings of unit. Closes: Signed-off-by: Andrew Clayton --- src/nxt_conf_validation.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/nxt_conf_validation.c') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 0f22c540..218254bf 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -314,6 +314,9 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[] = { }, { .name = nxt_string("idle_timeout"), .type = NXT_CONF_VLDT_INTEGER, + }, { + .name = nxt_string("large_header_buffer_size"), + .type = NXT_CONF_VLDT_INTEGER, }, { .name = nxt_string("body_buffer_size"), .type = NXT_CONF_VLDT_INTEGER, -- cgit From f88371ff1d5173da44b8bf152e1b261e444a6eac Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Tue, 6 Dec 2022 12:56:03 +0000 Subject: Configuration: made large_header_buffers a valid setting. This is an extension to the previous commit, which made large_header_buffer_size a valid configuration setting. This commit makes a related value, large_header_buffers, a valid configuration setting. While large_header_buffer_size effectively limits the maximum size of any single header (although unit will try to pack multiple headers into a buffer if they wholly fit). large_header_buffers limits how many of these 'large' buffers are available. It makes sense to also allow this to be user set. large_header_buffers is already set by the configuration system in nxt_router.c it just isn't set as a valid config option in nxt_conf_validation.c With this change users can set this option in their config if required by the following "settings": { "http": { "large_header_buffers": 8 } }, It retains its default value of 4 if this is not set. NOTE: This is being released as undocumented and subject to change as it exposes internal workings of unit. Signed-off-by: Andrew Clayton --- src/nxt_conf_validation.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/nxt_conf_validation.c') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 218254bf..c6e63c25 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -317,6 +317,9 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[] = { }, { .name = nxt_string("large_header_buffer_size"), .type = NXT_CONF_VLDT_INTEGER, + }, { + .name = nxt_string("large_header_buffers"), + .type = NXT_CONF_VLDT_INTEGER, }, { .name = nxt_string("body_buffer_size"), .type = NXT_CONF_VLDT_INTEGER, -- cgit From 6dae517ebd20baa2066541e703d6aa594326dd69 Mon Sep 17 00:00:00 2001 From: OutOfFocus4 Date: Sun, 14 Nov 2021 10:47:07 -0500 Subject: Python: Added "prefix" to configuration. This patch gives users the option to set a `"prefix"` attribute for Python applications, either at the top level or for specific `"target"`s. If the attribute is present, the value of `"prefix"` must be a string beginning with `"/"`. If the value of the `"prefix"` attribute is longer than 1 character and ends in `"/"`, the trailing `"/"` is stripped. The purpose of the `"prefix"` attribute is to set the `SCRIPT_NAME` context value for WSGI applications and the `root_path` context value for ASGI applications, allowing applications to properly route requests regardless of the path that the server uses to expose the application. The context value is only set if the request's URL path begins with the value of the `"prefix"` attribute. In all other cases, the `SCRIPT_NAME` or `root_path` values are not set. In addition, for WSGI applications, the value of `"prefix"` will be stripped from the beginning of the request's URL path before it is sent to the application. Reviewed-by: Andrei Zeliankou Reviewed-by: Artem Konev Signed-off-by: Alejandro Colomar --- src/nxt_conf_validation.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/nxt_conf_validation.c') diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index c6e63c25..bf8aa760 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -128,6 +128,8 @@ static nxt_int_t nxt_conf_vldt_python_path_element(nxt_conf_validation_t *vldt, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_python_protocol(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_python_prefix(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_threads(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_thread_stack_size(nxt_conf_validation_t *vldt, @@ -795,6 +797,11 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_python_members[] = { .type = NXT_CONF_VLDT_STRING, .validator = nxt_conf_vldt_targets_exclusive, .u.string = "callable", + }, { + .name = nxt_string("prefix"), + .type = NXT_CONF_VLDT_STRING, + .validator = nxt_conf_vldt_targets_exclusive, + .u.string = "prefix", }, { .name = nxt_string("targets"), .type = NXT_CONF_VLDT_OBJECT, @@ -814,6 +821,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_python_target_members[] = { }, { .name = nxt_string("callable"), .type = NXT_CONF_VLDT_STRING, + }, { + .name = nxt_string("prefix"), + .type = NXT_CONF_VLDT_STRING, + .validator = nxt_conf_vldt_python_prefix, }, NXT_CONF_VLDT_END @@ -828,6 +839,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_python_notargets_members[] = { }, { .name = nxt_string("callable"), .type = NXT_CONF_VLDT_STRING, + }, { + .name = nxt_string("prefix"), + .type = NXT_CONF_VLDT_STRING, + .validator = nxt_conf_vldt_python_prefix, }, NXT_CONF_VLDT_NEXT(nxt_conf_vldt_python_common_members) @@ -1870,6 +1885,28 @@ nxt_conf_vldt_python_protocol(nxt_conf_validation_t *vldt, } +static nxt_int_t +nxt_conf_vldt_python_prefix(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data) +{ + nxt_str_t prefix; + + if (nxt_conf_type(value) != NXT_CONF_STRING) { + return nxt_conf_vldt_error(vldt, "The \"prefix\" must be a string " + "beginning with \"/\"."); + } + + nxt_conf_get_string(value, &prefix); + + if (!nxt_strchr_start(&prefix, '/')) { + return nxt_conf_vldt_error(vldt, "The \"prefix\" must be a string " + "beginning with \"/\"."); + } + + return NXT_OK; +} + + static nxt_int_t nxt_conf_vldt_threads(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data) -- cgit