[PATCH] ngx_conf_file: "include x.conf nearby; " acts relative to the currently parsed file
Guillaume Outters
guillaume-nginx at outters.eu
Mon Sep 2 03:09:45 UTC 2019
Hello Maxim (and anyone interested in fact),
here is my re-attempt at easing cascade includes, that is, an included
file can include snippets (that it knows are located next to him)
without having to know the path through which itself was included.
I have abandoned the (definitely obscure and error prone) "./" prefix
to use a conventional flag (I have chosen "nearby" which seems more
natural than either "local" or "relative").
Use case:
in nginx.conf:
include /var/www/*/conf/nginx/main.conf;
in /var/www/outters.eu/conf/nginx/main.conf:
include nearby snippets/phpfpm.conf;
instead of:
- either including /var/www/outters.eu/conf/nginx/snippets/phpfpm.conf
(requires templating when the webapp has no fixed delivery path)
- or inlining the contents of phpfpm.conf (which would be a pity if it
has to be included multiple times).
As "nearby" plugs into ngx_conf_file.c, it works gracefully with
wildcards includes too.
Hoping this patch will this time be both helpful and clean,
--
Guillaume
# HG changeset patch
# User Guillaume Outters <guillaume-nginx at outters.eu>
# Date 1567393678 -7200
# Mon Sep 02 05:07:58 2019 +0200
# Node ID 3165025ac6d67c0895fe2b7f110ba7d00c73d485
# Parent 9f1f9d6e056a4f85907957ef263f78a426ae4f9c
ngx_conf_file: "include x.conf nearby;" acts relative to the currently parsed file
"include x.conf nearby;" found in d/0.conf will include d/x.conf.
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 3165025ac6d6 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 Mon Sep 02 05:07:58 2019 +0200
@@ -10,16 +10,19 @@
#define NGX_CONF_BUFFER 4096
+#define NGX_CONF_FLAG_RELATIVE "nearby"
+
static ngx_int_t ngx_conf_add_dump(ngx_conf_t *cf, ngx_str_t *filename);
static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last);
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_conf_t *cf, ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix, ngx_uint_t relative);
static ngx_command_t ngx_conf_commands[] = {
{ ngx_string("include"),
- NGX_ANY_CONF|NGX_CONF_TAKE1,
+ NGX_ANY_CONF|NGX_CONF_TAKE12,
ngx_conf_include,
0,
0,
@@ -824,13 +827,32 @@
ngx_int_t n;
ngx_str_t *value, file, name;
ngx_glob_t gl;
+ ngx_uint_t relative;
value = cf->args->elts;
file = value[1];
+ relative = 0;
+ if (cf->args->nelts == 3) {
+ if (ngx_strcmp(value[2].data, NGX_CONF_FLAG_RELATIVE) == 0) {
+ relative = 1;
+
+ } else if (ngx_strcmp(value[1].data, NGX_CONF_FLAG_RELATIVE) == 0) {
+ relative = 1;
+ file = value[2];
+
+ } else {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid value \"%s\" in \"%s\" directive, "
+ "expected \"%s\"", value[2].data,
+ cmd->name.data, NGX_CONF_FLAG_RELATIVE);
+ return NGX_CONF_ERROR;
+ }
+ }
+
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, cf->cycle, &file, 1, relative) != NGX_OK) {
return NGX_CONF_ERROR;
}
@@ -884,16 +906,44 @@
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_conf_t *cf, ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix, ngx_uint_t relative)
{
ngx_str_t *prefix;
+ ngx_str_t local_prefix;
- prefix = conf_prefix ? &cycle->conf_prefix : &cycle->prefix;
+ if (relative) {
+ if (name->len >= 1 && name->data[0] == '/') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "relative path \"%s\" "
+ "should not start with \"/\"",
+ name);
+ return NGX_ERROR;
+ }
+
+ local_prefix.data = cf->conf_file->file.name.data;
+ for (local_prefix.len = cf->conf_file->file.name.len;
+ --local_prefix.len >= 0
+ && 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(NULL, cycle, name, conf_prefix, 0);
+}
+
+
ngx_open_file_t *
ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
{
More information about the nginx-devel
mailing list