Commit 4c28ffc7 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/varnish-cache@3044 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent a7f2f1d6
...@@ -258,7 +258,6 @@ struct object { ...@@ -258,7 +258,6 @@ struct object {
unsigned response; unsigned response;
unsigned valid;
unsigned cacheable; unsigned cacheable;
unsigned busy; unsigned busy;
......
...@@ -162,11 +162,6 @@ cnt_deliver(struct sess *sp) ...@@ -162,11 +162,6 @@ cnt_deliver(struct sess *sp)
switch (sp->handling) { switch (sp->handling) {
case VCL_RET_DELIVER: case VCL_RET_DELIVER:
break; break;
case VCL_RET_ERROR:
HSH_Deref(sp->obj);
sp->obj = NULL;
sp->step = STP_ERROR;
return (0);
default: default:
INCOMPL(); INCOMPL();
} }
...@@ -316,6 +311,8 @@ cnt_error(struct sess *sp) ...@@ -316,6 +311,8 @@ cnt_error(struct sess *sp)
if (sp->obj == NULL) { if (sp->obj == NULL) {
HSH_Prealloc(sp); HSH_Prealloc(sp);
sp->obj = sp->wrk->nobj; sp->obj = sp->wrk->nobj;
sp->obj->xid = sp->xid;
sp->obj->entered = sp->t_req;
sp->wrk->nobj = NULL; sp->wrk->nobj = NULL;
} else { } else {
/* XXX: Null the headers ? */ /* XXX: Null the headers ? */
...@@ -384,15 +381,22 @@ cnt_fetch(struct sess *sp) ...@@ -384,15 +381,22 @@ cnt_fetch(struct sess *sp)
i = Fetch(sp); i = Fetch(sp);
CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC); CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
if (!i) if (i) {
RFC2616_cache_policy(sp, sp->obj->http); /* XXX -> VCL */ VSL(SLT_Debug, sp->fd, "Fetch = %d", i);
else { sp->err_code = 503;
http_PutStatus(sp->wrk, sp->fd, sp->obj->http, 503); sp->step = STP_ERROR;
http_PutProtocol(sp->wrk, sp->fd, sp->obj->http, "HTTP/1.1"); VBE_free_bereq(sp->bereq);
http_PutResponse(sp->wrk, sp->fd, sp->obj->http, sp->bereq = NULL;
"Backend error"); 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); sp->err_code = http_GetStatus(sp->obj->http);
VCL_fetch_method(sp); VCL_fetch_method(sp);
......
...@@ -413,7 +413,6 @@ VRT_r_obj_##onm(const struct sess *sp) \ ...@@ -413,7 +413,6 @@ VRT_r_obj_##onm(const struct sess *sp) \
return (sp->obj->field); \ return (sp->obj->field); \
} }
VOBJ(unsigned, valid, valid)
VOBJ(unsigned, cacheable, cacheable) VOBJ(unsigned, cacheable, cacheable)
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
......
...@@ -135,9 +135,6 @@ static const char *default_vcl = ...@@ -135,9 +135,6 @@ static const char *default_vcl =
"}\n" "}\n"
"\n" "\n"
"sub vcl_fetch {\n" "sub vcl_fetch {\n"
" if (!obj.valid) {\n"
" error obj.status;\n"
" }\n"
" if (!obj.cacheable) {\n" " if (!obj.cacheable) {\n"
" pass;\n" " pass;\n"
" }\n" " }\n"
......
...@@ -178,12 +178,10 @@ RFC2616_cache_policy(const struct sess *sp, const struct http *hp) ...@@ -178,12 +178,10 @@ RFC2616_cache_policy(const struct sess *sp, const struct http *hp)
case 410: /* Gone */ case 410: /* Gone */
case 404: /* Not Found */ case 404: /* Not Found */
sp->obj->cacheable = 1; sp->obj->cacheable = 1;
sp->obj->valid = 1;
body = 1; body = 1;
break; break;
default: default:
sp->obj->cacheable = 0; sp->obj->cacheable = 0;
sp->obj->valid = 1; /* XXX ? */
body = 0; body = 0;
break; break;
} }
......
...@@ -2,19 +2,82 @@ ...@@ -2,19 +2,82 @@
test "Check synthetic error page caching" 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 { server s1 {
rxreq rxreq
txresp -status 503 -msg "Server Error" txresp -status 302
} -start } -start
varnish v1 -vcl+backend { } -start varnish v1 -vcl+backend { }
client c1 { client c1 {
txreq -url "/" txreq -url "/"
rxresp rxresp
expect resp.status == 503 expect resp.status == 302
# Disable this for now to not upset automatic scripts expect resp.http.X-varnish == "1003"
#txreq -url "/" } -run
#rxresp
#expect resp.status == 503 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 } -run
...@@ -34,8 +34,6 @@ int VRT_r_obj_status(const struct sess *); ...@@ -34,8 +34,6 @@ int VRT_r_obj_status(const struct sess *);
void VRT_l_obj_status(const struct sess *, int); void VRT_l_obj_status(const struct sess *, int);
const char * VRT_r_obj_response(const struct sess *); const char * VRT_r_obj_response(const struct sess *);
void VRT_l_obj_response(const struct sess *, const char *, ...); 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 *); unsigned VRT_r_obj_cacheable(const struct sess *);
void VRT_l_obj_cacheable(const struct sess *, unsigned); void VRT_l_obj_cacheable(const struct sess *, unsigned);
double VRT_r_obj_ttl(const struct sess *); double VRT_r_obj_ttl(const struct sess *);
......
...@@ -280,9 +280,28 @@ parse_set(struct tokenlist *tl) ...@@ -280,9 +280,28 @@ parse_set(struct tokenlist *tl)
} }
Fb(tl, 0, "vrt_magic_string_end);\n"); Fb(tl, 0, "vrt_magic_string_end);\n");
break; 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: default:
vsb_printf(tl->sb, 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); vcc_ErrWhere(tl, tl->t);
return; return;
} }
......
...@@ -150,11 +150,6 @@ set spobj { ...@@ -150,11 +150,6 @@ set spobj {
"const struct sess *" "const struct sess *"
} }
{ obj.valid
RW BOOL
{ hit fetch discard timeout error}
"const struct sess *"
}
{ obj.cacheable { obj.cacheable
RW BOOL RW BOOL
{ hit fetch discard timeout error} { hit fetch discard timeout error}
......
...@@ -151,13 +151,6 @@ struct var vcc_vars[] = { ...@@ -151,13 +151,6 @@ struct var vcc_vars[] = {
"HDR_OBJ", "HDR_OBJ",
VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_ERROR 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, { "obj.cacheable", BOOL, 13,
"VRT_r_obj_cacheable(sp)", "VRT_r_obj_cacheable(sp)",
"VRT_l_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