Commit 3e610dc8 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Complete the separation of synthetic from received objects.

	Any object, also errors, we receive from the backend will
	go to vcl_fetch(), and can be cached if desired.

	Any object we create, for instance if we cannot contact the
	backend, will go to vcl_error() and will not be cached.

Technical details:

	Implement VCL variable setting for booleans like obj.cacheable.

	Remove obj.valid, only valid objects go to vcl_fetch now.

	On fetch failure, drop the object and go to STP_ERROR with 503

	Update testcase b00015.vtc accordingly.



git-svn-id: http://www.varnish-cache.org/svn/trunk@3044 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 42514e41
......@@ -258,7 +258,6 @@ struct object {
unsigned response;
unsigned valid;
unsigned cacheable;
unsigned busy;
......
......@@ -162,11 +162,6 @@ cnt_deliver(struct sess *sp)
switch (sp->handling) {
case VCL_RET_DELIVER:
break;
case VCL_RET_ERROR:
HSH_Deref(sp->obj);
sp->obj = NULL;
sp->step = STP_ERROR;
return (0);
default:
INCOMPL();
}
......@@ -316,6 +311,8 @@ cnt_error(struct sess *sp)
if (sp->obj == NULL) {
HSH_Prealloc(sp);
sp->obj = sp->wrk->nobj;
sp->obj->xid = sp->xid;
sp->obj->entered = sp->t_req;
sp->wrk->nobj = NULL;
} else {
/* XXX: Null the headers ? */
......@@ -384,15 +381,22 @@ cnt_fetch(struct sess *sp)
i = Fetch(sp);
CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
if (!i)
RFC2616_cache_policy(sp, sp->obj->http); /* XXX -> VCL */
else {
http_PutStatus(sp->wrk, sp->fd, sp->obj->http, 503);
http_PutProtocol(sp->wrk, sp->fd, sp->obj->http, "HTTP/1.1");
http_PutResponse(sp->wrk, sp->fd, sp->obj->http,
"Backend error");
if (i) {
VSL(SLT_Debug, sp->fd, "Fetch = %d", i);
sp->err_code = 503;
sp->step = STP_ERROR;
VBE_free_bereq(sp->bereq);
sp->bereq = NULL;
sp->obj->ttl = 0;
sp->obj->cacheable = 0;
HSH_Unbusy(sp);
HSH_Deref(sp->obj);
sp->obj = NULL;
return (0);
}
RFC2616_cache_policy(sp, sp->obj->http); /* XXX -> VCL */
sp->err_code = http_GetStatus(sp->obj->http);
VCL_fetch_method(sp);
......
......@@ -413,7 +413,6 @@ VRT_r_obj_##onm(const struct sess *sp) \
return (sp->obj->field); \
}
VOBJ(unsigned, valid, valid)
VOBJ(unsigned, cacheable, cacheable)
/*--------------------------------------------------------------------*/
......
......@@ -135,9 +135,6 @@ static const char *default_vcl =
"}\n"
"\n"
"sub vcl_fetch {\n"
" if (!obj.valid) {\n"
" error obj.status;\n"
" }\n"
" if (!obj.cacheable) {\n"
" pass;\n"
" }\n"
......
......@@ -178,12 +178,10 @@ RFC2616_cache_policy(const struct sess *sp, const struct http *hp)
case 410: /* Gone */
case 404: /* Not Found */
sp->obj->cacheable = 1;
sp->obj->valid = 1;
body = 1;
break;
default:
sp->obj->cacheable = 0;
sp->obj->valid = 1; /* XXX ? */
body = 0;
break;
}
......
......@@ -2,19 +2,82 @@
test "Check synthetic error page caching"
# First test that an internally generated error is not cached
varnish v1 -vcl {
backend foo {
.host = "127.0.0.2";
}
} -start
client c1 {
txreq -url "/"
rxresp
expect resp.status == 503
expect resp.http.X-varnish == "1001"
} -run
client c1 {
txreq -url "/"
rxresp
expect resp.status == 503
expect resp.http.X-varnish == "1002"
} -run
# Then check that an cacheable error from the backend is
server s1 {
rxreq
txresp -status 503 -msg "Server Error"
txresp -status 302
} -start
varnish v1 -vcl+backend { } -start
varnish v1 -vcl+backend { }
client c1 {
txreq -url "/"
rxresp
expect resp.status == 503
# Disable this for now to not upset automatic scripts
#txreq -url "/"
#rxresp
#expect resp.status == 503
expect resp.status == 302
expect resp.http.X-varnish == "1003"
} -run
server s1 -wait
client c1 {
txreq -url "/"
rxresp
expect resp.status == 302
expect resp.http.X-varnish == "1004 1003"
} -run
# Then check that a non-cacheable error from the backend can be
server s1 {
rxreq
txresp -status 502
} -start
varnish v1 -vcl+backend {
sub vcl_fetch {
if (obj.status == 502) {
set obj.cacheable = true;
set obj.ttl = 10m;
}
}
}
client c1 {
txreq -url "/2"
rxresp
expect resp.status == 502
expect resp.http.X-varnish == "1005"
} -run
server s1 -wait
client c1 {
txreq -url "/2"
rxresp
expect resp.status == 502
expect resp.http.X-varnish == "1006 1005"
} -run
......@@ -34,8 +34,6 @@ int VRT_r_obj_status(const struct sess *);
void VRT_l_obj_status(const struct sess *, int);
const char * VRT_r_obj_response(const struct sess *);
void VRT_l_obj_response(const struct sess *, const char *, ...);
unsigned VRT_r_obj_valid(const struct sess *);
void VRT_l_obj_valid(const struct sess *, unsigned);
unsigned VRT_r_obj_cacheable(const struct sess *);
void VRT_l_obj_cacheable(const struct sess *, unsigned);
double VRT_r_obj_ttl(const struct sess *);
......
......@@ -280,9 +280,28 @@ parse_set(struct tokenlist *tl)
}
Fb(tl, 0, "vrt_magic_string_end);\n");
break;
case BOOL:
if (tl->t->tok != '=') {
illegal_assignment(tl, "boolean");
return;
}
vcc_NextToken(tl);
ExpectErr(tl, ID);
if (vcc_IdIs(tl->t, "true")) {
Fb(tl, 0, " 1);\n", vp->lname);
} else if (vcc_IdIs(tl->t, "false")) {
Fb(tl, 0, " 0);\n", vp->lname);
} else {
vsb_printf(tl->sb,
"Expected true or false\n");
vcc_ErrWhere(tl, tl->t);
return;
}
vcc_NextToken(tl);
break;
default:
vsb_printf(tl->sb,
"Assignments not possible for '%s'\n", vp->name);
"Assignments not possible for type of '%s'\n", vp->name);
vcc_ErrWhere(tl, tl->t);
return;
}
......
......@@ -150,11 +150,6 @@ set spobj {
"const struct sess *"
}
{ obj.valid
RW BOOL
{ hit fetch discard timeout error}
"const struct sess *"
}
{ obj.cacheable
RW BOOL
{ hit fetch discard timeout error}
......
......@@ -151,13 +151,6 @@ struct var vcc_vars[] = {
"HDR_OBJ",
VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_ERROR
},
{ "obj.valid", BOOL, 9,
"VRT_r_obj_valid(sp)",
"VRT_l_obj_valid(sp, ",
V_RW,
0,
VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DISCARD | VCL_MET_TIMEOUT | VCL_MET_ERROR
},
{ "obj.cacheable", BOOL, 13,
"VRT_r_obj_cacheable(sp)",
"VRT_l_obj_cacheable(sp, ",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment