Guillaume Outters
August 29, 2019 03:02PM
Hello,

as an Nginx user, I regularly discover new features that prove useful if not game changers.

However I stay puzzled (nearly since I started using it) on why the config include system does not allow relative paths, that is, relative to the currently parsed file. This would allow for simple modular config designs, where a "main" server config file can embed the snippets that are deployed next to it.
The only tips I see on the forums and so is "hey, just use a templating system to absolutize every include at deployment time", which takes us away from Nginx' KISS philosophy.

In an ideal world, my production nginx.conf would only include /var/www/*/app.conf, and I could drop my "blorp" web app (that I developed on /home/gui/www/blorp) in /var/www and have it running at the next nginx reload, with it correctly loading every location /xxx { include inc/phpfpm.conf; } of its app.conf.
For now, I either have to centralize the snippets in /etc/nginx/inc/phpfpm.conf (thus when a new rule has to be added my developer has to tell my system operator to apply the change to the centralized file), or inline the snippets in the (then monolithic) app.conf (hey, duplication!), or hardcode the snippet's path as /var/www/blorp/inc/phpfpm.conf (and symlink it on my dev machine so that prod and dev config files are shared?), or better make the app.conf a template and fill absolute paths at deployment, so that if I want to run my shiny new version of blorp as blorp-ng along blorp it does not include the old version's phpfpm.conf erronously.

The following patch adds a simple heuristic to include: if the includee starts with "./", it is considered relative to the current file. If not, the current heuristic applies (paths stay relative to the prefix).

I would be interested in learning the flaws or drawbacks in this (bad?) idea. I first thought "security", (disallowing relative includes keeps included files under control in config's root), but anyhow, either you keep total control on the config (and are on your responsibility to not include anything out of the conf tree) or give the web app's developer a hook to load its app-required snippets, and then nothing prevents him to include whatever he wants.

--
Guillaume

# HG changeset patch
# User Guillaume Outters <guillaume-nginx@outters.eu>
# Date 1567058353 -7200
# Thu Aug 29 07:59:13 2019 +0200
# Node ID 704100d8a8772a4bc2faaef9abcc0308316e580c
# Parent 9f1f9d6e056a4f85907957ef263f78a426ae4f9c
ngx_conf_file: "include ./" acts relative to currently parsed file

Allow configuration files to include relatively to them instead of to prefix.
Eases modular configurations, where includees do not need to know their
absolute path to reach helper config files next to them.

diff -r 9f1f9d6e056a -r 704100d8a877 src/core/ngx_conf_file.c
--- a/src/core/ngx_conf_file.c Mon Aug 19 15:16:06 2019 +0300
+++ b/src/core/ngx_conf_file.c Thu Aug 29 12:59:13 2019 +0200
@@ -15,6 +15,7 @@
static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf);
static void ngx_conf_flush_files(ngx_cycle_t *cycle);

+ngx_int_t ngx_conf_full_name_rel(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix, ngx_str_t *current);

static ngx_command_t ngx_conf_commands[] = {

@@ -830,7 +831,7 @@

ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);

- if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
+ if (ngx_conf_full_name_rel(cf->cycle, &file, 1, &cf->conf_file->file.name) != NGX_OK) {
return NGX_CONF_ERROR;
}

@@ -884,16 +885,39 @@


ngx_int_t
-ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix)
+ngx_conf_full_name_rel(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix, ngx_str_t *current)
{
ngx_str_t *prefix;
+ ngx_str_t local_prefix;

- prefix = conf_prefix ? &cycle->conf_prefix : &cycle->prefix;
+ /*
+ * Path starting with literal ./ is interpreted relative to current's
+ * directory instead of prefix.
+ */
+ if (name->len >= 2 && name->data[0] == '.' && name->data[1] == '/' && current && current->len && current->data[0] == '/') {
+ name->len -= 2;
+ name->data += 2;
+
+ local_prefix.data = current->data;
+ for (local_prefix.len = current->len; local_prefix.data[--local_prefix.len] != '/'; /* void */ ) /* void */ ;
+ ++local_prefix.len;
+ prefix = &local_prefix;
+
+ } else {
+ prefix = conf_prefix ? &cycle->conf_prefix : &cycle->prefix;
+ }

return ngx_get_full_name(cycle->pool, prefix, name);
}


+ngx_int_t
+ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix)
+{
+ return ngx_conf_full_name_rel(cycle, name, conf_prefix, NULL);
+}
+
+
ngx_open_file_t *
ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
{


_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[PATCH] ngx_conf_file: "include ./" acts relative to currently parsed file

Guillaume Outters 481 August 29, 2019 03:02PM

Re: [PATCH] ngx_conf_file: "include ./" acts relative to currently parsed file

Maxim Dounin 208 August 30, 2019 10:04AM

Re: [PATCH] ngx_conf_file: "include ./" acts relative to currently parsed file

Guillaume Outters 186 August 30, 2019 10:28AM

Re: [PATCH] ngx_conf_file: "include ./" acts relative to currently parsed file

Maxim Dounin 179 September 03, 2019 10:40AM

Re: [PATCH] ngx_conf_file: "include ./" acts relative to currently parsed file

Guillaume Outters 189 September 03, 2019 12:24PM

Re: [PATCH] ngx_conf_file: "include ./" acts relative to currently parsed file

Maxim Dounin 198 September 09, 2019 06:50AM

Re: [PATCH] ngx_conf_file: "include ./" acts relative to currently parsed file

Guillaume Outters 212 September 09, 2019 12:16PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 309
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready