#endif
/* Hashing -----------------------------------------------------------*/
-struct object { /* XXX: this goes elsewhere in due time */
- unsigned char hash[16];
- unsigned refcnt;
-};
typedef void hash_init_f(void);
typedef struct object *hash_lookup_f(unsigned char *key, struct object *nobj);
sp->backend = sp->vcl->default_backend;
/* Call the VCL program */
- sp->vcl->main_func(sp);
+ sp->vcl->recv_func(sp);
printf("Handling: %d\n", sp->handling);
switch(sp->handling) {
sess->handling = HND_Pass;
sess->done++;
}
+
+void VCL_insert(VCL_FARGS) { }
+void VCL_fetch(VCL_FARGS) { }
+void VCL_error(VCL_FARGS, unsigned err, const char *str) { }
"backend default {\n"
" set backend.host = \"%s\";\n"
"}\n"
- "sub main {\n"
- " pass;\n"
-#if 0
+ "sub vcl_recv {\n"
" if (req.request != \"GET\" && req.request != \"HEAD\") {\n"
" pass;\n"
" }\n"
- " lookup;\n"
+ "}\n"
+ "\n"
+ "sub vcl_lookup {\n"
" if (!obj.valid) {\n"
" fetch;\n"
- " if (obj.cacheable) {\n"
- " insert;\n"
- " }\n"
" }\n"
-#endif
+ " if (!obj.cacheable) {\n"
+ " pass;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "sub vcl_fetch {\n"
+ " if (!obj.valid) {\n"
+ " error;\n"
+ " }\n"
+ " insert;\n"
"}\n"
"", bflag);
assert(buf != NULL);
unsigned nuhdr;
};
+struct object {
+ unsigned char hash[16];
+ unsigned refcnt;
+ unsigned valid;
+ unsigned cacheable;
+};
+
struct sess {
int fd;
sesscb_f *sesscb;
struct backend *backend;
+ struct object *obj;
struct VCL_conf *vcl;
/* Various internal stuff */
#define VCL_PASS_ARGS sess
void VCL_count(unsigned);
-void VCL_no_cache();
-void VCL_no_new_cache();
+void VCL_no_cache(VCL_FARGS);
+void VCL_no_new_cache(VCL_FARGS);
int ip_match(unsigned, struct vcl_acl *);
int string_match(const char *, const char *);
int VCL_rewrite(const char *, const char *);
-int VCL_error(unsigned, const char *);
+void VCL_error(VCL_FARGS, unsigned, const char *);
void VCL_pass(VCL_FARGS);
-int VCL_fetch(void);
+void VCL_fetch(VCL_FARGS);
+void VCL_insert(VCL_FARGS);
int VCL_switch_config(const char *);
typedef void vcl_init_f(void);
unsigned magic;
#define VCL_CONF_MAGIC 0x7406c509 /* from /dev/random */
vcl_init_f *init_func;
- vcl_func_f *main_func;
+ vcl_func_f *recv_func;
+ vcl_func_f *lookup_func;
+ vcl_func_f *fetch_func;
struct backend *default_backend;
struct vcl_ref *ref;
unsigned nref;
static struct var vars[] = {
+ { "req.request", STRING, 0, "sess->http.req" },
+ { "obj.valid", BOOL, 0, "sess->obj->valid" },
+ { "obj.cacheable", BOOL, 0, "sess->obj->cacheable" },
#if 0
{ "req.ttlfactor", FLOAT, 0, "req->ttlfactor" },
{ "req.url.host", STRING, 0, "req->url.host" },
tl->t->e - tl->t->b, tl->t->b);
NextToken(tl);
break;
+ case T_NEQ:
+ I(tl); sbuf_printf(tl->fc, "strcmp(%s, ", vp->cname);
+ NextToken(tl);
+ ExpectErr(tl, CSTR);
+ sbuf_printf(tl->fc, "%*.*s)\n",
+ tl->t->e - tl->t->b,
+ tl->t->e - tl->t->b, tl->t->b);
+ NextToken(tl);
+ break;
default:
sbuf_printf(tl->sb, "Illegal condition ");
ErrToken(tl, tl->t);
switch (at->tok) {
case T_NO_NEW_CACHE:
I(tl);
- sbuf_printf(tl->fc, "VCL_no_new_cache();\n");
+ sbuf_printf(tl->fc, "VCL_no_new_cache(VCL_PASS_ARGS);\n");
return;
case T_NO_CACHE:
I(tl);
- sbuf_printf(tl->fc, "VCL_no_cache();\n");
+ sbuf_printf(tl->fc, "VCL_no_cache(VCL_PASS_ARGS);\n");
return;
case T_FINISH:
- I(tl);
- sbuf_printf(tl->fc, "return;\n");
+ I(tl); sbuf_printf(tl->fc, "sess->done = 1;\n");
+ I(tl); sbuf_printf(tl->fc, "return;\n");
return;
case T_PASS:
I(tl);
sbuf_printf(tl->fc, "VCL_pass(VCL_PASS_ARGS);\n");
- sbuf_printf(tl->fc, "return;\n");
+ I(tl); sbuf_printf(tl->fc, "sess->done = 1;\n");
+ I(tl); sbuf_printf(tl->fc, "return;\n");
return;
case T_FETCH:
I(tl);
- sbuf_printf(tl->fc, "VCL_fetch();\n");
+ sbuf_printf(tl->fc, "VCL_fetch(VCL_PASS_ARGS);\n");
+ I(tl); sbuf_printf(tl->fc, "sess->done = 1;\n");
+ I(tl); sbuf_printf(tl->fc, "return;\n");
+ return;
+ case T_INSERT:
+ I(tl);
+ sbuf_printf(tl->fc, "VCL_insert(VCL_PASS_ARGS);\n");
+ I(tl); sbuf_printf(tl->fc, "sess->done = 1;\n");
+ I(tl); sbuf_printf(tl->fc, "return;\n");
return;
case T_ERROR:
- a = UintVal(tl);
+ if (tl->t->tok == CNUM)
+ a = UintVal(tl);
+ else
+ a = 0;
I(tl);
- sbuf_printf(tl->fc, "VCL_error(%u, ", a);
+ sbuf_printf(tl->fc, "VCL_error(VCL_PASS_ARGS, %u, ", a);
if (tl->t->tok == CSTR) {
sbuf_printf(tl->fc, "%*.*s);\n",
tl->t->e - tl->t->b,
NextToken(tl);
} else
sbuf_printf(tl->fc, "(const char *)0);\n");
+ I(tl); sbuf_printf(tl->fc, "sess->done = 1;\n");
+ I(tl); sbuf_printf(tl->fc, "return;\n");
return;
case T_SWITCH_CONFIG:
ExpectErr(tl, ID);
"\t.magic = VCL_CONF_MAGIC,\n");
sbuf_printf(tl->fc,
"\t.init_func = VCL_Init,\n");
- sbuf_printf(tl->fc,
- "\t.main_func = VCL_function_main,\n");
+ sbuf_printf(tl->fc, "\t.recv_func = VCL_function_vcl_recv,\n");
+ sbuf_printf(tl->fc, "\t.lookup_func = VCL_function_vcl_lookup,\n");
+ sbuf_printf(tl->fc, "\t.fetch_func = VCL_function_vcl_fetch,\n");
sbuf_printf(tl->fc,
"\t.default_backend = &VCL_backend_default,\n");
sbuf_printf(tl->fc,
}
return (0);
case 'i':
+ if (p[0] == 'i' && p[1] == 'n' && p[2] == 's' &&
+ p[3] == 'e' && p[4] == 'r' && p[5] == 't'
+ && !isvar(p[6])) {
+ *q = p + 6;
+ return (T_INSERT);
+ }
if (p[0] == 'i' && p[1] == 'f' && !isvar(p[2])) {
*q = p + 2;
return (T_IF);
vcl_tnames[T_IF] = "if";
vcl_tnames[T_INC] = "++";
vcl_tnames[T_INCR] = "+=";
+ vcl_tnames[T_INSERT] = "insert";
vcl_tnames[T_LEQ] = "<=";
vcl_tnames[T_MUL] = "*=";
vcl_tnames[T_NEQ] = "!=";
fputs("HTTPH(\"Expires\", H_Expires, 2, 1, 0, 0, 0)\n", f);
fputs("HTTPH(\"Location\", H_Location, 2, 1, 0, 0, 0)\n", f);
fputs("HTTPH(\"Content-Encoding\", H_Content_Encoding, 2, 1, 0, 0, 0)\n", f);
+ fputs("HTTPH(\"ETag:\", H_ETag, 2, 1, 0, 0, 0)\n", f);
fputs("\n", f);
fputs("#undef HTTPH\n", f);
fputs(" const char *uhdr[VCA_UNKNOWNHDR];\n", f);
fputs(" unsigned nuhdr;\n", f);
fputs("};\n", f);
fputs("\n", f);
+ fputs("struct object { \n", f);
+ fputs(" unsigned char hash[16];\n", f);
+ fputs(" unsigned refcnt;\n", f);
+ fputs(" unsigned valid;\n", f);
+ fputs(" unsigned cacheable;\n", f);
+ fputs("};\n", f);
+ fputs("\n", f);
fputs("struct sess {\n", f);
fputs(" int fd;\n", f);
fputs("\n", f);
fputs(" sesscb_f *sesscb;\n", f);
fputs("\n", f);
fputs(" struct backend *backend;\n", f);
+ fputs(" struct object *obj;\n", f);
fputs(" struct VCL_conf *vcl;\n", f);
fputs("\n", f);
fputs(" /* Various internal stuff */\n", f);
fputs("#define VCL_PASS_ARGS sess\n", f);
fputs("\n", f);
fputs("void VCL_count(unsigned);\n", f);
- fputs("void VCL_no_cache();\n", f);
- fputs("void VCL_no_new_cache();\n", f);
+ fputs("void VCL_no_cache(VCL_FARGS);\n", f);
+ fputs("void VCL_no_new_cache(VCL_FARGS);\n", f);
fputs("int ip_match(unsigned, struct vcl_acl *);\n", f);
fputs("int string_match(const char *, const char *);\n", f);
fputs("int VCL_rewrite(const char *, const char *);\n", f);
- fputs("int VCL_error(unsigned, const char *);\n", f);
+ fputs("void VCL_error(VCL_FARGS, unsigned, const char *);\n", f);
fputs("void VCL_pass(VCL_FARGS);\n", f);
- fputs("int VCL_fetch(void);\n", f);
+ fputs("void VCL_fetch(VCL_FARGS);\n", f);
+ fputs("void VCL_insert(VCL_FARGS);\n", f);
fputs("int VCL_switch_config(const char *);\n", f);
fputs("\n", f);
fputs("typedef void vcl_init_f(void);\n", f);
fputs(" unsigned magic;\n", f);
fputs("#define VCL_CONF_MAGIC 0x7406c509 /* from /dev/random */\n", f);
fputs(" vcl_init_f *init_func;\n", f);
- fputs(" vcl_func_f *main_func;\n", f);
+ fputs(" vcl_func_f *recv_func;\n", f);
+ fputs(" vcl_func_f *lookup_func;\n", f);
+ fputs(" vcl_func_f *fetch_func;\n", f);
fputs(" struct backend *default_backend;\n", f);
fputs(" struct vcl_ref *ref;\n", f);
fputs(" unsigned nref;\n", f);
error
pass
fetch
+ insert
call
no_cache
no_new_cache
#define T_ERROR 137
#define T_PASS 138
#define T_FETCH 139
-#define T_CALL 140
-#define T_NO_CACHE 141
-#define T_NO_NEW_CACHE 142
-#define T_SET 143
-#define T_REWRITE 144
-#define T_FINISH 145
-#define T_SWITCH_CONFIG 146
-#define T_INC 147
-#define T_DEC 148
-#define T_CAND 149
-#define T_COR 150
-#define T_LEQ 151
-#define T_EQ 152
-#define T_NEQ 153
-#define T_GEQ 154
-#define T_SHR 155
-#define T_SHL 156
-#define T_INCR 157
-#define T_DECR 158
-#define T_MUL 159
-#define T_DIV 160
-#define ID 161
-#define VAR 162
-#define CNUM 163
-#define CSTR 164
-#define EOI 165
+#define T_INSERT 140
+#define T_CALL 141
+#define T_NO_CACHE 142
+#define T_NO_NEW_CACHE 143
+#define T_SET 144
+#define T_REWRITE 145
+#define T_FINISH 146
+#define T_SWITCH_CONFIG 147
+#define T_INC 148
+#define T_DEC 149
+#define T_CAND 150
+#define T_COR 151
+#define T_LEQ 152
+#define T_EQ 153
+#define T_NEQ 154
+#define T_GEQ 155
+#define T_SHR 156
+#define T_SHL 157
+#define T_INCR 158
+#define T_DECR 159
+#define T_MUL 160
+#define T_DIV 161
+#define ID 162
+#define VAR 163
+#define CNUM 164
+#define CSTR 165
+#define EOI 166