summaryrefslogtreecommitdiffhomepage
path: root/src/python/nxt_python.c
diff options
context:
space:
mode:
authorOutOfFocus4 <jeff.iadarola@gmail.com>2021-11-14 10:47:07 -0500
committerAlejandro Colomar <alx@nginx.com>2022-12-14 11:30:30 +0100
commit6dae517ebd20baa2066541e703d6aa594326dd69 (patch)
tree6fe6a7cc8a767bc536545b640542590bbb222d30 /src/python/nxt_python.c
parent7a81d9d61d0c4e3cc7e6b74b6be367cbf26ea2ab (diff)
downloadunit-6dae517ebd20baa2066541e703d6aa594326dd69.tar.gz
unit-6dae517ebd20baa2066541e703d6aa594326dd69.tar.bz2
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 <zelenkov@nginx.com> Reviewed-by: Artem Konev <artem.konev@nginx.com> Signed-off-by: Alejandro Colomar <alx@nginx.com>
Diffstat (limited to '')
-rw-r--r--src/python/nxt_python.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/src/python/nxt_python.c b/src/python/nxt_python.c
index 8983815c..bdb04579 100644
--- a/src/python/nxt_python.c
+++ b/src/python/nxt_python.c
@@ -30,6 +30,8 @@ static nxt_int_t nxt_python_start(nxt_task_t *task,
nxt_process_data_t *data);
static nxt_int_t nxt_python_set_target(nxt_task_t *task,
nxt_python_target_t *target, nxt_conf_value_t *conf);
+nxt_inline nxt_int_t nxt_python_set_prefix(nxt_task_t *task,
+ nxt_python_target_t *target, nxt_conf_value_t *value);
static nxt_int_t nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value);
static int nxt_python_init_threads(nxt_python_app_conf_t *c);
static int nxt_python_ready_handler(nxt_unit_ctx_t *ctx);
@@ -389,6 +391,7 @@ nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target,
static nxt_str_t module_str = nxt_string("module");
static nxt_str_t callable_str = nxt_string("callable");
+ static nxt_str_t prefix_str = nxt_string("prefix");
module = obj = NULL;
@@ -436,6 +439,11 @@ nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target,
goto fail;
}
+ value = nxt_conf_get_object_member(conf, &prefix_str, NULL);
+ if (nxt_slow_path(nxt_python_set_prefix(task, target, value) != NXT_OK)) {
+ goto fail;
+ }
+
target->application = obj;
obj = NULL;
@@ -453,6 +461,48 @@ fail:
}
+nxt_inline nxt_int_t
+nxt_python_set_prefix(nxt_task_t *task, nxt_python_target_t *target,
+ nxt_conf_value_t *value)
+{
+ u_char *prefix;
+ nxt_str_t str;
+
+ if (value == NULL) {
+ return NXT_OK;
+ }
+
+ nxt_conf_get_string(value, &str);
+
+ if (str.length == 0) {
+ return NXT_OK;
+ }
+
+ if (str.start[str.length - 1] == '/') {
+ str.length--;
+ }
+ target->prefix.length = str.length;
+ prefix = nxt_malloc(str.length);
+ if (nxt_slow_path(prefix == NULL)) {
+ nxt_alert(task, "Failed to allocate target prefix string");
+ return NXT_ERROR;
+ }
+
+ target->py_prefix = PyString_FromStringAndSize((char *)str.start,
+ str.length);
+ if (nxt_slow_path(target->py_prefix == NULL)) {
+ nxt_free(prefix);
+ nxt_alert(task, "Python failed to allocate target prefix "
+ "string");
+ return NXT_ERROR;
+ }
+ nxt_memcpy(prefix, str.start, str.length);
+ target->prefix.start = prefix;
+
+ return NXT_OK;
+}
+
+
static nxt_int_t
nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value)
{
@@ -730,7 +780,8 @@ nxt_python_done_strings(nxt_python_string_t *pstr)
static void
nxt_python_atexit(void)
{
- nxt_int_t i;
+ nxt_int_t i;
+ nxt_python_target_t *target;
if (nxt_py_proto.done != NULL) {
nxt_py_proto.done();
@@ -740,7 +791,12 @@ nxt_python_atexit(void)
if (nxt_py_targets != NULL) {
for (i = 0; i < nxt_py_targets->count; i++) {
- Py_XDECREF(nxt_py_targets->target[i].application);
+ target = &nxt_py_targets->target[i];
+
+ Py_XDECREF(target->application);
+ Py_XDECREF(target->py_prefix);
+
+ nxt_free(target->prefix.start);
}
nxt_unit_free(NULL, nxt_py_targets);