]> err.no Git - varnish/commitdiff
Add VCC support for backend probe specifications.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 8 Jul 2008 09:15:32 +0000 (09:15 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 8 Jul 2008 09:15:32 +0000 (09:15 +0000)
It is possible to specify just the URL to be probed, or to specify the
entire HTTP request:

backend b0 {
.host = "127.0.0.1";
.probe = {
.url = "/test.jpg";
.timeout = 224 ms;
}
}

backend b1 {
.host = "127.0.0.1";
.probe = {
# NB: \r\n automatically inserted after each string!
.request =
    "GET / HTTP/1.1"
    "Host: www.foo.bar"
    "Connection: close";
.timeout = 0.3 s;
}
}

If the full request has not been completed within the timeout, the
backend will be set to down.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2902 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishtest/tests/v00005.vtc [new file with mode: 0644]
varnish-cache/include/vrt.h
varnish-cache/lib/libvcl/vcc_backend.c
varnish-cache/lib/libvcl/vcc_fixed_token.c

diff --git a/varnish-cache/bin/varnishtest/tests/v00005.vtc b/varnish-cache/bin/varnishtest/tests/v00005.vtc
new file mode 100644 (file)
index 0000000..f582de9
--- /dev/null
@@ -0,0 +1,51 @@
+# $Id$
+
+test "VCL: test backend probe syntax"
+
+# Check url definition
+varnish v1 -vcl {
+       backend b1 {
+               .host = "localhost";
+               .probe = {
+                       .url = "/";
+               }
+       }
+}
+
+# Check request definition
+varnish v1 -vcl {
+       backend b1 {
+               .host = "localhost";
+               .probe = {
+                       .request = 
+                           "GET / HTTP/1.1"
+                           "Host: foo.bar" ;
+               }
+       }
+}
+
+# Check redefinition
+varnish v1 -badvcl {
+       backend b1 {
+               .host = "localhost";
+               .probe = {
+                       .url = "/";
+                       .request = 
+                           "GET / HTTP/1.1"
+                           "Host: foo.bar" ;
+               }
+       }
+}
+
+# Check redefinition the other way
+varnish v1 -badvcl {
+       backend b1 {
+               .host = "localhost";
+               .probe = {
+                       .request = 
+                           "GET / HTTP/1.1"
+                           "Host: foo.bar" ;
+                       .url = "/";
+               }
+       }
+}
index a8eb9b47fb9dea0929a24ccc11159bc4286fea01..49cfeb14f3d122bad0485121e365d7ee94cfd6f8 100644 (file)
@@ -41,15 +41,25 @@ struct director;
 struct VCL_conf;
 struct sockaddr;
 
+/*
+ * A backend probe specification
+ */
+
+struct vrt_backend_probe {
+       char            *request;
+       double          timeout;
+};
+
 /*
  * A backend is a host+port somewhere on the network
  */
 struct vrt_backend {
-       char            *portname;
-       char            *hostname;
-       char            *vcl_name;
-       char            *ident;
-       double          connect_timeout;
+       char                            *portname;
+       char                            *hostname;
+       char                            *vcl_name;
+       char                            *ident;
+       double                          connect_timeout;
+       struct vrt_backend_probe        probe;
 };
 
 /*
index 1283f2fdeceeddc01bb9607d92578d13bb64af5e..484d2d83de5201a117c97e83d38cc3cd91b9931a 100644 (file)
@@ -216,6 +216,89 @@ vcc_FieldsOk(struct tokenlist *tl, const struct fld_spec *fs)
        }
 }
 
+/*--------------------------------------------------------------------
+ * Parse a backend probe specification
+ */
+
+static void
+vcc_ProbeRedef(struct tokenlist *tl, struct token **t_did, struct token *t_field)
+{
+       if (*t_did != NULL) {
+               vsb_printf(tl->sb,
+                   "Probe request redefinition at:\n");
+               vcc_ErrWhere(tl, t_field);
+               vsb_printf(tl->sb,
+                   "Previous definition:\n");
+               vcc_ErrWhere(tl, *t_did);
+               return;
+       }
+       *t_did = t_field;
+}
+
+static void
+vcc_ParseProbe(struct tokenlist *tl)
+{
+       struct fld_spec *fs;
+       struct token *t_field;
+       struct token *t_did = NULL;
+
+       fs = vcc_FldSpec(tl, "?url", "?request", "?timeout", NULL);
+
+       ExpectErr(tl, '{');
+       vcc_NextToken(tl);
+
+       Fh(tl, 0, "\t.probe = {\n");
+       while (tl->t->tok != '}') {
+
+               vcc_IsField(tl, &t_field, fs);
+               ERRCHK(tl);
+               if (tl->err)
+                       break;
+               if (vcc_IdIs(t_field, "url")) {
+                       vcc_ProbeRedef(tl, &t_did, t_field);
+                       ERRCHK(tl);
+                       ExpectErr(tl, CSTR);
+                       Fh(tl, 0, "\t\t.request =\n");
+                       Fh(tl, 0, "\t\t\t\"GET \" ");
+                       EncToken(tl->fh, tl->t);
+                       Fh(tl, 0, " \" /HTTP/1.1\\r\\n\"\n");
+                       Fh(tl, 0, "\t\t\t\"Connection: close\\r\\n\"\n");
+                       Fh(tl, 0, "\t\t\t\"\\r\\n\",\n");
+                       vcc_NextToken(tl);
+               } else if (vcc_IdIs(t_field, "request")) {
+                       vcc_ProbeRedef(tl, &t_did, t_field);
+                       ERRCHK(tl);
+                       ExpectErr(tl, CSTR);
+                       Fh(tl, 0, "\t\t.request =\n");
+                       while (tl->t->tok == CSTR) {
+                               Fh(tl, 0, "\t\t\t");
+                               EncToken(tl->fh, tl->t);
+                               Fh(tl, 0, " \"\\r\\n\"\n");
+                               vcc_NextToken(tl);
+                       }
+                       Fh(tl, 0, "\t\t\t\"\\r\\n\",\n");
+               } else if (vcc_IdIs(t_field, "timeout")) {
+                       Fh(tl, 0, "\t\t.timeout = ");
+                       tl->fb = tl->fh;
+                       vcc_TimeVal(tl);
+                       tl->fb = NULL;
+                       ERRCHK(tl);
+                       Fh(tl, 0, ",\n");
+               } else {
+                       vcc_ErrToken(tl, t_field);
+                       vcc_ErrWhere(tl, t_field);
+                       ErrInternal(tl);
+                       return;
+               }
+
+               ExpectErr(tl, ';');
+               vcc_NextToken(tl);
+       }
+       Fh(tl, 0, "\t},\n");
+       ExpectErr(tl, '}');
+       vcc_NextToken(tl);
+}
+
 /*--------------------------------------------------------------------
  * Parse and emit a backend host definition 
  *
@@ -244,7 +327,8 @@ vcc_ParseHostDef(struct tokenlist *tl, int *nbh, const struct token *name, const
        const char *ep;
        struct fld_spec *fs;
 
-       fs = vcc_FldSpec(tl, "!host", "?port", "?connect_timeout", NULL);
+       fs = vcc_FldSpec(tl,
+           "!host", "?port", "?connect_timeout", "?probe", NULL);
        t_first = tl->t;
 
        ExpectErr(tl, '{');
@@ -276,11 +360,15 @@ vcc_ParseHostDef(struct tokenlist *tl, int *nbh, const struct token *name, const
                        assert(tl->t->dec != NULL);
                        t_host = tl->t;
                        vcc_NextToken(tl);
+                       ExpectErr(tl, ';');
+                       vcc_NextToken(tl);
                } else if (vcc_IdIs(t_field, "port")) {
                        ExpectErr(tl, CSTR);
                        assert(tl->t->dec != NULL);
                        t_port = tl->t;
                        vcc_NextToken(tl);
+                       ExpectErr(tl, ';');
+                       vcc_NextToken(tl);
                } else if (vcc_IdIs(t_field, "connect_timeout")) {
                        Fh(tl, 0, "\t.connect_timeout = ");
                        tl->fb = tl->fh;
@@ -288,13 +376,16 @@ vcc_ParseHostDef(struct tokenlist *tl, int *nbh, const struct token *name, const
                        tl->fb = NULL;
                        ERRCHK(tl);
                        Fh(tl, 0, ",\n");
+                       ExpectErr(tl, ';');
+                       vcc_NextToken(tl);
+               } else if (vcc_IdIs(t_field, "probe")) {
+                       vcc_ParseProbe(tl);
+                       ERRCHK(tl);
                } else {
                        ErrInternal(tl);
                        return;
                }
 
-               ExpectErr(tl, ';');
-               vcc_NextToken(tl);
        }
 
        vcc_FieldsOk(tl, fs);
index 85b715f1292688fbd4d6edb5b52ef4a993cc13dd..da89ee4b287c63d28071149570c479e54e094cbc 100644 (file)
@@ -380,14 +380,24 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, "struct sockaddr;\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "/*\n");
+       vsb_cat(sb, " * A backend probe specification\n");
+       vsb_cat(sb, " */\n");
+       vsb_cat(sb, "\n");
+       vsb_cat(sb, "struct vrt_backend_probe {\n");
+       vsb_cat(sb, "   char            *request;\n");
+       vsb_cat(sb, "   double          timeout;\n");
+       vsb_cat(sb, "};\n");
+       vsb_cat(sb, "\n");
+       vsb_cat(sb, "/*\n");
        vsb_cat(sb, " * A backend is a host+port somewhere on the network\n");
        vsb_cat(sb, " */\n");
        vsb_cat(sb, "struct vrt_backend {\n");
-       vsb_cat(sb, "   char            *portname;\n");
-       vsb_cat(sb, "   char            *hostname;\n");
-       vsb_cat(sb, "   char            *vcl_name;\n");
-       vsb_cat(sb, "   char            *ident;\n");
-       vsb_cat(sb, "   double          connect_timeout;\n");
+       vsb_cat(sb, "   char                            *portname;\n");
+       vsb_cat(sb, "   char                            *hostname;\n");
+       vsb_cat(sb, "   char                            *vcl_name;\n");
+       vsb_cat(sb, "   char                            *ident;\n");
+       vsb_cat(sb, "   double                          connect_timeout;\n");
+       vsb_cat(sb, "   struct vrt_backend_probe        probe;\n");
        vsb_cat(sb, "};\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "/*\n");