r449 - in trunk/varnish-cache: bin/varnishd include lib/libvcl

phk at projects.linpro.no phk at projects.linpro.no
Wed Jul 12 10:34:48 CEST 2006


Author: phk
Date: 2006-07-12 10:34:48 +0200 (Wed, 12 Jul 2006)
New Revision: 449

Modified:
   trunk/varnish-cache/bin/varnishd/varnishd.c
   trunk/varnish-cache/include/libvcl.h
   trunk/varnish-cache/lib/libvcl/vcl_compile.c
Log:
Teach the VCL compiler about default functions, so that users will
not have to copy&paste the default methods if they have no special
requirements for a particular method.

No such facility exists for backends, so a backend description is
now the minumum VCL program.

When we initialize the VCL compiler we hand it a piece of source code
with the "default code", this must include definitions of all methods
named with a "default_" prefix (ie: "default_vcl_recv" etc).

During compilation we always compile this piece of source code in (after
the user supplied VCL source).

If the user did not provide a particular method, the default method is
used instead.  The user can also call the default method directly,
for instance by:

	sub vcl_recv {
		if (req.http.Expect) {
			error;
		}
		call default_vcl_recv;
	}

Later on, this could be expanded to allow other subroutines to be
included in the default VCL for the users calling convenience.



Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c	2006-07-12 07:45:59 UTC (rev 448)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c	2006-07-12 08:34:48 UTC (rev 449)
@@ -33,6 +33,46 @@
 
 /*--------------------------------------------------------------------*/
 
+static const char *default_vcl =
+    "sub default_vcl_recv {\n"
+    "    if (req.request != \"GET\" && req.request != \"HEAD\") {\n"
+    "        pipe;\n"
+    "    }\n"
+    "    if (req.http.Expect) {\n"
+    "        pipe;\n"
+    "    }\n"
+    "    if (req.http.Authenticate || req.http.Cookie) {\n"
+    "        pass;\n"
+    "    }\n"
+    "    lookup;\n"
+    "}\n"
+    "\n"
+    "sub default_vcl_hit {\n"
+    "    if (!obj.cacheable) {\n"
+    "        pass;\n"
+    "    }\n"
+    "    deliver;\n"
+    "}\n"
+    "\n"
+    "sub default_vcl_miss {\n"
+    "    fetch;\n"
+    "}\n"
+    "\n"
+    "sub default_vcl_fetch {\n"
+    "    if (!obj.valid) {\n"
+    "        error;\n"
+    "    }\n"
+    "    if (!obj.cacheable) {\n"
+    "        pass;\n"
+    "    }\n"
+    "    insert;\n"
+    "}\n"
+    "sub default_vcl_timeout {\n"
+    "    discard;\n"
+    "}\n";
+
+/*--------------------------------------------------------------------*/
+
 struct heritage heritage;
 struct event_base *mgt_eb;
 
@@ -90,44 +130,7 @@
 	    "backend default {\n"
 	    "    set backend.host = \"%*.*s\";\n"
 	    "    set backend.port = \"%s\";\n"
-	    "}\n"
-	    "sub vcl_recv {\n"
-	    "    if (req.request != \"GET\" && req.request != \"HEAD\") {\n"
-	    "        pipe;\n"
-	    "    }\n"
-	    "    if (req.http.Expect) {\n"
-	    "        pipe;\n"
-	    "    }\n"
-	    "    if (req.http.Authenticate || req.http.Cookie) {\n"
-	    "        pass;\n"
-	    "    }\n"
-	    "    lookup;\n"
-	    "}\n"
-	    "\n"
-	    "sub vcl_hit {\n"
-	    "    if (!obj.cacheable) {\n"
-	    "        pass;\n"
-	    "    }\n"
-	    "    deliver;\n"
-	    "}\n"
-	    "\n"
-	    "sub vcl_miss {\n"
-	    "    fetch;\n"
-	    "}\n"
-	    "\n"
-	    "sub vcl_fetch {\n"
-	    "    if (!obj.valid) {\n"
-	    "        error;\n"
-	    "    }\n"
-	    "    if (!obj.cacheable) {\n"
-	    "        pass;\n"
-	    "    }\n"
-	    "    insert;\n"
-	    "}\n"
-	    "sub vcl_timeout {\n"
-	    "    discard;\n"
-	    "}\n"
-	    "", p - bflag, p - bflag, bflag, q);
+	    "}\n", p - bflag, p - bflag, bflag, q);
 	assert(buf != NULL);
 	sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
 	assert(sb != NULL);
@@ -243,6 +246,9 @@
 m_cli_func_exit(struct cli *cli, char **av, void *priv)
 {
 
+	(void)cli;
+	(void)av;
+	(void)priv;
 	mgt_child_kill();
 	exit (0);
 }
@@ -503,7 +509,7 @@
 	setbuf(stdout, NULL);
 	setbuf(stderr, NULL);
  
-	VCC_InitCompile();
+	VCC_InitCompile(default_vcl);
 
 	heritage.default_ttl = 120;
 	heritage.wthread_min = 1;

Modified: trunk/varnish-cache/include/libvcl.h
===================================================================
--- trunk/varnish-cache/include/libvcl.h	2006-07-12 07:45:59 UTC (rev 448)
+++ trunk/varnish-cache/include/libvcl.h	2006-07-12 08:34:48 UTC (rev 449)
@@ -4,6 +4,6 @@
 
 char *VCC_Compile(struct sbuf *sb, const char *b, const char *e);
 char *VCC_CompileFile(struct sbuf *sb, const char *fn);
-void VCC_InitCompile(void);
+void VCC_InitCompile(const char *default_vcl);
 
 

Modified: trunk/varnish-cache/lib/libvcl/vcl_compile.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcl_compile.c	2006-07-12 07:45:59 UTC (rev 448)
+++ trunk/varnish-cache/lib/libvcl/vcl_compile.c	2006-07-12 08:34:48 UTC (rev 449)
@@ -128,10 +128,11 @@
 
 static struct method {
 	const char		*name;
+	const char		*defname;
 	unsigned		returns;
 } method_tab[] = {
 #define VCL_RET_MAC(a,b,c)
-#define VCL_MET_MAC(a,b,c)	{ "vcl_"#a, c },
+#define VCL_MET_MAC(a,b,c)	{ "vcl_"#a, "default_vcl_"#a, c },
 #include "vcl_returns.h"
 #undef VCL_MET_MAC
 #undef VCL_RET_MAC
@@ -195,6 +196,7 @@
 static void Cond_0(struct tokenlist *tl);
 static struct proc *AddProc(struct tokenlist *tl, struct token *t, int def);
 static void AddCall(struct tokenlist *tl, struct token *t);
+static const char *vcc_default_vcl_b, *vcc_default_vcl_e;
 
 /*--------------------------------------------------------------------*/
 
@@ -223,13 +225,22 @@
 ErrWhere(struct tokenlist *tl, struct token *t)
 {
 	unsigned lin, pos, x, y;
-	const char *p, *l;
+	const char *p, *l, *f, *b, *e;
 	
 	lin = 1;
 	pos = 0;
 	if (t->tok == METHOD)
 		return;
-	for (l = p = tl->b; p < t->b; p++) {
+	if (t->b >= vcc_default_vcl_b && t->b < vcc_default_vcl_e) {
+		f = "Default VCL code (compiled in)";
+		b = vcc_default_vcl_b;
+		e = vcc_default_vcl_e;
+	} else {
+		f = "VCL code";
+		b = tl->b;
+		e = tl->e;
+	}
+	for (l = p = b; p < t->b; p++) {
 		if (*p == '\n') {
 			lin++;
 			pos = 0;
@@ -240,9 +251,9 @@
 		} else
 			pos++;
 	}
-	sbuf_printf(tl->sb, "Line %d Pos %d\n", lin, pos);
+	sbuf_printf(tl->sb, "In %s Line %d Pos %d\n", f, lin, pos);
 	x = y = 0;
-	for (p = l; p < tl->e && *p != '\n'; p++) {
+	for (p = l; p < e && *p != '\n'; p++) {
 		if (*p == '\t') {
 			y &= ~7;
 			y += 8;
@@ -258,7 +269,7 @@
 	}
 	sbuf_cat(tl->sb, "\n");
 	x = y = 0;
-	for (p = l; p < tl->e && *p != '\n'; p++) {
+	for (p = l; p < e && *p != '\n'; p++) {
 		if (p >= t->b && p < t->e) {
 			sbuf_bcat(tl->sb, "#", 1);
 			x++;
@@ -452,6 +463,20 @@
 	return (r);
 }
 
+static int
+FindRefStr(struct tokenlist *tl, const char *s, enum ref_type type)
+{
+	struct ref *r;
+
+	TAILQ_FOREACH(r, &tl->refs, list) {
+		if (r->type != type)
+			continue;
+		if (IdIs(r->name, s))
+			return (1);
+	}
+	return (0);
+}
+
 static void
 AddRef(struct tokenlist *tl, struct token *t, enum ref_type type)
 {
@@ -1381,8 +1406,13 @@
 	t->e = e;
 	TAILQ_INSERT_TAIL(&tl->tokens, t, list);
 	tl->t = t;
-	if (0)
-		fprintf(stderr, "+ %s\n", vcl_tnames[tok]);
+	if (0) {
+		fprintf(stderr, "[%s %*.*s] ",
+		    vcl_tnames[tok],
+		    e - b, e - b, b);
+		if (tok == EOI)
+			fprintf(stderr, "\n");
+	}
 }
 
 /*--------------------------------------------------------------------
@@ -1478,8 +1508,6 @@
 		ErrWhere(tl, tl->t);
 		return;
 	}
-	/* Add End Of Input token */
-	AddToken(tl, EOI, p, p);
 }
 
 /*--------------------------------------------------------------------
@@ -1575,6 +1603,8 @@
 
 	TAILQ_FOREACH(p, &tl->procs, list) {
 		for(m = method_tab; m->name != NULL; m++) {
+			if (IdIs(p->name, m->defname))
+				p->called = 1;
 			if (IdIs(p->name, m->name))
 				break;
 		}
@@ -1722,8 +1752,13 @@
 	Fc(tl, 0, "\t.nref = VGC_NREFS,\n");
 #define VCL_RET_MAC(l,u,b)
 #define VCL_MET_MAC(l,u,b) \
-	Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n"); \
-	AddRefStr(tl, "vcl_" #l, R_FUNC);
+	if (FindRefStr(tl, "vcl_" #l, R_FUNC)) { \
+		Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n"); \
+		AddRefStr(tl, "vcl_" #l, R_FUNC); \
+	} else { \
+		Fc(tl, 0, "\t." #l "_func = VGC_function_default_vcl_" #l ",\n"); \
+	} \
+	AddRefStr(tl, "default_vcl_" #l, R_FUNC);
 #include "vcl_returns.h"
 #undef VCL_MET_MAC
 #undef VCL_RET_MAC
@@ -1762,6 +1797,8 @@
 	assert(e != NULL);
 	tokens.e = e;
 	Lexer(&tokens, b, e);
+	Lexer(&tokens, vcc_default_vcl_b, vcc_default_vcl_e);
+	AddToken(&tokens, EOI, e, e);
 	if (tokens.err)
 		goto done;
 	tokens.t = TAILQ_FIRST(&tokens.tokens);
@@ -1870,10 +1907,14 @@
 /*--------------------------------------------------------------------*/
 
 void
-VCC_InitCompile(void)
+VCC_InitCompile(const char *default_vcl)
 {
 	struct var *v;
 
+	vcc_default_vcl_b = default_vcl;
+	vcc_default_vcl_e = strchr(default_vcl, '\0');
+	assert(vcc_default_vcl_e != NULL);
+	
 	register_printf_function ('T', VCC_T_render, VCC_T_arginfo);
 	vcl_init_tnames();
 	for (v = vars; v->name != NULL; v++)




More information about the varnish-commit mailing list