From 860750d3bc8216d6fd0d801477528ef419b32aec Mon Sep 17 00:00:00 2001 From: phk Date: Fri, 27 Feb 2009 15:20:57 +0000 Subject: [PATCH] TIMBER! Move the vcl_fetch{} execution up between fetching the headers and the body of the backend response. This makes obj.* unavailable in vcl_fetch{} and replaces it with a new beresp.* family of variables. This paves the way for a lot of good stuff, such as streaming pass, on-the-fly delivery of misses, storage selection based on headers etc. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@3838 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache.h | 12 ++- varnish-cache/bin/varnishd/cache_backend.c | 8 +- varnish-cache/bin/varnishd/cache_center.c | 81 ++++++++++++-- varnish-cache/bin/varnishd/cache_fetch.c | 27 ++--- varnish-cache/bin/varnishd/cache_http.c | 2 +- varnish-cache/bin/varnishd/cache_pipe.c | 2 +- varnish-cache/bin/varnishd/cache_vrt.c | 100 +++++++++++++++++- varnish-cache/bin/varnishd/cache_vrt_esi.c | 23 ++-- varnish-cache/bin/varnishd/default.vcl | 4 +- varnish-cache/bin/varnishd/rfc2616.c | 69 +++--------- .../bin/varnishtest/tests/b00015.vtc | 6 +- .../bin/varnishtest/tests/b00018.vtc | 2 +- .../bin/varnishtest/tests/b00028.vtc | 14 ++- .../bin/varnishtest/tests/c00001.vtc | 22 ++-- .../bin/varnishtest/tests/c00009.vtc | 2 +- .../bin/varnishtest/tests/r00251.vtc | 4 +- .../bin/varnishtest/tests/r00412.vtc | 10 +- .../bin/varnishtest/tests/v00000.vtc | 4 +- .../bin/varnishtest/tests/v00001.vtc | 10 +- .../bin/varnishtest/tests/v00010.vtc | 4 +- .../bin/varnishtest/tests/v00016.vtc | 8 +- .../bin/varnishtest/tests/v00018.vtc | 16 +-- .../bin/varnishtest/tests/v00020.vtc | 2 +- varnish-cache/include/vrt_obj.h | 14 ++- varnish-cache/lib/libvcl/vcc_fixed_token.c | 50 +++++---- varnish-cache/lib/libvcl/vcc_gen_obj.tcl | 46 +++++--- varnish-cache/lib/libvcl/vcc_obj.c | 55 ++++++---- 27 files changed, 383 insertions(+), 214 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 3aeeaa24..deb98faf 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -242,8 +242,15 @@ struct bereq { #define BEREQ_MAGIC 0x3b6d250c VTAILQ_ENTRY(bereq) list; struct ws ws[1]; - struct http http[2]; + struct http bereq[1]; + struct http beresp[2]; struct http_conn htc[1]; + unsigned cacheable; + double age; + double entered; + double ttl; + double grace; + unsigned do_esi; }; /* Storage -----------------------------------------------------------*/ @@ -639,6 +646,7 @@ void VCL_Poll(void); void ESI_Deliver(struct sess *); void ESI_Destroy(struct object *); +void ESI_Parse(struct sess *); /* cache_ws.c */ @@ -654,7 +662,7 @@ char *WS_Snapshot(struct ws *ws); unsigned WS_Free(const struct ws *ws); /* rfc2616.c */ -int RFC2616_cache_policy(const struct sess *sp, const struct http *hp); +double RFC2616_Ttl(const struct sess *sp); /* storage_synth.c */ struct vsb *SMS_Makesynth(struct object *obj); diff --git a/varnish-cache/bin/varnishd/cache_backend.c b/varnish-cache/bin/varnishd/cache_backend.c index 3637fedd..44e16012 100644 --- a/varnish-cache/bin/varnishd/cache_backend.c +++ b/varnish-cache/bin/varnishd/cache_backend.c @@ -65,10 +65,10 @@ VBE_AddHostHeader(const struct sess *sp) CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC); - CHECK_OBJ_NOTNULL(sp->bereq->http, HTTP_MAGIC); + CHECK_OBJ_NOTNULL(sp->bereq->bereq, HTTP_MAGIC); CHECK_OBJ_NOTNULL(sp->vbe, VBE_CONN_MAGIC); CHECK_OBJ_NOTNULL(sp->vbe->backend, BACKEND_MAGIC); - http_PrintfHeader(sp->wrk, sp->fd, sp->bereq->http, + http_PrintfHeader(sp->wrk, sp->fd, sp->bereq->bereq, "Host: %s", sp->vbe->backend->hosthdr); } @@ -163,8 +163,8 @@ VBE_new_bereq(void) WS_Init(bereq->ws, "bereq", bereq + 1, len); VSL_stats->n_bereq++; } - http_Setup(&bereq->http[0], bereq->ws); - http_Setup(&bereq->http[1], bereq->ws); + http_Setup(bereq->bereq, bereq->ws); + http_Setup(bereq->beresp, bereq->ws); return (bereq); } diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index e0484750..2e23fc8a 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -378,6 +378,8 @@ static int cnt_fetch(struct sess *sp) { int i; + struct http *hp, *hp2; + char *b; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); @@ -388,10 +390,79 @@ cnt_fetch(struct sess *sp) sp->obj->xid = sp->xid; WS_Assert(sp->obj->ws_o); + i = FetchHdr(sp); + + /* + * Save a copy before it might get mangled in VCL. When it comes to + * dealing with the body, we want to see the unadultered headers. + */ + sp->bereq->beresp[1] = sp->bereq->beresp[0]; + + if (i) { + sp->err_code = 503; + sp->step = STP_ERROR; + VBE_free_bereq(&sp->bereq); + HSH_Drop(sp); + AZ(sp->obj); + return (0); + } + + sp->err_code = http_GetStatus(sp->bereq->beresp); + + /* + * Initial cacheability determination per [RFC2616, 13.4] + * We do not support ranges yet, so 206 is out. + */ + switch (sp->err_code) { + case 200: /* OK */ + case 203: /* Non-Authoritative Information */ + case 300: /* Multiple Choices */ + case 301: /* Moved Permanently */ + case 302: /* Moved Temporarily */ + case 410: /* Gone */ + case 404: /* Not Found */ + sp->bereq->cacheable = 1; + break; + default: + sp->bereq->cacheable = 0; + break; + } + + sp->bereq->entered = TIM_real(); + sp->bereq->age = 0; + sp->bereq->ttl = RFC2616_Ttl(sp); + + if (sp->bereq->ttl == 0.) + sp->bereq->cacheable = 0; + + sp->bereq->do_esi = 0; + sp->bereq->grace = NAN; + + VCL_fetch_method(sp); + + sp->obj->response = sp->err_code; + sp->obj->cacheable = sp->bereq->cacheable; + sp->obj->ttl = sp->bereq->ttl; + sp->obj->grace = sp->bereq->grace; + if (sp->obj->ttl == 0.) + sp->obj->cacheable = 0; + sp->obj->age = sp->bereq->age; + sp->obj->entered = sp->bereq->entered; + + /* Filter into object */ + hp = sp->bereq->beresp; + hp2 = sp->obj->http; + + hp2->logtag = HTTP_Obj; + http_CopyResp(hp2, hp); + http_FilterFields(sp->wrk, sp->fd, hp2, hp, HTTPH_A_INS); + http_CopyHome(sp->wrk, sp->fd, hp2); + + if (http_GetHdr(hp, H_Last_Modified, &b)) + sp->obj->last_modified = TIM_parse(b); - if (i == 0) - i = FetchBody(sp); + i = FetchBody(sp); AZ(sp->wrk->wfd); AZ(sp->vbe); AN(sp->director); @@ -405,10 +476,8 @@ cnt_fetch(struct sess *sp) return (0); } - RFC2616_cache_policy(sp, sp->obj->http); /* XXX -> VCL */ - - sp->err_code = http_GetStatus(sp->obj->http); - VCL_fetch_method(sp); + if (sp->bereq->do_esi) + ESI_Parse(sp); VBE_free_bereq(&sp->bereq); diff --git a/varnish-cache/bin/varnishd/cache_fetch.c b/varnish-cache/bin/varnishd/cache_fetch.c index ef50042c..29900651 100644 --- a/varnish-cache/bin/varnishd/cache_fetch.c +++ b/varnish-cache/bin/varnishd/cache_fetch.c @@ -330,7 +330,7 @@ FetchHdr(struct sess *sp) w = sp->wrk; bereq = sp->bereq; - hp = &bereq->http[0]; + hp = bereq->bereq; VBE_GetFd(sp); if (sp->vbe == NULL) @@ -381,7 +381,7 @@ FetchHdr(struct sess *sp) return (__LINE__); } - hp = &bereq->http[1]; + hp = bereq->beresp; if (http_DissectResponse(sp->wrk, bereq->htc, hp)) { VBE_ClosedFd(sp); @@ -399,15 +399,18 @@ FetchBody(struct sess *sp) struct vbe_conn *vc; char *b; int cls; - struct http *hp, *hp2; + struct http *hp; struct storage *st; int mklen, is_head; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); + CHECK_OBJ_NOTNULL(sp->obj->http, HTTP_MAGIC); CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC); - hp = &sp->bereq->http[1]; + + /* We use the unmodified headers */ + hp = &sp->bereq->beresp[1]; AN(sp->director); if (sp->obj->objcore != NULL) /* pass has no objcore */ AN(ObjIsBusy(sp->obj)); @@ -415,19 +418,7 @@ FetchBody(struct sess *sp) vc = sp->vbe; - sp->obj->entered = TIM_real(); - is_head = (strcasecmp(http_GetReq(&sp->bereq->http[0]), "head") == 0); - - if (http_GetHdr(hp, H_Last_Modified, &b)) - sp->obj->last_modified = TIM_parse(b); - - /* Filter into object */ - hp2 = sp->obj->http; - - hp2->logtag = HTTP_Obj; - http_CopyResp(hp2, hp); - http_FilterFields(sp->wrk, sp->fd, hp2, hp, HTTPH_A_INS); - http_CopyHome(sp->wrk, sp->fd, hp2); + is_head = (strcasecmp(http_GetReq(sp->bereq->bereq), "head") == 0); /* Determine if we have a body or not */ cls = 0; @@ -495,7 +486,7 @@ FetchBody(struct sess *sp) } if (mklen > 0) - http_PrintfHeader(sp->wrk, sp->fd, hp2, + http_PrintfHeader(sp->wrk, sp->fd, sp->obj->http, "Content-Length: %u", sp->obj->len); if (http_HdrIs(hp, H_Connection, "close")) diff --git a/varnish-cache/bin/varnishd/cache_http.c b/varnish-cache/bin/varnishd/cache_http.c index f83da384..0edade0d 100644 --- a/varnish-cache/bin/varnishd/cache_http.c +++ b/varnish-cache/bin/varnishd/cache_http.c @@ -637,7 +637,7 @@ http_FilterHeader(struct sess *sp, unsigned how) AZ(sp->bereq); bereq = VBE_new_bereq(); AN(bereq); - hp = bereq->http; + hp = bereq->bereq; hp->logtag = HTTP_Tx; http_copyreq(hp, sp->http, how); diff --git a/varnish-cache/bin/varnishd/cache_pipe.c b/varnish-cache/bin/varnishd/cache_pipe.c index eb725a3c..a74ca958 100644 --- a/varnish-cache/bin/varnishd/cache_pipe.c +++ b/varnish-cache/bin/varnishd/cache_pipe.c @@ -84,7 +84,7 @@ PipeSession(struct sess *sp) TCP_blocking(vc->fd); WRW_Reserve(w, &vc->fd); - sp->acct_req.hdrbytes += http_Write(w, bereq->http, 0); + sp->acct_req.hdrbytes += http_Write(w, bereq->bereq, 0); if (sp->htc->pipeline.b != NULL) sp->acct_req.bodybytes += diff --git a/varnish-cache/bin/varnishd/cache_vrt.c b/varnish-cache/bin/varnishd/cache_vrt.c index d4a5a8e2..20be6e35 100644 --- a/varnish-cache/bin/varnishd/cache_vrt.c +++ b/varnish-cache/bin/varnishd/cache_vrt.c @@ -100,10 +100,10 @@ vrt_selecthttp(const struct sess *sp, enum gethdr_e where) hp = sp->http; break; case HDR_BEREQ: - hp = &sp->bereq->http[0]; + hp = sp->bereq->bereq; break; case HDR_BERESP: - hp = &sp->bereq->http[1]; + hp = sp->bereq->beresp; break; case HDR_RESP: hp = sp->http; @@ -243,13 +243,15 @@ VRT_r_##obj##_##hdr(const struct sess *sp) \ VRT_DO_HDR(req, request, sp->http, HTTP_HDR_REQ) VRT_DO_HDR(req, url, sp->http, HTTP_HDR_URL) VRT_DO_HDR(req, proto, sp->http, HTTP_HDR_PROTO) -VRT_DO_HDR(bereq, request, sp->bereq->http, HTTP_HDR_REQ) -VRT_DO_HDR(bereq, url, sp->bereq->http, HTTP_HDR_URL) -VRT_DO_HDR(bereq, proto, sp->bereq->http, HTTP_HDR_PROTO) +VRT_DO_HDR(bereq, request, sp->bereq->bereq, HTTP_HDR_REQ) +VRT_DO_HDR(bereq, url, sp->bereq->bereq, HTTP_HDR_URL) +VRT_DO_HDR(bereq, proto, sp->bereq->bereq, HTTP_HDR_PROTO) VRT_DO_HDR(obj, proto, sp->obj->http, HTTP_HDR_PROTO) VRT_DO_HDR(obj, response, sp->obj->http, HTTP_HDR_RESPONSE) VRT_DO_HDR(resp, proto, sp->http, HTTP_HDR_PROTO) VRT_DO_HDR(resp, response, sp->http, HTTP_HDR_RESPONSE) +VRT_DO_HDR(beresp, proto, sp->bereq->beresp, HTTP_HDR_PROTO) +VRT_DO_HDR(beresp, response, sp->bereq->beresp, HTTP_HDR_RESPONSE) /*--------------------------------------------------------------------*/ @@ -277,6 +279,7 @@ VRT_r_obj_status(const struct sess *sp) /* XXX: use http_GetStatus() */ if (sp->obj->http->status) return (sp->obj->http->status); + AN(sp->obj->http->hd[HTTP_HDR_STATUS].b); return (atoi(sp->obj->http->hd[HTTP_HDR_STATUS].b)); } @@ -302,6 +305,93 @@ VRT_r_resp_status(const struct sess *sp) return (atoi(sp->http->hd[HTTP_HDR_STATUS].b)); } +/*--------------------------------------------------------------------*/ + +#define VBEREQ(dir, type,onm,field) \ +void \ +VRT_l_##dir##_##onm(const struct sess *sp, type a) \ +{ \ + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \ + CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC); /* XXX */ \ + sp->bereq->field = a; \ +} \ + \ +type \ +VRT_r_##dir##_##onm(const struct sess *sp) \ +{ \ + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \ + CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC); /* XXX */ \ + return (sp->bereq->field); \ +} + +VBEREQ(beresp, unsigned, cacheable, cacheable) +VBEREQ(beresp, double, grace, grace) + +/*-------------------------------------------------------------------- + * XXX: Working relative to t_req is maybe not the right thing, we could + * XXX: have spent a long time talking to the backend since then. + * XXX: It might make sense to cache a timestamp as "current time" + * XXX: before vcl_recv (== t_req) and vcl_fetch. + * XXX: On the other hand, that might lead to inconsistent behaviour + * XXX: where an object expires while we are running VCL code, and + * XXX: and that may not be a good idea either. + * XXX: See also related t_req use in cache_hash.c + */ + +void +VRT_l_beresp_ttl(const struct sess *sp, double a) +{ + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC); /* XXX */ + WSP(sp, SLT_TTL, "%u VCL %.0f %.0f", sp->xid, a, sp->t_req); + /* + * If people set obj.ttl = 0s, they don't expect it to be cacheable + * any longer, but it will still be for up to 1s - epsilon because + * of the rounding to seconds. + * We special case and make sure that rounding does not surprise. + */ + if (a <= 0) + sp->bereq->ttl = sp->t_req - 1; + else + sp->bereq->ttl = sp->t_req + a; +} + +double +VRT_r_beresp_ttl(const struct sess *sp) +{ + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC); /* XXX */ + return (sp->bereq->ttl - sp->t_req); +} + +void +VRT_l_beresp_status(const struct sess *sp, int num) +{ + char *p; + + assert(num >= 100 && num <= 999); + p = WS_Alloc(sp->obj->http->ws, 4); + if (p == NULL) + WSP(sp, SLT_LostHeader, "%s", "obj.status"); + else + sprintf(p, "%d", num); + http_SetH(sp->bereq->beresp, HTTP_HDR_STATUS, p); +} + +int +VRT_r_beresp_status(const struct sess *sp) +{ + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC); + /* XXX: use http_GetStatus() */ + if (sp->bereq->beresp->status) + return (sp->bereq->beresp->status); + AN(sp->bereq->beresp->hd[HTTP_HDR_STATUS].b); + return (atoi(sp->bereq->beresp->hd[HTTP_HDR_STATUS].b)); +} + + void VRT_l_bereq_connect_timeout(struct sess *sp, double num) { diff --git a/varnish-cache/bin/varnishd/cache_vrt_esi.c b/varnish-cache/bin/varnishd/cache_vrt_esi.c index b6af0a35..7bf3c935 100644 --- a/varnish-cache/bin/varnishd/cache_vrt_esi.c +++ b/varnish-cache/bin/varnishd/cache_vrt_esi.c @@ -398,8 +398,8 @@ esi_handle_include(struct esi_work *ew) */ CHECK_OBJ_NOTNULL(ew->sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(ew->sp->bereq, BEREQ_MAGIC); - CHECK_OBJ_NOTNULL(ew->sp->bereq->http, HTTP_MAGIC); - tag = ew->sp->bereq->http->hd[HTTP_HDR_URL]; + CHECK_OBJ_NOTNULL(ew->sp->bereq->bereq, HTTP_MAGIC); + tag = ew->sp->bereq->bereq->hd[HTTP_HDR_URL]; /* Use the objects WS to store the result */ CHECK_OBJ_NOTNULL(ew->sp->obj, OBJECT_MAGIC); @@ -639,12 +639,8 @@ parse_esi_tag(struct esi_work *ew, int closing) void VRT_ESI(struct sess *sp) { - struct esi_work *ew, eww[1]; + CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC); - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); - if (sp->obj->objcore != NULL) /* Pass has no objcore */ - AN(ObjIsBusy(sp->obj)); if (sp->cur_method != VCL_MET_FETCH) { /* XXX: we should catch this at compile time */ WSP(sp, SLT_VCL_error, @@ -652,6 +648,19 @@ VRT_ESI(struct sess *sp) return; } + sp->bereq->do_esi = 1; +} + + +void +ESI_Parse(struct sess *sp) +{ + struct esi_work *ew, eww[1]; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); + if (sp->obj->objcore != NULL) /* Pass has no objcore */ + AN(ObjIsBusy(sp->obj)); if (VTAILQ_EMPTY(&sp->obj->store)) return; diff --git a/varnish-cache/bin/varnishd/default.vcl b/varnish-cache/bin/varnishd/default.vcl index dcf144ac..048a5f99 100644 --- a/varnish-cache/bin/varnishd/default.vcl +++ b/varnish-cache/bin/varnishd/default.vcl @@ -91,10 +91,10 @@ sub vcl_miss { } sub vcl_fetch { - if (!obj.cacheable) { + if (!beresp.cacheable) { return (pass); } - if (obj.http.Set-Cookie) { + if (beresp.http.Set-Cookie) { return (pass); } return (deliver); diff --git a/varnish-cache/bin/varnishd/rfc2616.c b/varnish-cache/bin/varnishd/rfc2616.c index 66c63ab1..dc1312f4 100644 --- a/varnish-cache/bin/varnishd/rfc2616.c +++ b/varnish-cache/bin/varnishd/rfc2616.c @@ -68,15 +68,19 @@ * */ -static double -RFC2616_Ttl(const struct sess *sp, const struct http *hp, struct object *obj) +double +RFC2616_Ttl(const struct sess *sp) { int ttl; unsigned max_age, age; double h_date, h_expires, ttd; char *p; + const struct http *hp; - assert(obj->entered != 0.0 && !isnan(sp->obj->entered)); + CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC); + hp = sp->bereq->beresp; + + assert(sp->bereq->entered != 0.0 && !isnan(sp->bereq->entered)); /* If all else fails, cache using default ttl */ ttl = params->default_ttl; @@ -99,7 +103,7 @@ RFC2616_Ttl(const struct sess *sp, const struct http *hp, struct object *obj) max_age = strtoul(p, NULL, 0); if (http_GetHdr(hp, H_Age, &p)) { age = strtoul(p, NULL, 0); - obj->age = age; + sp->bereq->age = age; } if (age > max_age) @@ -126,14 +130,14 @@ RFC2616_Ttl(const struct sess *sp, const struct http *hp, struct object *obj) } if (h_date == 0 || - (h_date < obj->entered + params->clock_skew && - h_date + params->clock_skew > obj->entered)) { + (h_date < sp->bereq->entered + params->clock_skew && + h_date + params->clock_skew > sp->bereq->entered)) { /* * If we have no Date: header or if it is * sufficiently close to our clock we will * trust Expires: relative to our own clock. */ - if (h_expires < obj->entered) + if (h_expires < sp->bereq->entered) ttl = 0; else ttd = h_expires; @@ -150,58 +154,13 @@ RFC2616_Ttl(const struct sess *sp, const struct http *hp, struct object *obj) } while (0); if (ttl > 0 && ttd == 0) - ttd = obj->entered + ttl; + ttd = sp->bereq->entered + ttl; /* calculated TTL, Our time, Date, Expires, max-age, age */ WSP(sp, SLT_TTL, "%u RFC %d %d %d %d %u %u", sp->xid, - ttd ? (int)(ttd - obj->entered) : 0, - (int)obj->entered, (int)h_date, + ttd ? (int)(ttd - sp->bereq->entered) : 0, + (int)sp->bereq->entered, (int)h_date, (int)h_expires, max_age, age); return (ttd); } - -/* - * We could move this policy to vcl_fetch{} now but I have decided to leave - * it here for the POLA principle. It is not credible to think that a - * majority of our uses will change the cacheability decision, so moving - * it to VCL would just make the average and median vcl_fetch{} implementation - * harder for people to write. Instead the minority who want to override - * the RFC2616 mandated behaviour, can do so in their vcl_fetch{} - */ -int -RFC2616_cache_policy(const struct sess *sp, const struct http *hp) -{ - int body = 0; - double ttl; - - /* - * Initial cacheability determination per [RFC2616, 13.4] - * We do not support ranges yet, so 206 is out. - */ - sp->obj->response = http_GetStatus(hp); - switch (sp->obj->response) { - case 200: /* OK */ - case 203: /* Non-Authoritative Information */ - case 300: /* Multiple Choices */ - case 301: /* Moved Permanently */ - case 302: /* Moved Temporarily */ - case 410: /* Gone */ - case 404: /* Not Found */ - sp->obj->cacheable = 1; - body = 1; - break; - default: - sp->obj->cacheable = 0; - body = 0; - break; - } - - ttl = RFC2616_Ttl(sp, hp, sp->obj); - sp->obj->ttl = ttl; - if (ttl == 0) - sp->obj->cacheable = 0; - - return (body); -} - diff --git a/varnish-cache/bin/varnishtest/tests/b00015.vtc b/varnish-cache/bin/varnishtest/tests/b00015.vtc index a131a960..6d5c608c 100644 --- a/varnish-cache/bin/varnishtest/tests/b00015.vtc +++ b/varnish-cache/bin/varnishtest/tests/b00015.vtc @@ -57,9 +57,9 @@ server s1 { varnish v1 -vcl+backend { sub vcl_fetch { - if (obj.status == 502) { - set obj.cacheable = true; - set obj.ttl = 10m; + if (beresp.status == 502) { + set beresp.cacheable = true; + set beresp.ttl = 10m; } } } diff --git a/varnish-cache/bin/varnishtest/tests/b00018.vtc b/varnish-cache/bin/varnishtest/tests/b00018.vtc index 3ff45f64..24329ef9 100644 --- a/varnish-cache/bin/varnishtest/tests/b00018.vtc +++ b/varnish-cache/bin/varnishtest/tests/b00018.vtc @@ -9,7 +9,7 @@ server s1 { varnish v1 -vcl+backend { sub vcl_fetch { - set obj.http.Foo = "bar"; + set beresp.http.Foo = "bar"; error 523 "not ok"; } } -start diff --git a/varnish-cache/bin/varnishtest/tests/b00028.vtc b/varnish-cache/bin/varnishtest/tests/b00028.vtc index 95fd593d..85a8a01c 100644 --- a/varnish-cache/bin/varnishtest/tests/b00028.vtc +++ b/varnish-cache/bin/varnishtest/tests/b00028.vtc @@ -10,11 +10,15 @@ server s1 { varnish v1 -vcl+backend { sub vcl_fetch { - if (obj.http.foo ~ "bar") { - set obj.http.foo1 = "1"; + if (beresp.http.foo ~ "bar") { + set beresp.http.foo1 = "1"; + } else { + error 999; } - if (obj.http.bar !~ "bar") { - set obj.http.bar1 = "1"; + if (beresp.http.bar !~ "bar") { + set beresp.http.bar1 = "2"; + } else { + error 999; } } @@ -24,5 +28,5 @@ client c1 { txreq rxresp expect resp.http.foo1 == "1" - expect resp.http.bar1 == "1" + expect resp.http.bar1 == "2" } -run diff --git a/varnish-cache/bin/varnishtest/tests/c00001.vtc b/varnish-cache/bin/varnishtest/tests/c00001.vtc index ccbf6538..7c6f516b 100644 --- a/varnish-cache/bin/varnishtest/tests/c00001.vtc +++ b/varnish-cache/bin/varnishtest/tests/c00001.vtc @@ -12,17 +12,17 @@ server s1 { varnish v1 -vcl+backend { sub vcl_fetch { - set obj.http.Snafu1 = regsub(obj.http.Foobar, "ar", "\0\0"); - set obj.http.Snafu2 = - regsub(obj.http.Foobar, "(b)(a)(r)(f)", "\4\3\2p"); - set obj.http.Snafu3 = - regsub(obj.http.Foobar, "(b)(a)(r)(f)", "\4\\\3\2p"); - set obj.http.Snafu4 = - regsub(obj.http.Foobar, "(b)(a)(r)(f)", "\4\&\3\2p"); - set obj.http.Snafu5 = - regsub(obj.http.Foobar, "(b)(a)(r)(f)", "\0\4\3\2\\p"); - set obj.http.Snafu6 = - regsub(obj.http.Foobar, "(b)(a)(r)(f)", "\4\&\3\2p\"); + set beresp.http.Snafu1 = regsub(beresp.http.Foobar, "ar", "\0\0"); + set beresp.http.Snafu2 = + regsub(beresp.http.Foobar, "(b)(a)(r)(f)", "\4\3\2p"); + set beresp.http.Snafu3 = + regsub(beresp.http.Foobar, "(b)(a)(r)(f)", "\4\\\3\2p"); + set beresp.http.Snafu4 = + regsub(beresp.http.Foobar, "(b)(a)(r)(f)", "\4\&\3\2p"); + set beresp.http.Snafu5 = + regsub(beresp.http.Foobar, "(b)(a)(r)(f)", "\0\4\3\2\\p"); + set beresp.http.Snafu6 = + regsub(beresp.http.Foobar, "(b)(a)(r)(f)", "\4\&\3\2p\"); } } -start diff --git a/varnish-cache/bin/varnishtest/tests/c00009.vtc b/varnish-cache/bin/varnishtest/tests/c00009.vtc index 29241235..999ca0e9 100644 --- a/varnish-cache/bin/varnishtest/tests/c00009.vtc +++ b/varnish-cache/bin/varnishtest/tests/c00009.vtc @@ -24,7 +24,7 @@ varnish v1 -vcl+backend { } sub vcl_fetch { - if (obj.status != 200) { + if (beresp.status != 200) { restart; } } diff --git a/varnish-cache/bin/varnishtest/tests/r00251.vtc b/varnish-cache/bin/varnishtest/tests/r00251.vtc index 86879b30..57c40d43 100644 --- a/varnish-cache/bin/varnishtest/tests/r00251.vtc +++ b/varnish-cache/bin/varnishtest/tests/r00251.vtc @@ -12,9 +12,9 @@ server s1 { varnish v1 -vcl+backend { sub vcl_fetch { - set obj.http.Snafu1 = + set beresp.http.Snafu1 = "zoom" - regsub(obj.http.Foomble, "ar", "\0\0") + regsub(beresp.http.Foomble, "ar", "\0\0") "box"; } } -start diff --git a/varnish-cache/bin/varnishtest/tests/r00412.vtc b/varnish-cache/bin/varnishtest/tests/r00412.vtc index 87bfdaf8..4153e4e9 100644 --- a/varnish-cache/bin/varnishtest/tests/r00412.vtc +++ b/varnish-cache/bin/varnishtest/tests/r00412.vtc @@ -13,11 +13,11 @@ server s1 { varnish v1 -vcl+backend { sub vcl_fetch { - if (obj.status == 303) { - set obj.cacheable = true; - set obj.ttl = 60 s; - set obj.http.X-Magic-Redirect = "1"; - set req.url = obj.http.Location; + if (beresp.status == 303) { + set beresp.cacheable = true; + set beresp.ttl = 60 s; + set beresp.http.X-Magic-Redirect = "1"; + set req.url = beresp.http.Location; restart; } } diff --git a/varnish-cache/bin/varnishtest/tests/v00000.vtc b/varnish-cache/bin/varnishtest/tests/v00000.vtc index 43743d43..ac565cb3 100644 --- a/varnish-cache/bin/varnishtest/tests/v00000.vtc +++ b/varnish-cache/bin/varnishtest/tests/v00000.vtc @@ -15,8 +15,8 @@ varnish v1 -vcl+backend { set req.grace += 1 s; } sub vcl_fetch { - set obj.ttl += 1 m; - set obj.grace += 1 h; + set beresp.ttl += 1 m; + set beresp.grace += 1 h; } } -start diff --git a/varnish-cache/bin/varnishtest/tests/v00001.vtc b/varnish-cache/bin/varnishtest/tests/v00001.vtc index c912bc8a..404b4acc 100644 --- a/varnish-cache/bin/varnishtest/tests/v00001.vtc +++ b/varnish-cache/bin/varnishtest/tests/v00001.vtc @@ -29,11 +29,11 @@ varnish v1 -vcl+backend { set bereq.request = "GET"; } sub vcl_fetch { - set obj.http.foobar = - obj.proto obj.response obj.status; - set obj.proto = "HTTP/1.2"; - set obj.response = "For circular files"; - set obj.status = 903; + set beresp.http.foobar = + beresp.proto beresp.response beresp.status; + set beresp.proto = "HTTP/1.2"; + set beresp.response = "For circular files"; + set beresp.status = 903; } sub vcl_deliver { set resp.proto = "HTTP/1.2"; diff --git a/varnish-cache/bin/varnishtest/tests/v00010.vtc b/varnish-cache/bin/varnishtest/tests/v00010.vtc index c534cdf0..ee9049d2 100644 --- a/varnish-cache/bin/varnishtest/tests/v00010.vtc +++ b/varnish-cache/bin/varnishtest/tests/v00010.vtc @@ -13,8 +13,8 @@ server s1 { varnish v1 -vcl+backend { sub vcl_fetch { - if (obj.http.panic) { - panic "Had Panic header: " obj.http.panic; + if (beresp.http.panic) { + panic "Had Panic header: " beresp.http.panic; } } } -start diff --git a/varnish-cache/bin/varnishtest/tests/v00016.vtc b/varnish-cache/bin/varnishtest/tests/v00016.vtc index a70a563f..f4570c07 100644 --- a/varnish-cache/bin/varnishtest/tests/v00016.vtc +++ b/varnish-cache/bin/varnishtest/tests/v00016.vtc @@ -63,13 +63,13 @@ varnish v1 -vcl { /* test time and backend comparison */ sub vcl_fetch { - if (obj.ttl > 1d) { - set obj.ttl = 1d; + if (beresp.ttl > 1d) { + set beresp.ttl = 1d; } if (req.backend == b) { - set obj.ttl = 1d; + set beresp.ttl = 1d; } else if (req.backend != b) { - set obj.ttl = 1h; + set beresp.ttl = 1h; } } diff --git a/varnish-cache/bin/varnishtest/tests/v00018.vtc b/varnish-cache/bin/varnishtest/tests/v00018.vtc index 9f3dcbd0..bf94c6c8 100644 --- a/varnish-cache/bin/varnishtest/tests/v00018.vtc +++ b/varnish-cache/bin/varnishtest/tests/v00018.vtc @@ -15,14 +15,14 @@ varnish v1 -badvcl { varnish v1 -vcl { backend b { .host = "127.0.0.1"; } - sub vcl_fetch { error obj.status ; } + sub vcl_fetch { error beresp.status ; } } varnish v1 -vcl { backend b { .host = "127.0.0.1"; } sub vcl_miss { error req.url ; } sub vcl_pass { error "the butter please" ; } - sub vcl_fetch { error obj.status req.url; } + sub vcl_fetch { error beresp.status req.url; } } varnish v1 -badvcl { @@ -37,12 +37,12 @@ varnish v1 -badvcl { varnish v1 -vcl { backend b { .host = "127.0.0.1"; } - sub vcl_fetch { set obj.ttl /= 2; } + sub vcl_fetch { set beresp.ttl /= 2; } } varnish v1 -badvcl { backend b { .host = "127.0.0.1"; } - sub vcl_fetch { set obj.ttl >>= 2; } + sub vcl_fetch { set beresp.ttl >>= 2; } } varnish v1 -badvcl { @@ -78,22 +78,22 @@ varnish v1 -badvcl { varnish v1 -vcl { backend b { .host = "127.0.0.1"; } - sub vcl_fetch { set obj.cacheable = true; } + sub vcl_fetch { set beresp.cacheable = true; } } varnish v1 -vcl { backend b { .host = "127.0.0.1"; } - sub vcl_fetch { set obj.cacheable = false; } + sub vcl_fetch { set beresp.cacheable = false; } } varnish v1 -badvcl { backend b { .host = "127.0.0.1"; } - sub vcl_fetch { set obj.cacheable = mu; } + sub vcl_fetch { set beresp.cacheable = mu; } } varnish v1 -badvcl { backend b { .host = "127.0.0.1"; } - sub vcl_fetch { unset obj.cacheable; } + sub vcl_fetch { unset beresp.cacheable; } } varnish v1 -badvcl { diff --git a/varnish-cache/bin/varnishtest/tests/v00020.vtc b/varnish-cache/bin/varnishtest/tests/v00020.vtc index ca3441d9..8e7dafb0 100644 --- a/varnish-cache/bin/varnishtest/tests/v00020.vtc +++ b/varnish-cache/bin/varnishtest/tests/v00020.vtc @@ -16,7 +16,7 @@ varnish v1 -badvcl " sub vcl_recv { { } { " varnish v1 -vcl { backend b { .host = "127.0.0.1"; } sub vcl_fetch { - set obj.ttl = 1w; + set beresp.ttl = 1w; } } diff --git a/varnish-cache/include/vrt_obj.h b/varnish-cache/include/vrt_obj.h index 66f03b70..b781e9e8 100644 --- a/varnish-cache/include/vrt_obj.h +++ b/varnish-cache/include/vrt_obj.h @@ -34,12 +34,18 @@ double VRT_r_bereq_first_byte_timeout(struct sess *); void VRT_l_bereq_first_byte_timeout(struct sess *, double); double VRT_r_bereq_between_bytes_timeout(struct sess *); void VRT_l_bereq_between_bytes_timeout(struct sess *, double); -const char * VRT_r_beresp_request(const struct sess *); -void VRT_l_beresp_request(const struct sess *, const char *, ...); -const char * VRT_r_beresp_url(const struct sess *); -void VRT_l_beresp_url(const struct sess *, const char *, ...); const char * VRT_r_beresp_proto(const struct sess *); void VRT_l_beresp_proto(const struct sess *, const char *, ...); +int VRT_r_beresp_status(const struct sess *); +void VRT_l_beresp_status(const struct sess *, int); +const char * VRT_r_beresp_response(const struct sess *); +void VRT_l_beresp_response(const struct sess *, const char *, ...); +unsigned VRT_r_beresp_cacheable(const struct sess *); +void VRT_l_beresp_cacheable(const struct sess *, unsigned); +double VRT_r_beresp_ttl(const struct sess *); +void VRT_l_beresp_ttl(const struct sess *, double); +double VRT_r_beresp_grace(const struct sess *); +void VRT_l_beresp_grace(const struct sess *, double); const char * VRT_r_obj_proto(const struct sess *); void VRT_l_obj_proto(const struct sess *, const char *, ...); int VRT_r_obj_status(const struct sess *); diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index cf88ce3a..af2e2aad 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -233,8 +233,8 @@ vcl_output_lang_h(struct vsb *sb) vsb_cat(sb, " * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWI"); vsb_cat(sb, "SE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFT"); vsb_cat(sb, "WARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"); - vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 3542 2009-01-24 10:"); - vsb_cat(sb, "36:46Z phk $\n *\n * Runtime support for compiled VCL "); + vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 3834 2009-02-27 12:"); + vsb_cat(sb, "02:50Z phk $\n *\n * Runtime support for compiled VCL "); vsb_cat(sb, "programs.\n *\n * XXX: When this file is changed, lib/"); vsb_cat(sb, "libvcl/vcc_gen_fixed_token.tcl\n"); vsb_cat(sb, " * XXX: *MUST* be rerun.\n */\n"); @@ -322,7 +322,7 @@ vcl_output_lang_h(struct vsb *sb) /* ../../include/vrt_obj.h */ - vsb_cat(sb, "/*\n * $Id: vcc_gen_obj.tcl 3781 2009-02-17 10:29:20Z "); + vsb_cat(sb, "/*\n * $Id: vcc_gen_obj.tcl 3834 2009-02-27 12:02:50Z "); vsb_cat(sb, "phk $\n *\n * NB: This file is machine generated, DO "); vsb_cat(sb, "NOT EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n"); vsb_cat(sb, " */\n\nstruct sockaddr * VRT_r_client_ip(const struct "); @@ -354,25 +354,31 @@ vcl_output_lang_h(struct vsb *sb) vsb_cat(sb, "*);\nvoid VRT_l_bereq_first_byte_timeout(struct sess *"); vsb_cat(sb, ", double);\ndouble VRT_r_bereq_between_bytes_timeout(s"); vsb_cat(sb, "truct sess *);\nvoid VRT_l_bereq_between_bytes_timeout"); - vsb_cat(sb, "(struct sess *, double);\nconst char * VRT_r_beresp_re"); - vsb_cat(sb, "quest(const struct sess *);\nvoid VRT_l_beresp_request"); - vsb_cat(sb, "(const struct sess *, const char *, ...);\n"); - vsb_cat(sb, "const char * VRT_r_beresp_url(const struct sess *);\n"); - vsb_cat(sb, "void VRT_l_beresp_url(const struct sess *, const char "); - vsb_cat(sb, "*, ...);\nconst char * VRT_r_beresp_proto(const struct"); - vsb_cat(sb, " sess *);\nvoid VRT_l_beresp_proto(const struct sess *"); - vsb_cat(sb, ", const char *, ...);\nconst char * VRT_r_obj_proto(co"); - vsb_cat(sb, "nst struct sess *);\nvoid VRT_l_obj_proto(const struct"); - vsb_cat(sb, " sess *, const char *, ...);\nint VRT_r_obj_status(con"); - vsb_cat(sb, "st struct sess *);\nvoid VRT_l_obj_status(const struct"); - vsb_cat(sb, " sess *, int);\nconst char * VRT_r_obj_response(const "); - vsb_cat(sb, "struct sess *);\nvoid VRT_l_obj_response(const struct "); - vsb_cat(sb, "sess *, const char *, ...);\nint VRT_r_obj_hits(const "); - vsb_cat(sb, "struct sess *);\nunsigned VRT_r_obj_cacheable(const st"); - vsb_cat(sb, "ruct sess *);\nvoid VRT_l_obj_cacheable(const struct s"); - vsb_cat(sb, "ess *, unsigned);\ndouble VRT_r_obj_ttl(const struct s"); - vsb_cat(sb, "ess *);\nvoid VRT_l_obj_ttl(const struct sess *, doubl"); - vsb_cat(sb, "e);\ndouble VRT_r_obj_grace(const struct sess *);\n"); + vsb_cat(sb, "(struct sess *, double);\nconst char * VRT_r_beresp_pr"); + vsb_cat(sb, "oto(const struct sess *);\nvoid VRT_l_beresp_proto(con"); + vsb_cat(sb, "st struct sess *, const char *, ...);\n"); + vsb_cat(sb, "int VRT_r_beresp_status(const struct sess *);\n"); + vsb_cat(sb, "void VRT_l_beresp_status(const struct sess *, int);\n"); + vsb_cat(sb, "const char * VRT_r_beresp_response(const struct sess *"); + vsb_cat(sb, ");\nvoid VRT_l_beresp_response(const struct sess *, co"); + vsb_cat(sb, "nst char *, ...);\nunsigned VRT_r_beresp_cacheable(con"); + vsb_cat(sb, "st struct sess *);\nvoid VRT_l_beresp_cacheable(const "); + vsb_cat(sb, "struct sess *, unsigned);\ndouble VRT_r_beresp_ttl(con"); + vsb_cat(sb, "st struct sess *);\nvoid VRT_l_beresp_ttl(const struct"); + vsb_cat(sb, " sess *, double);\ndouble VRT_r_beresp_grace(const str"); + vsb_cat(sb, "uct sess *);\nvoid VRT_l_beresp_grace(const struct ses"); + vsb_cat(sb, "s *, double);\nconst char * VRT_r_obj_proto(const stru"); + vsb_cat(sb, "ct sess *);\nvoid VRT_l_obj_proto(const struct sess *,"); + vsb_cat(sb, " const char *, ...);\nint VRT_r_obj_status(const struc"); + vsb_cat(sb, "t sess *);\nvoid VRT_l_obj_status(const struct sess *,"); + vsb_cat(sb, " int);\nconst char * VRT_r_obj_response(const struct s"); + vsb_cat(sb, "ess *);\nvoid VRT_l_obj_response(const struct sess *, "); + vsb_cat(sb, "const char *, ...);\nint VRT_r_obj_hits(const struct s"); + vsb_cat(sb, "ess *);\nunsigned VRT_r_obj_cacheable(const struct ses"); + vsb_cat(sb, "s *);\nvoid VRT_l_obj_cacheable(const struct sess *, u"); + vsb_cat(sb, "nsigned);\ndouble VRT_r_obj_ttl(const struct sess *);\n"); + vsb_cat(sb, "void VRT_l_obj_ttl(const struct sess *, double);\n"); + vsb_cat(sb, "double VRT_r_obj_grace(const struct sess *);\n"); vsb_cat(sb, "void VRT_l_obj_grace(const struct sess *, double);\n"); vsb_cat(sb, "double VRT_r_obj_lastuse(const struct sess *);\n"); vsb_cat(sb, "const char * VRT_r_obj_hash(const struct sess *);\n"); diff --git a/varnish-cache/lib/libvcl/vcc_gen_obj.tcl b/varnish-cache/lib/libvcl/vcc_gen_obj.tcl index 2f5b18af..66265070 100755 --- a/varnish-cache/lib/libvcl/vcc_gen_obj.tcl +++ b/varnish-cache/lib/libvcl/vcc_gen_obj.tcl @@ -146,81 +146,97 @@ set spobj { ####################################################################### # Response from the backend - { beresp.request + { beresp.proto RW STRING { fetch } "const struct sess *" } - { beresp.url - RW STRING + { beresp.status + RW INT { fetch } "const struct sess *" } - { beresp.proto + { beresp.response RW STRING { fetch } "const struct sess *" } { beresp.http. - RW HDR_BEREQ + RW HDR_BERESP { fetch } "const struct sess *" } + { beresp.cacheable + RW BOOL + { fetch } + "const struct sess *" + } + { beresp.ttl + RW TIME + { fetch } + "const struct sess *" + } + { beresp.grace + RW TIME + { fetch } + "const struct sess *" + } ####################################################################### # The (possibly) cached object { obj.proto RW STRING - { hit fetch error} + { hit error} "const struct sess *" } { obj.status RW INT - { fetch error} + { error} "const struct sess *" } { obj.response RW STRING - { fetch error} + { error} "const struct sess *" } { obj.hits RO INT - { hit fetch deliver } + { hit deliver } "const struct sess *" } { obj.http. RW HDR_OBJ - { hit fetch error} + { hit error} "const struct sess *" } { obj.cacheable RW BOOL - { hit fetch discard timeout error} + { hit } "const struct sess *" } { obj.ttl RW TIME - { hit fetch discard timeout error} + { hit discard timeout error} "const struct sess *" } { obj.grace RW TIME - { hit fetch discard timeout error} + { hit discard timeout error} "const struct sess *" } { obj.lastuse RO TIME - { hit fetch deliver discard timeout error} + { hit deliver discard timeout error} "const struct sess *" } { obj.hash RO STRING - { miss hit fetch deliver error} + { miss hit deliver error} "const struct sess *" } + ####################################################################### # The response we send back { resp.proto RW STRING diff --git a/varnish-cache/lib/libvcl/vcc_obj.c b/varnish-cache/lib/libvcl/vcc_obj.c index 74f1391a..f57b4724 100644 --- a/varnish-cache/lib/libvcl/vcc_obj.c +++ b/varnish-cache/lib/libvcl/vcc_obj.c @@ -123,80 +123,91 @@ struct var vcc_vars[] = { V_RW, 0, VCL_MET_PASS | VCL_MET_MISS }, - { "beresp.request", STRING, 14, - "VRT_r_beresp_request(sp)", "VRT_l_beresp_request(sp, ", + { "beresp.proto", STRING, 12, + "VRT_r_beresp_proto(sp)", "VRT_l_beresp_proto(sp, ", V_RW, 0, VCL_MET_FETCH }, - { "beresp.url", STRING, 10, - "VRT_r_beresp_url(sp)", "VRT_l_beresp_url(sp, ", + { "beresp.status", INT, 13, + "VRT_r_beresp_status(sp)", "VRT_l_beresp_status(sp, ", V_RW, 0, VCL_MET_FETCH }, - { "beresp.proto", STRING, 12, - "VRT_r_beresp_proto(sp)", "VRT_l_beresp_proto(sp, ", + { "beresp.response", STRING, 15, + "VRT_r_beresp_response(sp)", "VRT_l_beresp_response(sp, ", V_RW, 0, VCL_MET_FETCH }, { "beresp.http.", HEADER, 12, "VRT_r_beresp_http_(sp)", "VRT_l_beresp_http_(sp, ", - V_RW, "HDR_BEREQ", + V_RW, "HDR_BERESP", + VCL_MET_FETCH + }, + { "beresp.cacheable", BOOL, 16, + "VRT_r_beresp_cacheable(sp)", "VRT_l_beresp_cacheable(sp, ", + V_RW, 0, + VCL_MET_FETCH + }, + { "beresp.ttl", TIME, 10, + "VRT_r_beresp_ttl(sp)", "VRT_l_beresp_ttl(sp, ", + V_RW, 0, + VCL_MET_FETCH + }, + { "beresp.grace", TIME, 12, + "VRT_r_beresp_grace(sp)", "VRT_l_beresp_grace(sp, ", + V_RW, 0, VCL_MET_FETCH }, { "obj.proto", STRING, 9, "VRT_r_obj_proto(sp)", "VRT_l_obj_proto(sp, ", V_RW, 0, - VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_ERROR + VCL_MET_HIT | VCL_MET_ERROR }, { "obj.status", INT, 10, "VRT_r_obj_status(sp)", "VRT_l_obj_status(sp, ", V_RW, 0, - VCL_MET_FETCH | VCL_MET_ERROR + VCL_MET_ERROR }, { "obj.response", STRING, 12, "VRT_r_obj_response(sp)", "VRT_l_obj_response(sp, ", V_RW, 0, - VCL_MET_FETCH | VCL_MET_ERROR + VCL_MET_ERROR }, { "obj.hits", INT, 8, "VRT_r_obj_hits(sp)", NULL, V_RO, 0, - VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER + VCL_MET_HIT | VCL_MET_DELIVER }, { "obj.http.", HEADER, 9, "VRT_r_obj_http_(sp)", "VRT_l_obj_http_(sp, ", V_RW, "HDR_OBJ", - VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_ERROR + VCL_MET_HIT | VCL_MET_ERROR }, { "obj.cacheable", BOOL, 13, "VRT_r_obj_cacheable(sp)", "VRT_l_obj_cacheable(sp, ", V_RW, 0, - VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DISCARD | VCL_MET_TIMEOUT - | VCL_MET_ERROR + VCL_MET_HIT }, { "obj.ttl", TIME, 7, "VRT_r_obj_ttl(sp)", "VRT_l_obj_ttl(sp, ", V_RW, 0, - VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DISCARD | VCL_MET_TIMEOUT - | VCL_MET_ERROR + VCL_MET_HIT | VCL_MET_DISCARD | VCL_MET_TIMEOUT | VCL_MET_ERROR }, { "obj.grace", TIME, 9, "VRT_r_obj_grace(sp)", "VRT_l_obj_grace(sp, ", V_RW, 0, - VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DISCARD | VCL_MET_TIMEOUT - | VCL_MET_ERROR + VCL_MET_HIT | VCL_MET_DISCARD | VCL_MET_TIMEOUT | VCL_MET_ERROR }, { "obj.lastuse", TIME, 11, "VRT_r_obj_lastuse(sp)", NULL, V_RO, 0, - VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_DISCARD - | VCL_MET_TIMEOUT | VCL_MET_ERROR + VCL_MET_HIT | VCL_MET_DELIVER | VCL_MET_DISCARD | VCL_MET_TIMEOUT + | VCL_MET_ERROR }, { "obj.hash", STRING, 8, "VRT_r_obj_hash(sp)", NULL, V_RO, 0, - VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER - | VCL_MET_ERROR + VCL_MET_MISS | VCL_MET_HIT | VCL_MET_DELIVER | VCL_MET_ERROR }, { "resp.proto", STRING, 10, "VRT_r_resp_proto(sp)", "VRT_l_resp_proto(sp, ", -- 2.39.5