Hi all, attached is a patch to make 'import foo' relative to the importing source file, and a patch to remove the error upon duplicate 'include'.
vcl that comes from the cli or f_arg doesn't get a path, but in this case we fallback to vcl_dir. This means the same behavior for absolute paths and one-directory deep relative includes under vcl_dir. Use case: These two patches together make it possible to write and release a self-contained vcl package which you can include into your vcl. PRs are on github fwiw. 0K
From 0e0b6b7885f83b7cb84d2a4bd8120f78c8f612e0 Mon Sep 17 00:00:00 2001 From: Kacper Wysocki <[email protected]> Date: Tue, 17 Nov 2015 04:30:01 +0100 Subject: [PATCH] Allow duplicate vmod imports. The first vcl to import the vmod counts. --- bin/varnishtest/tests/m00001.vtc | 9 ++++++++- lib/libvcc/vcc_vmod.c | 24 ++++++++++-------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/bin/varnishtest/tests/m00001.vtc b/bin/varnishtest/tests/m00001.vtc index 1e0b45f..260162a 100644 --- a/bin/varnishtest/tests/m00001.vtc +++ b/bin/varnishtest/tests/m00001.vtc @@ -47,11 +47,18 @@ varnish v1 -cliok "vcl.discard vcl1" varnish v1 -cliok "vcl.list" varnish v1 -cliok "debug.vmod" -varnish v1 -errvcl {Module std already imported.} { +varnish v1 -vcl+backend { import ${vmod_std}; import ${vmod_std}; } +varnish v1 -vcl+backend { +} + +varnish v1 -cliok "vcl.discard vcl3" +varnish v1 -cliok "vcl.list" +varnish v1 -cliok "debug.vmod" + varnish v1 -errvcl {Symbol not found: 'std' (expected type BOOL):} { import ${vmod_std}; diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c index e8bab4f..9ab9ab6 100644 --- a/lib/libvcc/vcc_vmod.c +++ b/lib/libvcc/vcc_vmod.c @@ -68,21 +68,15 @@ vcc_ParseImport(struct vcc *tl) vcc_ErrWhere2(tl, t1, tl->t); return; } - if (osym != NULL) { - VSB_printf(tl->sb, "Module %.*s already imported.\n", - PF(mod)); - vcc_ErrWhere2(tl, t1, tl->t); - VSB_printf(tl->sb, "Previous import was here:\n"); - vcc_ErrWhere2(tl, osym->def_b, osym->def_e); - return; - } - bprintf(fn, "%.*s", PF(mod)); - sym = VCC_AddSymbolStr(tl, fn, SYM_VMOD); - ERRCHK(tl); - AN(sym); - sym->def_b = t1; - sym->def_e = tl->t; + if(osym == NULL) { + bprintf(fn, "%.*s", PF(mod)); + sym = VCC_AddSymbolStr(tl, fn, SYM_VMOD); + ERRCHK(tl); + AN(sym); + sym->def_b = t1; + sym->def_e = tl->t; + } if (tl->t->tok == ID) { if (!tl->unsafe_path) { @@ -106,6 +100,8 @@ vcc_ParseImport(struct vcc *tl) } SkipToken(tl, ';'); + if (osym != NULL) + return; hdl = dlopen(fn, RTLD_NOW | RTLD_LOCAL); if (hdl == NULL) { -- 2.6.2
From 448a5cd912a20f4fd3b6a88270031d379fec997a Mon Sep 17 00:00:00 2001 From: Kacper Wysocki <[email protected]> Date: Tue, 17 Nov 2015 04:11:08 +0100 Subject: [PATCH] VCL relative includes Modify vcl include resolution so that the include is relative to the including file's location, falling back to vcl_dir for default vcl and vcl defined on the console where file path is not available. --- bin/varnishtest/tests/v00045.vtc | 63 ++++++++++++++++++++++++++++++++++++++++ lib/libvcc/vcc_compile.c | 60 ++++++++++++++++++++++++++++++++++---- lib/libvcc/vcc_compile.h | 1 + 3 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 bin/varnishtest/tests/v00045.vtc diff --git a/bin/varnishtest/tests/v00045.vtc b/bin/varnishtest/tests/v00045.vtc new file mode 100644 index 0000000..cbc620f --- /dev/null +++ b/bin/varnishtest/tests/v00045.vtc @@ -0,0 +1,63 @@ +varnishtest "Test relative and absolute includes" + +# relative plain +shell "true > ${tmpdir}/_start.vcl" +varnish v1 -arg "-p vcl_dir=${tmpdir}" -vcl { + backend b { .host = "127.0.0.1"; } + include "_start.vcl" ; +} + +# absolute include +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + include "${tmpdir}/_start.vcl" ; +} + +# absolute -> relative include +shell "mkdir -p ${tmpdir}/1/2/3" +shell "true > ${tmpdir}/1/2/b.vcl" +shell "echo 'include \"2/b.vcl\";' > ${tmpdir}/1/a.vcl" +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + include "${tmpdir}/1/a.vcl" ; +} + +# relative -> relative +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + include "1/a.vcl" ; +} + +# relative -> relative -> relative +shell "echo 'include \"3/c.vcl\";' > ${tmpdir}/1/2/b.vcl" +shell "true > ${tmpdir}/1/2/3/c.vcl" +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + include "1/a.vcl" ; +} + +# relative -> absolute +shell "echo 'include \"${tmpdir}/1/2/3/c.vcl\";' > ${tmpdir}/1/aa.vcl" +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + include "1/aa.vcl" ; +} + +# relative -> absolute -> relative +shell "echo 'include \"${tmpdir}/1/2/b.vcl\";' > ${tmpdir}/1/aaa.vcl" +varnish v1 -vcl { + backend b { .host = "127.0.0.1"; } + include "1/aaa.vcl" ; +} + +# includes and parses out +shell "echo 'zool' > ${tmpdir}/1/2/3/c.vcl" +varnish v1 -errvcl {Found: 'zool' at} { + backend b { .host = "127.0.0.1"; } + include "1/a.vcl"; +} + +shell "rm -f ${tmpdir}/a" +shell "rm -f ${tmpdir}/_start.vcl" + + diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c index e79597f..699169f 100644 --- a/lib/libvcc/vcc_compile.c +++ b/lib/libvcc/vcc_compile.c @@ -422,7 +422,7 @@ EmitStruct(const struct vcc *tl) /*--------------------------------------------------------------------*/ static struct source * -vcc_new_source(const char *b, const char *e, const char *name) +vcc_new_source(const char *b, const char *e, const char *name, const char *path) { struct source *sp; @@ -434,6 +434,10 @@ vcc_new_source(const char *b, const char *e, const char *name) AN(sp->name); sp->b = b; sp->e = e; + if (path != NULL) { + sp->path = strdup(path); + AN(sp->path); + } return (sp); } @@ -447,6 +451,48 @@ vcc_destroy_source(struct source *sp) free(sp); } +/*-------------------------------------------------------------------- + * Include files relative to source's path + * + */ + +static struct vsb *vcc_include_path(const struct vcc *tl, const char *fn) { + struct vsb *vsb; + char *p, *relp; + const char *fsrc; + vsb = VSB_new_auto(); + AN(vsb); + VSB_clear(vsb); + /* absolute paths .. are relative to / */ + if(fn[0] == '/'){ + fsrc = fn + 1; + goto dirname; + } + + /* relative paths are relative to includers source path */ + relp = tl->vcl_dir; + if(tl->src->path) + relp = tl->src->path; + + VSB_cat(vsb, relp); + /* including source may have a relative prefix we need to add */ + fsrc = tl->src->name; + if(fsrc[0] == '/'){ + VSB_finish(vsb); + return vsb; + } +dirname: + p = strrchr(fsrc, '/'); + if(p == NULL){ + VSB_finish(vsb); + return vsb; + } + VSB_putc(vsb, '/'); + VSB_bcat(vsb, fsrc, p - fsrc); + VSB_finish(vsb); + return vsb; +} + /*--------------------------------------------------------------------*/ static struct source * @@ -454,19 +500,23 @@ vcc_file_source(const struct vcc *tl, struct vsb *sb, const char *fn) { char *f; struct source *sp; + struct vsb *fb; if (!tl->unsafe_path && strchr(fn, '/') != NULL) { VSB_printf(sb, "Include path is unsafe '%s'\n", fn); return (NULL); } - f = VFIL_readfile(tl->vcl_dir, fn, NULL); + fb = vcc_include_path(tl, fn); + f = VFIL_readfile(VSB_data(fb), fn, NULL); if (f == NULL) { VSB_printf(sb, "Cannot read file '%s': %s\n", fn, strerror(errno)); + VSB_delete(fb); return (NULL); } - sp = vcc_new_source(f, NULL, fn); + sp = vcc_new_source(f, NULL, fn, VSB_data(fb)); sp->freeit = f; + VSB_delete(fb); return (sp); } @@ -649,7 +699,7 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp) return (vcc_DestroyTokenList(tl, NULL)); /* Register and lex the builtin VCL */ - sp = vcc_new_source(tl->builtin_vcl, NULL, "Builtin"); + sp = vcc_new_source(tl->builtin_vcl, NULL, "Builtin", NULL); assert(sp != NULL); VTAILQ_INSERT_TAIL(&tl->sources, sp, list); sp->idx = tl->nsources++; @@ -764,7 +814,7 @@ VCC_Compile(const struct vcc *tl, struct vsb *sb, const char *b) struct source *sp; char *r; - sp = vcc_new_source(b, NULL, "input"); + sp = vcc_new_source(b, NULL, "input", NULL); if (sp == NULL) return (NULL); r = vcc_CompileSource(tl, sb, sp); diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index 4c155a1..fcb9c35 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -87,6 +87,7 @@ struct source { const char *e; unsigned idx; char *freeit; + char *path; }; struct token { -- 2.6.2
_______________________________________________ varnish-dev mailing list [email protected] https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
