[experimental-ims] 9e5fe24 Merge experimental-ims with trunk as of 2011-11-22
Geoff Simmons
geoff at varnish-cache.org
Mon Jan 9 21:52:50 CET 2012
commit 9e5fe240f7c393aa7f6cae56795b5e9cbc336a25
Merge: ace762d dcd622d
Author: Geoff Simmons <geoff at uplex.de>
Date: Mon Jan 9 21:28:45 2012 +0100
Merge experimental-ims with trunk as of 2011-11-22
diff --cc bin/varnishd/cache/cache.h
index 4df2e3d,ed6a3fd..521786b
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@@ -601,11 -631,8 +631,9 @@@ struct sess
VTAILQ_ENTRY(sess) list;
struct director *director;
- struct object *obj;
- struct objcore *objcore;
struct VCL_conf *vcl;
+ struct object *stale_obj;
/* The busy objhead we sleep on */
struct objhead *hash_objhead;
diff --cc bin/varnishd/cache/cache_center.c
index 7b8dc8a,8826ae2..dd4e1bd
--- a/bin/varnishd/cache/cache_center.c
+++ b/bin/varnishd/cache/cache_center.c
@@@ -579,16 -616,15 +616,16 @@@ cnt_fetch(struct sess *sp
/*
* What does RFC2616 think about TTL ?
*/
- EXP_Clr(&sp->wrk->exp);
- sp->wrk->exp.entered = VTIM_real();
+ EXP_Clr(&wrk->busyobj->exp);
+ wrk->busyobj->exp.entered = W_TIM_real(wrk);
RFC2616_Ttl(sp);
- sp->wrk->exp.keep = cache_param->default_keep;
++ wrk->busyobj->exp.keep = cache_param->default_keep;
/* pass from vclrecv{} has negative TTL */
- if (sp->objcore == NULL)
- sp->wrk->exp.ttl = -1.;
+ if (wrk->objcore == NULL)
+ wrk->busyobj->exp.ttl = -1.;
- AZ(sp->wrk->do_esi);
+ AZ(wrk->busyobj->do_esi);
VCL_fetch_method(sp);
@@@ -732,34 -770,30 +771,34 @@@ cnt_fetchbody(struct sess *sp
"Content-Encoding: gzip");
/* But we can't do both at the same time */
- assert(sp->wrk->do_gzip == 0 || sp->wrk->do_gunzip == 0);
+ assert(wrk->busyobj->do_gzip == 0 || wrk->busyobj->do_gunzip == 0);
/* ESI takes precedence and handles gzip/gunzip itself */
- if (sp->wrk->do_esi)
- sp->wrk->vfp = &vfp_esi;
- else if (sp->wrk->do_gunzip)
- sp->wrk->vfp = &vfp_gunzip;
- else if (sp->wrk->do_gzip)
- sp->wrk->vfp = &vfp_gzip;
- else if (sp->wrk->is_gzip)
- sp->wrk->vfp = &vfp_testgzip;
-
- if (sp->wrk->do_esi || sp->esi_level > 0)
- sp->wrk->do_stream = 0;
+ if (wrk->busyobj->do_esi)
+ wrk->busyobj->vfp = &vfp_esi;
+ else if (wrk->busyobj->do_gunzip)
+ wrk->busyobj->vfp = &vfp_gunzip;
+ else if (wrk->busyobj->do_gzip)
+ wrk->busyobj->vfp = &vfp_gzip;
+ else if (wrk->busyobj->is_gzip)
+ wrk->busyobj->vfp = &vfp_testgzip;
+
+ if (wrk->busyobj->do_esi || sp->esi_level > 0)
+ wrk->busyobj->do_stream = 0;
if (!sp->wantbody)
- sp->wrk->do_stream = 0;
+ wrk->busyobj->do_stream = 0;
- l = http_EstimateWS(sp->wrk->beresp,
+ l = http_EstimateWS(wrk->busyobj->beresp,
pass ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp);
+ if (sp->stale_obj) {
+ l += http_EstimateWS(sp->stale_obj->http, 0, &stale_nhttp);
+ nhttp += stale_nhttp;
+ }
/* Create Vary instructions */
- if (sp->objcore != NULL) {
- CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
- vary = VRY_Create(sp, sp->wrk->beresp);
+ if (wrk->objcore != NULL) {
+ CHECK_OBJ_NOTNULL(wrk->objcore, OBJCORE_MAGIC);
+ vary = VRY_Create(sp, wrk->busyobj->beresp);
if (vary != NULL) {
varyl = VSB_len(vary);
assert(varyl > 0);
@@@ -783,33 -817,32 +822,33 @@@
* Try to salvage the transaction by allocating a
* shortlived object on Transient storage.
*/
- sp->obj = STV_NewObject(sp, TRANSIENT_STORAGE, l,
- &sp->wrk->exp, nhttp);
- if (sp->wrk->exp.ttl > cache_param->shortlived)
- sp->wrk->exp.ttl = cache_param->shortlived;
- sp->wrk->exp.grace = 0.0;
- sp->wrk->exp.keep = 0.0;
+ wrk->obj = STV_NewObject(wrk, TRANSIENT_STORAGE, l, nhttp);
+ if (wrk->busyobj->exp.ttl > cache_param->shortlived)
+ wrk->busyobj->exp.ttl = cache_param->shortlived;
+ wrk->busyobj->exp.grace = 0.0;
+ wrk->busyobj->exp.keep = 0.0;
}
- if (sp->obj == NULL) {
+ if (wrk->obj == NULL) {
sp->err_code = 503;
sp->step = STP_ERROR;
- VDI_CloseFd(sp->wrk);
+ VDI_CloseFd(wrk, &wrk->busyobj->vbc);
+ VBO_DerefBusyObj(wrk, &wrk->busyobj);
return (0);
}
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
- sp->obj->exp.keep = sp->wrk->exp.keep;
+ CHECK_OBJ_NOTNULL(wrk->obj, OBJECT_MAGIC);
++ wrk->busyobj->exp.keep = sp->exp.keep;
- sp->wrk->storage_hint = NULL;
+ wrk->storage_hint = NULL;
- if (sp->wrk->do_gzip || (sp->wrk->is_gzip && !sp->wrk->do_gunzip))
- sp->obj->gziped = 1;
+ if (wrk->busyobj->do_gzip ||
+ (wrk->busyobj->is_gzip && !wrk->busyobj->do_gunzip))
+ wrk->obj->gziped = 1;
if (vary != NULL) {
- sp->obj->vary =
- (void *)WS_Alloc(sp->obj->http->ws, varyl);
- AN(sp->obj->vary);
- memcpy(sp->obj->vary, VSB_data(vary), varyl);
- VRY_Validate(sp->obj->vary);
+ wrk->obj->vary = (void *)WS_Alloc(wrk->obj->http->ws, varyl);
+ AN(wrk->obj->vary);
+ memcpy(wrk->obj->vary, VSB_data(vary), varyl);
+ VRY_Validate(wrk->obj->vary);
VSB_delete(vary);
}
@@@ -823,34 -856,16 +862,34 @@@
hp2->logtag = HTTP_Obj;
http_CopyResp(hp2, hp);
+
- http_FilterFields(sp->wrk, sp->vsl_id, hp2, hp,
+ http_FilterFields(wrk, sp->vsl_id, hp2, hp,
pass ? HTTPH_R_PASS : HTTPH_A_INS);
+
+ /*
+ * If we found a candidate for conditional backend request, attempt it
+ * now. If backend responds with 304, http_Check304() merges stale_obj
- * into sp->obj, any other response is handled as usual. In either case,
++ * into wrk->obj, any other response is handled as usual. In either case,
+ * the stale_obj is no longer needed in the cache, so discard it.
+ */
+ if (sp->stale_obj) {
+ http_Check304(sp);
- if (sp->wrk->beresp->status == 304)
- assert(sp->obj->http->status == 200);
++ if (wrk->busyobj->beresp->status == 304)
++ assert(wrk->obj->http->status == 200);
+ EXP_Clr(&sp->stale_obj->exp);
+ EXP_Rearm(sp->stale_obj);
+ HSH_Deref(sp->wrk, NULL, &sp->stale_obj);
+ AZ(sp->stale_obj);
+ }
- http_CopyHome(sp->wrk, sp->vsl_id, hp2);
+ http_CopyHome(wrk, sp->vsl_id, hp2);
- if (http_GetHdr(hp, H_Last_Modified, &b))
+ if (http_GetHdr(hp, H_Last_Modified, &b)
- || http_GetHdr(sp->obj->http, H_Last_Modified, &b))
- sp->obj->last_modified = VTIM_parse(b);
++ || http_GetHdr(wrk->obj->http, H_Last_Modified, &b))
+ wrk->obj->last_modified = VTIM_parse(b);
else
- sp->obj->last_modified = floor(sp->wrk->exp.entered);
+ wrk->obj->last_modified = floor(wrk->busyobj->exp.entered);
- assert(WRW_IsReleased(sp->wrk));
+ assert(WRW_IsReleased(wrk));
/*
* If we can deliver a 304 reply, we don't bother streaming.
@@@ -1160,12 -1202,10 +1226,12 @@@ cnt_lookup(struct sess *sp
sp->vary_e = NULL;
if (oc->flags & OC_F_PASS) {
- sp->wrk->stats.cache_hitpass++;
- WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
- (void)HSH_Deref(sp->wrk, NULL, &sp->obj);
+ wrk->stats.cache_hitpass++;
+ WSP(sp, SLT_HitPass, "%u", wrk->obj->xid);
+ (void)HSH_Deref(wrk, NULL, &wrk->obj);
+ if (sp->stale_obj != NULL)
- (void)HSH_Deref(sp->wrk, NULL, &sp->stale_obj);
- sp->objcore = NULL;
++ (void)HSH_Deref(wrk, NULL, &sp->stale_obj);
+ wrk->objcore = NULL;
sp->step = STP_PASS;
return (0);
}
@@@ -1218,26 -1263,22 +1289,28 @@@ cnt_miss(struct sess *sp
* client doesn't grok it. We will uncompress for
* the minority of clients which don't.
*/
- http_Unset(sp->wrk->bereq, H_Accept_Encoding);
- http_SetHeader(sp->wrk, sp->vsl_id, sp->wrk->bereq,
+ http_Unset(wrk->busyobj->bereq, H_Accept_Encoding);
+ http_SetHeader(wrk, sp->vsl_id, wrk->busyobj->bereq,
"Accept-Encoding: gzip");
}
- sp->wrk->connect_timeout = 0;
- sp->wrk->first_byte_timeout = 0;
- sp->wrk->between_bytes_timeout = 0;
+ wrk->connect_timeout = 0;
+ wrk->first_byte_timeout = 0;
+ wrk->between_bytes_timeout = 0;
+ /* If a candidate for a conditional backend request was found,
+ * add If-Modified-Since and/or If-None-Match to the bereq.
+ */
+ if (sp->stale_obj)
+ http_CheckRefresh(sp);
+
VCL_miss_method(sp);
+
switch(sp->handling) {
case VCL_RET_ERROR:
- AZ(HSH_Deref(sp->wrk, sp->objcore, NULL));
- sp->objcore = NULL;
- http_Setup(sp->wrk->bereq, NULL);
+ AZ(HSH_Deref(wrk, wrk->objcore, NULL));
+ wrk->objcore = NULL;
+ http_Setup(wrk->busyobj->bereq, NULL);
+ VBO_DerefBusyObj(wrk, &wrk->busyobj);
sp->step = STP_ERROR;
return (0);
case VCL_RET_PASS:
diff --cc bin/varnishd/cache/cache_fetch.c
index cc46222,936dc30..6291ac0
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@@ -499,16 -508,11 +508,16 @@@ FetchBody(struct worker *wrk, struct ob
AssertObjCorePassOrBusy(obj->objcore);
- AZ(w->vgz_rx);
+ AZ(bo->vgz_rx);
- AZ(VTAILQ_FIRST(&obj->store));
+
+ /* If we've freshened from another object and got a "Not Modified"
+ * response, then we have already duped the other object's body.
+ */
- if (w->beresp->status != 304)
++ if (bo->beresp->status != 304)
+ AZ(VTAILQ_FIRST(&obj->store));
- w->fetch_obj = obj;
- w->fetch_failed = 0;
+ bo->fetch_obj = obj;
+ bo->fetch_failed = 0;
/* XXX: pick up estimate from objdr ? */
cl = 0;
diff --cc bin/varnishd/cache/cache_hash.c
index 5251f6d,6f6a85f..c56a2d5
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@@ -313,8 -304,7 +306,8 @@@ HSH_Lookup(struct sess *sp, struct objh
CHECK_OBJ_NOTNULL(sp->http, HTTP_MAGIC);
AN(sp->director);
AN(hash);
+ AZ(sp->stale_obj);
- w = sp->wrk;
+ wrk = sp->wrk;
HSH_Prealloc(sp);
memcpy(sp->wrk->nobjhead->digest, sp->digest, sizeof sp->digest);
@@@ -475,21 -443,9 +468,21 @@@
return (NULL);
}
+ /* If we're not serving a valid or graced object and we saved stale_o,
+ * it is a candidate for the conditional backend request. */
+ AZ(oc && !sp->hash_always_miss);
+ AZ(busy_oc);
+ if (stale_o != NULL) {
+ AZ(stale_o->objcore->flags & OC_F_BUSY);
+ CHECK_OBJ_NOTNULL(stale_o->objcore, OBJCORE_MAGIC);
+ Lck_AssertHeld(&oh->mtx);
+ stale_o->objcore->refcnt++;
+ sp->stale_obj = stale_o;
+ }
+
/* Insert (precreated) objcore in objecthead */
- oc = w->nobjcore;
- w->nobjcore = NULL;
+ oc = wrk->nobjcore;
+ wrk->nobjcore = NULL;
AN(oc->flags & OC_F_BUSY);
oc->refcnt = 1;
diff --cc bin/varnishd/cache/cache_http.c
index b937d64,4a6ba82..b314b55
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@@ -917,89 -883,6 +917,88 @@@ http_FilterHeader(const struct sess *sp
http_PrintfHeader(sp->wrk, sp->vsl_id, hp, "X-Varnish: %u", sp->xid);
}
+/*-------------------------------------------------------------------
+ * This function checks for sp->freshen_obj. If present, HSH_Lookup()
+ * found an expired object that qualifies for a refresh check,
+ * so add the appropriate headers.
+ */
+
+void
+http_CheckRefresh(struct sess *sp)
+{
+ struct object *freshen_obj;
+ struct http *obj_hp, *bereq_hp;
+ char *p;
+
+ freshen_obj = sp->stale_obj;
+ CHECK_OBJ_NOTNULL(freshen_obj, OBJECT_MAGIC);
- bereq_hp = sp->wrk->bereq;
++ bereq_hp = sp->wrk->busyobj->bereq;
+ CHECK_OBJ_NOTNULL(bereq_hp, HTTP_MAGIC);
+ obj_hp = freshen_obj->http;
+ CHECK_OBJ_NOTNULL(obj_hp, HTTP_MAGIC);
+
+ if(http_GetHdr(obj_hp, H_ETag, &p))
+ http_PrintfHeader(sp->wrk, sp->fd, bereq_hp, "If-None-Match: %s", p);
+
+ if(http_GetHdr(obj_hp, H_Last_Modified, &p))
+ http_PrintfHeader(sp->wrk, sp->fd, bereq_hp, "If-Modified-Since: %s",p);
+}
+
+/*-------------------------------------------------------------------
+ * Called after fetch and sp->freshen_obj present. Check
+ * response and handle as needed.
+ */
+
+void
+http_Check304(struct sess *sp)
+{
+ struct object *o, *o_stale;
+ char *p;
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ o_stale = sp->stale_obj;
+ CHECK_OBJ_NOTNULL(o_stale, OBJECT_MAGIC);
- o = sp->obj;
++ o = sp->wrk->obj;
+ CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+
- if (sp->wrk->beresp->status != 304) {
++ if (sp->wrk->busyobj->beresp->status != 304) {
+ /*
+ * IMS/INM headers may have been removed in VCL, so only count a
+ * non-validating response if they were present in the request.
+ */
- if (http_GetHdr(sp->wrk->bereq, H_If_Modified_Since, &p)
- || http_GetHdr(sp->wrk->bereq, H_If_None_Match, &p))
- sp->wrk->stats.cond_not_validated++;
++ if (http_GetHdr(sp->wrk->busyobj->bereq, H_If_Modified_Since, &p)
++ || http_GetHdr(sp->wrk->busyobj->bereq, H_If_None_Match, &p))
++ sp->wrk->stats.fetch_not_validated++;
+ return;
+ }
+
+ /*
+ * Copy headers we need from the stale object into the 304 response
+ */
- http_FilterMissingFields(sp->wrk, sp->fd, sp->obj->http,
- sp->stale_obj->http);
++ http_FilterMissingFields(sp->wrk, sp->fd, o->http, o_stale->http);
+
+ /*
+ * Dup the stale object's storage in to the new object
+ * and reset Content-Length from the size of the storage.
+ */
+ STV_dup(sp, o_stale, o);
+ http_Unset(o->http, H_Content_Length);
+ http_PrintfHeader(sp->wrk, sp->fd, o->http, "Content-Length: %u", o->len);
+
+ http_SetResp(o->http, "HTTP/1.1", 200, "Ok Not Modified");
+ http_SetH(o->http, HTTP_HDR_REQ, "GET");
- http_copyh(o->http, sp->wrk->bereq, HTTP_HDR_URL);
++ http_copyh(o->http, sp->wrk->busyobj->bereq, HTTP_HDR_URL);
+
+ /*
+ * XXX: Are we copying all the necessary fields from stale_obj?
+ * Should we copy o_stale->hits into o->hits?
+ */
+ o->response = 200;
+ o->gziped = o_stale->gziped;
+
+ AZ(o_stale->objcore->flags & OC_F_BUSY);
+}
+
/*--------------------------------------------------------------------
* This function copies any header fields which reference foreign
* storage into our own WS.
diff --cc bin/varnishd/cache/cache_vrt.c
index 27964dc,a696f64..290b6bf
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@@ -108,13 -109,9 +109,13 @@@ vrt_selecthttp(const struct sess *sp, e
hp = sp->wrk->resp;
break;
case HDR_OBJ:
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
- hp = sp->obj->http;
+ CHECK_OBJ_NOTNULL(sp->wrk->obj, OBJECT_MAGIC);
+ hp = sp->wrk->obj->http;
break;
+ case HDR_STALE_OBJ:
+ CHECK_OBJ_NOTNULL(sp->stale_obj, OBJECT_MAGIC);
+ hp = sp->stale_obj->http;
+ break;
default:
INCOMPL();
}
diff --cc bin/varnishd/cache/cache_vrt_var.c
index 407de1d,0662e26..b5a5bac
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@@ -82,32 -78,22 +82,32 @@@ const char *
VRT_r_##obj##_##hdr(const struct sess *sp) \
{ \
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- CHECK_OBJ_NOTNULL(http, HTTP_MAGIC); \
- return (http->hd[fld].b); \
-}
-
-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->wrk->busyobj->bereq, HTTP_HDR_REQ)
-VRT_DO_HDR(bereq, url, sp->wrk->busyobj->bereq, HTTP_HDR_URL)
-VRT_DO_HDR(bereq, proto, sp->wrk->busyobj->bereq, HTTP_HDR_PROTO)
-VRT_DO_HDR(obj, proto, sp->wrk->obj->http, HTTP_HDR_PROTO)
-VRT_DO_HDR(obj, response, sp->wrk->obj->http, HTTP_HDR_RESPONSE)
-VRT_DO_HDR(resp, proto, sp->wrk->resp, HTTP_HDR_PROTO)
-VRT_DO_HDR(resp, response, sp->wrk->resp, HTTP_HDR_RESPONSE)
-VRT_DO_HDR(beresp, proto, sp->wrk->busyobj->beresp, HTTP_HDR_PROTO)
-VRT_DO_HDR(beresp, response, sp->wrk->busyobj->beresp, HTTP_HDR_RESPONSE)
+ if (!nullable || cont != NULL) { \
+ CHECK_OBJ_NOTNULL(cont->http, HTTP_MAGIC); \
+ return (cont->http->hd[fld].b); \
+ } \
+ ILLEGAL_R(sp, #obj, #hdr); \
+ return(NULL); \
+} \
+
+#define VRT_DO_HDR(obj, hdr, cont, http, fld, nullable) \
+VRT_DO_HDR_l(obj, hdr, cont, http, fld) \
+VRT_DO_HDR_r(obj, hdr, cont, http, fld, nullable) \
+
- VRT_DO_HDR(req, request, sp, http, HTTP_HDR_REQ, 0)
- VRT_DO_HDR(req, url, sp, http, HTTP_HDR_URL, 0)
- VRT_DO_HDR(req, proto, sp, http, HTTP_HDR_PROTO, 0)
- VRT_DO_HDR(bereq, request, sp->wrk, bereq, HTTP_HDR_REQ, 0)
- VRT_DO_HDR(bereq, url, sp->wrk, bereq, HTTP_HDR_URL, 0)
- VRT_DO_HDR(bereq, proto, sp->wrk, bereq, HTTP_HDR_PROTO, 0)
- VRT_DO_HDR(obj, proto, sp->obj, http, HTTP_HDR_PROTO, 0)
- VRT_DO_HDR(obj, response, sp->obj, http, HTTP_HDR_RESPONSE, 0)
- VRT_DO_HDR(resp, proto, sp->wrk, resp, HTTP_HDR_PROTO, 0)
- VRT_DO_HDR(resp, response, sp->wrk, resp, HTTP_HDR_RESPONSE, 0)
- VRT_DO_HDR(beresp, proto, sp->wrk, beresp, HTTP_HDR_PROTO, 0)
- VRT_DO_HDR(beresp, response, sp->wrk, beresp, HTTP_HDR_RESPONSE, 0)
- VRT_DO_HDR_r(stale_obj, proto, sp->stale_obj, http, HTTP_HDR_PROTO, 1)
- VRT_DO_HDR_r(stale_obj, response, sp->stale_obj, http, HTTP_HDR_RESPONSE, 1)
++VRT_DO_HDR(req, request, sp, http, HTTP_HDR_REQ, 0)
++VRT_DO_HDR(req, url, sp, http, HTTP_HDR_URL, 0)
++VRT_DO_HDR(req, proto, sp, http, HTTP_HDR_PROTO, 0)
++VRT_DO_HDR(bereq, request, sp->wrk->busyobj, bereq, HTTP_HDR_REQ, 0)
++VRT_DO_HDR(bereq, url, sp->wrk->busyobj, bereq, HTTP_HDR_URL, 0)
++VRT_DO_HDR(bereq, proto, sp->wrk->busyobj, bereq, HTTP_HDR_PROTO, 0)
++VRT_DO_HDR(obj, proto, sp->wrk->obj, http, HTTP_HDR_PROTO, 0)
++VRT_DO_HDR(obj, response, sp->wrk->obj, http, HTTP_HDR_RESPONSE, 0)
++VRT_DO_HDR(resp, proto, sp->wrk, resp, HTTP_HDR_PROTO, 0)
++VRT_DO_HDR(resp, response, sp->wrk, resp, HTTP_HDR_RESPONSE, 0)
++VRT_DO_HDR(beresp, proto, sp->wrk->busyobj, beresp, HTTP_HDR_PROTO, 0)
++VRT_DO_HDR(beresp, response, sp->wrk->busyobj, beresp, HTTP_HDR_RESPONSE, 0)
++VRT_DO_HDR_r(stale_obj, proto, sp->stale_obj, http, HTTP_HDR_PROTO, 1)
++VRT_DO_HDR_r(stale_obj, response, sp->stale_obj, http, HTTP_HDR_RESPONSE, 1)
/*--------------------------------------------------------------------*/
@@@ -126,21 -111,12 +126,21 @@@ VRT_r_##obj##_status(const struct sess
{ \
\
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); \
- return(http->status); \
+ if (nullable && cont == NULL) { \
+ ILLEGAL_R(sp, #obj, "status"); \
+ return (503); \
+ } \
+ return(cont->http->status); \
}
-VRT_DO_STATUS(obj, sp->wrk->obj->http)
-VRT_DO_STATUS(beresp, sp->wrk->busyobj->beresp)
-VRT_DO_STATUS(resp, sp->wrk->resp)
+#define VRT_DO_STATUS(obj, cont, http, nullable) \
+VRT_DO_STATUS_l(obj, cont, http) \
+VRT_DO_STATUS_r(obj, cont, http, nullable) \
+
- VRT_DO_STATUS(obj, sp->obj, http, 0)
- VRT_DO_STATUS(beresp, sp->wrk, beresp, 0)
- VRT_DO_STATUS(resp, sp->wrk, resp, 0)
- VRT_DO_STATUS_r(stale_obj, sp->stale_obj, http, 1)
++VRT_DO_STATUS(obj, sp->wrk->obj, http, 0)
++VRT_DO_STATUS(beresp, sp->wrk->busyobj, beresp, 0)
++VRT_DO_STATUS(resp, sp->wrk, resp, 0)
++VRT_DO_STATUS_r(stale_obj, sp->stale_obj, http, 1)
/*--------------------------------------------------------------------*/
@@@ -429,30 -401,26 +433,30 @@@ vrt_wsp_exp(const struct sess *sp, unsi
sp->t_req, e->age + (sp->t_req - e->entered));
}
-VRT_DO_EXP(req, sp->exp, ttl, 0, )
-VRT_DO_EXP(req, sp->exp, grace, 0, )
-VRT_DO_EXP(req, sp->exp, keep, 0, )
+VRT_DO_EXP(req, sp, ttl, 0, 0, )
+VRT_DO_EXP(req, sp, grace, 0, 0, )
+VRT_DO_EXP(req, sp, keep, 0, 0, )
- VRT_DO_EXP(obj, sp->obj, grace, 0, 0,
- EXP_Rearm(sp->obj);
- vrt_wsp_exp(sp, sp->obj->xid, &sp->obj->exp);)
- VRT_DO_EXP(obj, sp->obj, ttl, (sp->t_req - sp->obj->exp.entered), 0,
- EXP_Rearm(sp->obj);
- vrt_wsp_exp(sp, sp->obj->xid, &sp->obj->exp);)
- VRT_DO_EXP(obj, sp->obj, keep, 0, 0,
- EXP_Rearm(sp->obj);
- vrt_wsp_exp(sp, sp->obj->xid, &sp->obj->exp);)
-
- VRT_DO_EXP(beresp, sp->wrk, grace, 0, 0,
- vrt_wsp_exp(sp, sp->xid, &sp->wrk->exp);)
- VRT_DO_EXP(beresp, sp->wrk, ttl, 0, 0,
- vrt_wsp_exp(sp, sp->xid, &sp->wrk->exp);)
- VRT_DO_EXP(beresp, sp->wrk, keep, 0, 0,
- vrt_wsp_exp(sp, sp->xid, &sp->wrk->exp);)
-VRT_DO_EXP(obj, sp->wrk->obj->exp, grace, 0,
++VRT_DO_EXP(obj, sp->wrk->obj, grace, 0, 0,
+ EXP_Rearm(sp->wrk->obj);
+ vrt_wsp_exp(sp, sp->wrk->obj->xid, &sp->wrk->obj->exp);)
-VRT_DO_EXP(obj, sp->wrk->obj->exp, ttl, (sp->t_req - sp->wrk->obj->exp.entered),
++VRT_DO_EXP(obj, sp->wrk->obj, ttl, (sp->t_req - sp->wrk->obj->exp.entered), 0,
+ EXP_Rearm(sp->wrk->obj);
+ vrt_wsp_exp(sp, sp->wrk->obj->xid, &sp->wrk->obj->exp);)
-VRT_DO_EXP(obj, sp->wrk->obj->exp, keep, 0,
++VRT_DO_EXP(obj, sp->wrk->obj, keep, 0, 0,
+ EXP_Rearm(sp->wrk->obj);
+ vrt_wsp_exp(sp, sp->wrk->obj->xid, &sp->wrk->obj->exp);)
+
-VRT_DO_EXP(beresp, sp->wrk->busyobj->exp, grace, 0,
++VRT_DO_EXP(beresp, sp->wrk->busyobj, grace, 0, 0,
+ vrt_wsp_exp(sp, sp->xid, &sp->wrk->busyobj->exp);)
-VRT_DO_EXP(beresp, sp->wrk->busyobj->exp, ttl, 0,
++VRT_DO_EXP(beresp, sp->wrk->busyobj, ttl, 0, 0,
+ vrt_wsp_exp(sp, sp->xid, &sp->wrk->busyobj->exp);)
-VRT_DO_EXP(beresp, sp->wrk->busyobj->exp, keep, 0,
++VRT_DO_EXP(beresp, sp->wrk->busyobj, keep, 0, 0,
+ vrt_wsp_exp(sp, sp->xid, &sp->wrk->busyobj->exp);)
+
+VRT_DO_EXP_r(stale_obj, sp->stale_obj, grace, 0, 1)
+VRT_DO_EXP_r(stale_obj, sp->stale_obj, ttl, 0, 1)
+VRT_DO_EXP_r(stale_obj, sp->stale_obj, keep, 0, 1)
/*--------------------------------------------------------------------
* req.xid
@@@ -565,45 -531,19 +569,45 @@@ VRT_r_obj_hits(const struct sess *sp
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
- return (sp->obj->hits);
+ CHECK_OBJ_NOTNULL(sp->wrk->obj, OBJECT_MAGIC); /* XXX */
+ return (sp->wrk->obj->hits);
}
+int
+VRT_r_stale_obj_hits(const struct sess *sp)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ if (sp->stale_obj == NULL) {
+ ILLEGAL_R(sp, "stale_obj", "hits");
+ return (0);
+ }
+ CHECK_OBJ(sp->stale_obj, OBJECT_MAGIC); /* XXX */
+ return (sp->stale_obj->hits);
+}
+
double
VRT_r_obj_lastuse(const struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
- return (VTIM_real() - sp->obj->last_use);
+ CHECK_OBJ_NOTNULL(sp->wrk->obj, OBJECT_MAGIC); /* XXX */
+ return (VTIM_real() - sp->wrk->obj->last_use);
}
+double
+VRT_r_stale_obj_lastuse(const struct sess *sp)
+{
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ if (sp->stale_obj == NULL) {
+ ILLEGAL_R(sp, "stale_obj", "lastuse");
+ return (0);
+ }
+ CHECK_OBJ(sp->stale_obj, OBJECT_MAGIC); /* XXX */
+ return (VTIM_real() - sp->stale_obj->last_use);
+}
+
unsigned
VRT_r_req_backend_healthy(const struct sess *sp)
{
diff --cc bin/varnishd/storage/stevedore.c
index 71241f5,a6156d4..037d77c
--- a/bin/varnishd/storage/stevedore.c
+++ b/bin/varnishd/storage/stevedore.c
@@@ -366,11 -376,8 +376,11 @@@ STV_Freestore(struct object *o
struct storage *
STV_alloc(struct worker *w, size_t size)
{
- struct object *obj = w->fetch_obj;
++ struct object *obj = w->busyobj->fetch_obj;
+ if (obj == NULL)
- obj = w->sp->obj;
++ obj = w->obj;
- return (stv_alloc(w, w->busyobj->fetch_obj, size));
+ return (stv_alloc(w, obj, size));
}
void
diff --cc bin/varnishd/storage/storage.h
index 879a6fb,c8c3689..70468be
--- a/bin/varnishd/storage/storage.h
+++ b/bin/varnishd/storage/storage.h
@@@ -39,11 -40,10 +40,11 @@@ struct lru
typedef void storage_init_f(struct stevedore *, int ac, char * const *av);
typedef void storage_open_f(const struct stevedore *);
typedef struct storage *storage_alloc_f(struct stevedore *, size_t size);
+typedef void storage_dup_f(const struct sess *sp, struct object *src, struct object *target);
typedef void storage_trim_f(struct storage *, size_t size);
typedef void storage_free_f(struct storage *);
- typedef struct object *storage_allocobj_f(struct stevedore *, struct sess *sp,
- unsigned ltot, const struct stv_objsecrets *);
+ typedef struct object *storage_allocobj_f(struct stevedore *,
+ struct worker *wrk, unsigned ltot, const struct stv_objsecrets *);
typedef void storage_close_f(const struct stevedore *);
/* Prototypes for VCL variable responders */
diff --cc bin/varnishtest/tests/i00001.vtc
index 306cc57,0000000..6383a1f
mode 100644,000000..100644
--- a/bin/varnishtest/tests/i00001.vtc
+++ b/bin/varnishtest/tests/i00001.vtc
@@@ -1,271 -1,0 +1,271 @@@
+# $Id$
+
+varnishtest "Test basic conditional requests to backends"
+
+## By default (default_keep = default_grace), cond. requests happen during grace
+
+server s1 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -hdr "ETag: foo" \
+ -body "123456"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ expect req.http.If-None-Match == "foo"
+ txresp -status 304
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_fetch {
+ set beresp.ttl = 0.5s;
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.content-length == 6
+ expect resp.bodylen == 6
+ expect resp.http.Age == 0
+} -run
+
+delay 0.6
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s1 -wait
+varnish v1 -stop
+
+## With keep > 0, using both If-Modified-Since and If-None-Match
+
+server s1 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -hdr "ETag: foo" \
+ -body "123456"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ expect req.http.If-None-Match == "foo"
+ txresp -status 304
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ expect req.http.If-None-Match == "foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Wed, 27 Jun 2008 12:00:01 GMT" \
+ -hdr "ETag: foo" \
+ -body "ABCDEF"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Wed, 27 Jun 2008 12:00:01 GMT"
+ expect req.http.If-None-Match == "foo"
+ txresp -status 304
+
+} -start
+
+varnish v1 -vcl {
+ backend s1 {
+ .host = "${s1_addr}"; .port = "${s1_port}";
+ }
+
+ sub vcl_fetch {
+ set beresp.http.X-Original-Keep = beresp.keep;
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ set beresp.keep = 1m;
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.ETag == "foo"
+ expect resp.http.content-length == 6
+ expect resp.bodylen == 6
+ expect resp.http.Age == 0
+ expect resp.http.X-Original-Keep == 10.000
+}
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 2
- varnish v1 -expect cond_not_validated == 1
++varnish v1 -expect fetch_not_validated == 1
+
+server s1 -wait
+varnish v1 -stop
+
+## Just If-Modified-Since
+
+server s1 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "123456"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 304
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 200 \
+ -hdr "Last-Modified: Wed, 27 Jun 2008 12:00:01 GMT" \
+ -body "ABCDEF"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Wed, 27 Jun 2008 12:00:01 GMT"
+ txresp -status 304
+
+} -start
+
+varnish v1 -vcl {
+ backend s1 {
+ .host = "${s1_addr}"; .port = "${s1_port}";
+ }
+ sub vcl_fetch {
+ set beresp.http.X-Original-Keep = beresp.keep;
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ set beresp.keep = 1m;
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.content-length == 6
+ expect resp.bodylen == 6
+ expect resp.http.Age == 0
+ expect resp.http.X-Original-Keep == 10.000
+}
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 2
- varnish v1 -expect cond_not_validated == 1
++varnish v1 -expect fetch_not_validated == 1
+
+server s1 -wait
+varnish v1 -stop
+
+## Just If-None-Match
+
+server s1 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "ETag: foo" \
+ -body "123456"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-None-Match == "foo"
+ txresp -status 304
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-None-Match == "foo"
+ txresp -status 200 \
+ -hdr "ETag: bar" \
+ -body "ABCDEF"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-None-Match == "bar"
+ txresp -status 304
+
+} -start
+
+varnish v1 -vcl {
+ backend s1 {
+ .host = "${s1_addr}"; .port = "${s1_port}";
+ }
+ sub vcl_fetch {
+ set beresp.http.X-Original-Keep = beresp.keep;
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ set beresp.keep = 1m;
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.ETag == "foo"
+ expect resp.http.content-length == 6
+ expect resp.bodylen == 6
+ expect resp.http.Age == 0
+ expect resp.http.X-Original-Keep == 10.000
+}
+
+client c2 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.ETag == "bar"
+ expect resp.http.content-length == 6
+ expect resp.bodylen == 6
+ expect resp.http.Age == 0
+ expect resp.http.X-Original-Keep == 10.000
+}
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+delay 1.1
+
+client c2 -run
+
+delay 1.1
+
+client c2 -run
+
+varnish v1 -expect fetch_304 == 2
- varnish v1 -expect cond_not_validated == 1
++varnish v1 -expect fetch_not_validated == 1
diff --cc bin/varnishtest/tests/i00003.vtc
index 293e843,0000000..fb66266
mode 100644,000000..100644
--- a/bin/varnishtest/tests/i00003.vtc
+++ b/bin/varnishtest/tests/i00003.vtc
@@@ -1,146 -1,0 +1,146 @@@
+# $Id$
+
+varnishtest "Test some anticipated use cases for conditional backend requests"
+
+## In vcl_miss(), it is possible to veto a conditional request by removing any
+## If-Modified-Since or If-None-Match header.
+
+server s1 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -hdr "ETag: foo" \
+ -body "abcdefghijklmonpqrstuvwxyz"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT"
+ expect req.http.If-None-Match != "foo"
+ txresp -status 200 -body "abcdefghijklmonpqrstuvwxyz"
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_fetch {
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ set beresp.keep = 1m;
+ }
+
+ sub vcl_miss {
+ unset bereq.http.If-Modified-Since;
+ unset bereq.http.If-None-Match;
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.content-length == 26
+}
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 0
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s1 -wait
+varnish v1 -stop
+
+## Verify that if a client sends a conditional request to Varnish, then Varnish
+## can return a 304 response to the client after it got 304 from the backend
+
+server s2 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 304
+} -start
+
+varnish v1 -vcl {
+ backend s2 {
+ .host = "${s2_addr}"; .port = "${s2_port}";
+ }
+
+ sub vcl_fetch {
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ set beresp.keep = 1m;
+ }
+} -start
+
+client c2 {
+ txreq -url "/foo" \
+ -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:01 GMT"
+ rxresp
+ expect resp.status == 304
+}
+
+client c1 -run
+
+delay 1.1
+
+client c2 -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s2 -wait
+varnish v1 -stop
+
+##
+## If stale_obj has a gzipped body, make sure it interacts correctly with clients
+##
+
+server s2 {
+ rxreq
+ expect req.http.accept-encoding == "gzip"
+ txresp -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" -gzipbody FOO
+
+ rxreq
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 304
+} -start
+
+varnish v1 -cliok "param.set http_gzip_support true" -vcl {
+ backend s2 {
+ .host = "${s2_addr}"; .port = "${s2_port}";
+ }
+
+ sub vcl_fetch {
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ set beresp.keep = 1m;
+ }
+} -start
+
+client c1 {
+ txreq -hdr "Accept-encoding: gzip;q=0.1"
+ rxresp
+ expect resp.http.content-encoding == "gzip"
+ gunzip
+ expect resp.bodylen == "3"
+} -run
+
+delay 1.1
+
+client c2 {
+ txreq
+ rxresp
+ expect resp.bodylen == "3"
+ expect resp.http.content-encoding != "gzip"
+} -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
diff --cc bin/varnishtest/tests/i00004.vtc
index bb70176,0000000..77fb9a6
mode 100644,000000..100644
--- a/bin/varnishtest/tests/i00004.vtc
+++ b/bin/varnishtest/tests/i00004.vtc
@@@ -1,201 -1,0 +1,201 @@@
+# $Id$
+
+varnishtest "Verify the semantics of keep (timeout for conditional requests)"
+
+server s1 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "foo bar baz quux"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 304
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 200 -body "foo bar baz quux"
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_fetch {
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.content-length == 16
+ expect resp.http.Age == 0
+}
+
+varnish v1 -cli "param.set default_keep 1"
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+delay 2.1
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s1 -wait
+varnish v1 -stop
+
+## Start a new varnish (now using the default default_keep),
+## and manipulate beresp.keep in VCL
+
+server s1 -start
+
+varnish v1 -vcl {
+ backend s1 {
+ .host = "${s1_addr}"; .port = "${s1_port}";
+ }
+
+ sub vcl_fetch {
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ set beresp.keep = 1s;
+ }
+} -start
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+delay 2.1
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s1 -wait
+varnish v1 -stop
+
+## Manipulate obj.keep in vcl_hit()
+
+server s1 -start
+
+varnish v1 -vcl {
+ backend s1 {
+ .host = "${s1_addr}"; .port = "${s1_port}";
+ }
+
+ sub vcl_fetch {
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ }
+
+ sub vcl_hit {
+ set obj.keep = 1s;
+ }
+} -start
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+delay 2.1
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s1 -wait
+varnish v1 -stop
+
+## Manipulate obj.keep in vcl_error()
+
+server s1 -start
+
+varnish v1 -vcl {
+ backend s1 {
+ .host = "${s1_addr}"; .port = "${s1_port}";
+ }
+
+ sub vcl_fetch {
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ }
+
+ sub vcl_hit {
+ error 200 "Ok";
+ }
+
+ sub vcl_error {
+ set obj.keep = 1s;
+ return(deliver);
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+}
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+delay 2.1
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s1 -wait
+varnish v1 -stop
+
+## req.keep sets an upper bound for all *.keeps in a session
+
+server s1 -start
+
+varnish v1 -vcl {
+ backend s1 {
+ .host = "${s1_addr}"; .port = "${s1_port}";
+ }
+
+ sub vcl_recv {
+ set req.keep = 0.5s;
+ }
+
+ sub vcl_fetch {
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ set beresp.keep = 1s;
+ }
+} -start
+
+client c1 -run
+
+delay 1.1
+
+client c1 -run
+
+delay 1.6
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
diff --cc bin/varnishtest/tests/i00005.vtc
index 983afb2,0000000..7f16892
mode 100644,000000..100644
--- a/bin/varnishtest/tests/i00005.vtc
+++ b/bin/varnishtest/tests/i00005.vtc
@@@ -1,147 -1,0 +1,147 @@@
+# $Id$
+
+varnishtest "Verify interactions of ttl, keep, grace and bans"
+
+## Banned objects are not used for conditional requests
+
+server s1 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "The quick brown fox jumps over the lazy dog."
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 200 -body "The quick brown fox jumps over the lazy dog."
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_fetch {
+ set beresp.grace = 0s;
+ set beresp.ttl = 1s;
+ set beresp.keep = 1m;
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 44
+}
+
+client c1 -run
+
+delay 1.1
+
+varnish v1 -cli "ban.url \"/foo\""
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 0
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s1 -wait
+varnish v1 -stop
+
+## If keep is set to non-zero, but then ttl is set to 0,
+## then the object is not used for conditional requests
+
+server s1 -start
+
+varnish v1 -vcl {
+ backend s2 {
+ .host = "${s1_addr}"; .port = "${s1_port}";
+ }
+
+ sub vcl_fetch {
+ set beresp.keep = 1m;
+ set beresp.ttl = 0s;
+ }
+} -start
+
+client c1 -run
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 0
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s1 -wait
+varnish v1 -stop
+
+## If ttl is set to 0 but keep is then set to non-zero,
+## then the object is used for conditional requests
+## First test using beresp in vcl_fetch()
+
+server s2 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "The quick brown fox jumps over the lazy dog."
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 304
+} -start
+
+varnish v1 -vcl {
+ backend s2 {
+ .host = "${s2_addr}"; .port = "${s2_port}";
+ }
+
+ # NB: return(deliver) necessary here, because default vcl_fetch() returns
+ # hit_for_pass if beresp.ttl <= 0
+ sub vcl_fetch {
+ set beresp.ttl = 0s;
+ set beresp.keep = 1m;
+ return (deliver);
+ }
+} -start
+
+client c2 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 44
+} -run
+
+delay 0.5
+
+client c2 -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s2 -wait
+varnish v1 -stop
+
+## Verify using obj.ttl in vcl_hit()
+
+server s2 -start
+
+varnish v1 -vcl {
+ backend s2 {
+ .host = "${s2_addr}"; .port = "${s2_port}";
+ }
+
+ sub vcl_hit {
+ set obj.ttl = 0s;
+ set obj.keep = 1m;
+ }
+} -start
+
+client c1 -run
+
+client c1 -run
+
+delay 0.5
+
+client c1 -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
diff --cc bin/varnishtest/tests/i00006.vtc
index db15078,0000000..5059a17
mode 100644,000000..100644
--- a/bin/varnishtest/tests/i00006.vtc
+++ b/bin/varnishtest/tests/i00006.vtc
@@@ -1,156 -1,0 +1,156 @@@
+# $Id$
+
+varnishtest "Verify effects of ttl, keep and grace on expiration"
+
+## Verify that an object's lifetime in the cache is
+## obj.ttl + max(obj.grace, obj.keep)
+## First with grace < keep
+
+server s1 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "fred garply waldo xyzzy"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 304
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 200 -body "fred garply waldo xyzzy"
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_fetch {
+ set beresp.ttl = 0.5s;
+ set beresp.grace = 0.5s;
+ set beresp.keep = 1s;
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 23
+} -run
+
+delay 1.1
+
+client c2 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 23
+ expect resp.msg == "Ok Not Modified"
+} -run
+
+delay 1.6
+
+client c3 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.msg == "Ok"
+} -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s1 -wait
+varnish v1 -stop
+
+## Now with keep < grace
+
+server s1 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "fred garply waldo xyzzy"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 304
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 200 -body "fred garply waldo xyzzy"
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_fetch {
+ set beresp.ttl = 1s;
+ set beresp.grace = 1s;
+ set beresp.keep = 0.5s;
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 23
+} -run
+
+delay 1.1
+
+client c2 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 23
+ expect resp.msg == "Ok Not Modified"
+} -run
+
+delay 1.6
+
+client c3 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.msg == "Ok"
+} -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
+
+server s1 -wait
+varnish v1 -stop
+
+## Verify that req.keep sets an upper bound in the session
+
+server s1 -start
+
+varnish v1 -vcl {
+ backend s1 {
+ .host = "${s1_addr}"; .port = "${s1_port}";
+ }
+
+ sub vcl_recv {
+ set req.keep = 1s;
+ }
+
+ sub vcl_fetch {
+ set beresp.ttl = 1s;
+ set beresp.grace = 0s;
+ set beresp.keep = 2s;
+ }
+} -start
+
+client c1 -run
+
+delay 1.1
+
+client c2 -run
+
+delay 2.1
+
+client c3 -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 0
++varnish v1 -expect fetch_not_validated == 0
diff --cc bin/varnishtest/tests/i00007.vtc
index 4a9b8c0,0000000..74bb596
mode 100644,000000..100644
--- a/bin/varnishtest/tests/i00007.vtc
+++ b/bin/varnishtest/tests/i00007.vtc
@@@ -1,129 -1,0 +1,129 @@@
+# $Id$
+
+varnishtest "Passes through responses to backend conditionals to the client if status != 304 or 200"
+
+# Testing a sample from each of the Nxx status codes
+
+server s1 {
+ rxreq
+ expect req.url == "/foo"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "Varnish has poked you"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 304
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 201 -msg "Created" \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "Varnish has poked you"
+
+ # 3xx responses typically do not include Last-Modified or a body
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 301 -msg "Moved Permanently"
+
+ # Restore a cached object with Last-Modified
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "Varnish has poked you"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 400 -msg "Bad Request" \
+ -body "Varnish has poked you"
+
+ # Restore a cached object with Last-Modified
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since != "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 200 \
+ -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+ -body "Varnish has poked you"
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.If-Modified-Since == "Thu, 26 Jun 2008 12:00:01 GMT"
+ txresp -status 500 -msg "Internal Server Error" \
+ -body "Varnish has poked you"
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_fetch {
+ set beresp.ttl = 1s;
+ set beresp.grace = 0s;
+ set beresp.keep = 1s;
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 21
+} -run
+
+delay 1.1
+
+client c1 -run
+
+delay 1.1
+
+client c2 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 201
+ expect resp.msg == "Created"
+ expect resp.http.Last-Modified == "Thu, 26 Jun 2008 12:00:01 GMT"
+ expect resp.bodylen == 21
+} -run
+
+delay 1.1
+
+client c2 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 301
+ expect resp.msg == "Moved Permanently"
+} -run
+
+delay 1.1
+
+client c1 -run
+
+delay 1.1
+
+client c2 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 400
+ expect resp.msg == "Bad Request"
+ expect resp.bodylen == 21
+} -run
+
+delay 1.1
+
+client c1 -run
+
+delay 1.1
+
+client c2 {
+ txreq -url "/foo"
+ rxresp
+ expect resp.status == 500
+ expect resp.msg == "Internal Server Error"
+ expect resp.bodylen == 21
+} -run
+
+varnish v1 -expect fetch_304 == 1
- varnish v1 -expect cond_not_validated == 4
++varnish v1 -expect fetch_not_validated == 4
diff --cc include/tbl/vsc_f_main.h
index 0000000,ab8415c..5b9abf6
mode 000000,100644..100644
--- a/include/tbl/vsc_f_main.h
+++ b/include/tbl/vsc_f_main.h
@@@ -1,0 -1,410 +1,412 @@@
+ /*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2011 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION, "")
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Definition of all shared memory statistics below.
+ *
+ * Fields (n, t, l, f, e, d):
+ * n - Name: Field name, in C-source and stats programs
+ * t - Type: C-type, uint64_t, unless marked in 'f'
+ * l - Local: Local counter in worker thread.
+ * f - Format: Semantics of the value in this field
+ * 'a' - Accumulator (deprecated, use 'c')
+ * 'b' - Bitmap
+ * 'c' - Counter, never decreases.
+ * 'g' - Gauge, goes up and down
+ * 'i' - Integer (deprecated, use 'g')
+ * e - Explantion: Short explanation of field (for screen use)
+ * d - Description: Long explanation of field (for doc use)
+ *
+ * Please describe Gauge variables as "Number of..." to indicate that
+ * this is a snapshot, and Counter variables as "Count of" to indicate
+ * accumulative count.
+ *
+ * -----------------------
+ * NB: Cleanup in progress
+ * -----------------------
+ *
+ * Insufficient attention has caused this to become a swamp of conflicting
+ * conventions, shorthands and general mumbo-jumbo. I'm trying to clean
+ * it up as I go over the code in other business.
+ *
+ * Please see the sessmem section for how it should look.
+ *
+ */
+
+ /*---------------------------------------------------------------------
+ * Sessions
+ * see: cache_acceptor.c and cache_pool.c
+ */
+
+ VSC_F(sess_conn, uint64_t, 1, 'c',
+ "Sessions accepted",
+ "Count of sessions succesfully accepted"
+ )
+ VSC_F(sess_drop, uint64_t, 1, 'c',
+ "Sessions dropped",
+ "Count of sessions silently dropped due to lack of session memory."
+ " See parameter 'max_sess'."
+ )
+
+ VSC_F(sess_fail, uint64_t, 1, 'c',
+ "Session accept failures",
+ "Count of failures to accept TCP connection."
+ " Either the client changed its mind, or the kernel ran out of"
+ " some resource like filedescriptors."
+ )
+
+ /*---------------------------------------------------------------------*/
+
+ VSC_F(client_req, uint64_t, 1, 'a',
+ "Client requests received",
+ "")
+
+ VSC_F(cache_hit, uint64_t, 1, 'a',
+ "Cache hits",
+ "Count of cache hits. "
+ " A cache hit indicates that an object has been delivered to a"
+ " client without fetching it from a backend server."
+ )
+
+ VSC_F(cache_hitpass, uint64_t, 1, 'a',
+ "Cache hits for pass",
+ "Count of hits for pass"
+ " A cache hit for pass indicates that Varnish is going to"
+ " pass the request to the backend and this decision has been "
+ " cached in it self. This counts how many times the cached "
+ " decision is being used."
+ )
+ VSC_F(cache_miss, uint64_t, 1, 'a',
+ "Cache misses",
+ "Count of misses"
+ " A cache miss indicates the object was fetched from the"
+ " backend before delivering it to the backend.")
+
+ VSC_F(backend_conn, uint64_t, 0, 'a',
+ "Backend conn. success",
+ "")
+
+ VSC_F(backend_unhealthy, uint64_t, 0, 'a',
+ "Backend conn. not attempted",
+ ""
+ )
+ VSC_F(backend_busy, uint64_t, 0, 'a', "Backend conn. too many", "")
+ VSC_F(backend_fail, uint64_t, 0, 'a', "Backend conn. failures", "")
+ VSC_F(backend_reuse, uint64_t, 0, 'a',
+ "Backend conn. reuses",
+ "Count of backend connection reuses"
+ " This counter is increased whenever we reuse a recycled connection.")
+ VSC_F(backend_toolate, uint64_t, 0, 'a', "Backend conn. was closed", "")
+ VSC_F(backend_recycle, uint64_t, 0, 'a',
+ "Backend conn. recycles",
+ "Count of backend connection recycles"
+ " This counter is increased whenever we have a keep-alive"
+ " connection that is put back into the pool of connections."
+ " It has not yet been used, but it might be, unless the backend"
+ " closes it.")
+ VSC_F(backend_retry, uint64_t, 0, 'a', "Backend conn. retry", "")
+
+ VSC_F(fetch_head, uint64_t, 1, 'a', "Fetch head", "")
+ VSC_F(fetch_length, uint64_t, 1, 'a', "Fetch with Length", "")
+ VSC_F(fetch_chunked, uint64_t, 1, 'a', "Fetch chunked", "")
+ VSC_F(fetch_eof, uint64_t, 1, 'a', "Fetch EOF", "")
+ VSC_F(fetch_bad, uint64_t, 1, 'a', "Fetch had bad headers", "")
+ VSC_F(fetch_close, uint64_t, 1, 'a', "Fetch wanted close", "")
+ VSC_F(fetch_oldhttp, uint64_t, 1, 'a', "Fetch pre HTTP/1.1 closed", "")
+ VSC_F(fetch_zero, uint64_t, 1, 'a', "Fetch zero len", "")
+ VSC_F(fetch_failed, uint64_t, 1, 'a', "Fetch failed", "")
+ VSC_F(fetch_1xx, uint64_t, 1, 'a', "Fetch no body (1xx)", "")
+ VSC_F(fetch_204, uint64_t, 1, 'a', "Fetch no body (204)", "")
+ VSC_F(fetch_304, uint64_t, 1, 'a', "Fetch no body (304)", "")
++VSC_F(fetch_not_validated, uint64_t, 1, 'c', "Non-validating responses",
++ "Count of backend responses to conditional requests with status != 304")
+
+ /*---------------------------------------------------------------------
+ * Session Memory
+ * see: cache_session.c
+ */
+
+ VSC_F(sessmem_size, uint64_t, 1, 'g',
+ "Session mem size",
+ "Bytes of memory allocated for last allocated session."
+ )
+
+ VSC_F(sessmem_alloc, uint64_t, 1, 'c',
+ "Session mem allocated",
+ "Count of all allocations of session memory."
+ )
+
+ VSC_F(sessmem_free, uint64_t, 1, 'c',
+ "Session mem freed",
+ "Count of all frees of session memory."
+ )
+
+ VSC_F(sessmem_fail, uint64_t, 1, 'c',
+ "Session mem alloc failed",
+ "Count of session memory allocation failures."
+ )
+
+ VSC_F(sessmem_limit, uint64_t, 1, 'c',
+ "Session mem alloc limited",
+ "Count of session memory allocations blocked by limit (max_sess)."
+ )
+
+ /*---------------------------------------------------------------------
+ * Pools, threads, and sessions
+ * see: cache_pool.c
+ *
+ */
+
+ VSC_F(pools, uint64_t, 1, 'g',
+ "Number of thread pools",
+ "Number of thread pools. See also param wthread_pools."
+ " NB: Presently pools cannot be removed once created."
+ )
+
+ VSC_F(threads, uint64_t, 1, 'g',
+ "Total number of threads",
+ "Number of threads in all pools."
+ " See also params thread_pools, thread_pool_min & thread_pool_max."
+ )
+
+ VSC_F(threads_limited, uint64_t, 1, 'c',
+ "Threads hit max",
+ "Number of times more threads were needed, but limit was reached"
+ " in a thread pool."
+ " See also param thread_pool_max."
+ )
+
+ VSC_F(threads_created, uint64_t, 1, 'c',
+ "Threads created",
+ "Total number of threads created in all pools."
+ )
+
+ VSC_F(threads_destroyed, uint64_t, 1, 'c',
+ "Threads destoryed",
+ "Total number of threads destroyed in all pools."
+ )
+
+ VSC_F(threads_failed, uint64_t, 1, 'c',
+ "Thread creation failed",
+ "Number of times creating a thread failed."
+ " See VSL::Debug for diagnostics."
+ " See also param thread_fail_delay."
+ )
+
+ VSC_F(thread_queue_len, uint64_t, 1, 'g',
+ "Length of session queue",
+ "Length of session queue waiting for threads."
+ " NB: Only updates once per second."
+ " See also param queue_max."
+ )
+
+ VSC_F(sess_queued, uint64_t, 1, 'c',
+ "Sessions queued for thread",
+ "Number of times session was queued waiting for a thread."
+ " See also param queue_max."
+ )
+
+ VSC_F(sess_dropped, uint64_t, 1, 'c',
+ "Sessions dropped for thread",
+ "Number of times session was dropped because the queue were too"
+ " long already."
+ " See also param queue_max."
+ )
+
+ /*---------------------------------------------------------------------
+ * BusyObj
+ */
+
+ VSC_F(busyobj_alloc, uint64_t, 1, 'c',
+ "Busyobj allocations",
+ "Number of busyobj structures allocated."
+ )
+
+ VSC_F(busyobj_free, uint64_t, 1, 'c',
+ "Busyobj freed",
+ "Number of busyobj structures freed."
+ )
+
+ /*---------------------------------------------------------------------*/
+
+ VSC_F(n_sess_mem, uint64_t, 0, 'i', "N struct sess_mem", "")
+ VSC_F(n_sess, uint64_t, 0, 'i', "N struct sess", "")
+ VSC_F(n_object, uint64_t, 1, 'i', "N struct object", "")
+ VSC_F(n_vampireobject, uint64_t, 1, 'i', "N unresurrected objects", "")
+ VSC_F(n_objectcore, uint64_t, 1, 'i', "N struct objectcore", "")
+ VSC_F(n_objecthead, uint64_t, 1, 'i', "N struct objecthead", "")
+ VSC_F(n_waitinglist, uint64_t, 1, 'i', "N struct waitinglist", "")
+
+ VSC_F(n_vbc, uint64_t, 0, 'i', "N struct vbc", "")
+
+ VSC_F(n_backend, uint64_t, 0, 'i', "N backends", "")
+
+ VSC_F(n_expired, uint64_t, 0, 'i', "N expired objects", "")
+ VSC_F(n_lru_nuked, uint64_t, 0, 'i', "N LRU nuked objects", "")
+ VSC_F(n_lru_moved, uint64_t, 0, 'i', "N LRU moved objects", "")
+
+ VSC_F(losthdr, uint64_t, 0, 'a', "HTTP header overflows", "")
+
+ VSC_F(n_objsendfile, uint64_t, 0, 'a', "Objects sent with sendfile",
+ "The number of objects sent with the sendfile system call. If enabled "
+ "sendfile will be used on object larger than a certain size.")
+ VSC_F(n_objwrite, uint64_t, 0, 'a', "Objects sent with write",
+ "The number of objects sent with regular write calls."
+ "Writes are used when the objects are too small for sendfile "
+ "or if the sendfile call has been disabled")
+ VSC_F(n_objoverflow, uint64_t, 1, 'a',
+ "Objects overflowing workspace", "")
+
+ VSC_F(s_sess, uint64_t, 1, 'a', "Total Sessions", "")
+ VSC_F(s_req, uint64_t, 1, 'a', "Total Requests", "")
+ VSC_F(s_pipe, uint64_t, 1, 'a', "Total pipe", "")
+ VSC_F(s_pass, uint64_t, 1, 'a', "Total pass", "")
+ VSC_F(s_fetch, uint64_t, 1, 'a', "Total fetch", "")
+ VSC_F(s_hdrbytes, uint64_t, 1, 'a', "Total header bytes", "")
+ VSC_F(s_bodybytes, uint64_t, 1, 'a', "Total body bytes", "")
+
+ VSC_F(sess_closed, uint64_t, 1, 'a', "Session Closed", "")
+ VSC_F(sess_pipeline, uint64_t, 1, 'a', "Session Pipeline", "")
+ VSC_F(sess_readahead, uint64_t, 1, 'a', "Session Read Ahead", "")
+ VSC_F(sess_linger, uint64_t, 1, 'a', "Session Linger", "")
+ VSC_F(sess_herd, uint64_t, 1, 'a', "Session herd", "")
+
+ VSC_F(shm_records, uint64_t, 0, 'a', "SHM records", "")
+ VSC_F(shm_writes, uint64_t, 0, 'a', "SHM writes", "")
+ VSC_F(shm_flushes, uint64_t, 0, 'a', "SHM flushes due to overflow", "")
+ VSC_F(shm_cont, uint64_t, 0, 'a', "SHM MTX contention", "")
+ VSC_F(shm_cycles, uint64_t, 0, 'a', "SHM cycles through buffer", "")
+
+ VSC_F(sms_nreq, uint64_t, 0, 'a', "SMS allocator requests", "")
+ VSC_F(sms_nobj, uint64_t, 0, 'i', "SMS outstanding allocations", "")
+ VSC_F(sms_nbytes, uint64_t, 0, 'i', "SMS outstanding bytes", "")
+ VSC_F(sms_balloc, uint64_t, 0, 'i', "SMS bytes allocated", "")
+ VSC_F(sms_bfree, uint64_t, 0, 'i', "SMS bytes freed", "")
+
+ VSC_F(backend_req, uint64_t, 0, 'a', "Backend requests made", "")
+
+ VSC_F(n_vcl, uint64_t, 0, 'a', "N vcl total", "")
+ VSC_F(n_vcl_avail, uint64_t, 0, 'a', "N vcl available", "")
+ VSC_F(n_vcl_discard, uint64_t, 0, 'a', "N vcl discarded", "")
+
+ /**********************************************************************/
+
+ VSC_F(bans, uint64_t, 0, 'g',
+ "Count of bans",
+ "Number of all bans in system, including bans superseded"
+ " by newer bans and bans already checked by the ban-lurker."
+ )
+ VSC_F(bans_gone, uint64_t, 0, 'g',
+ "Number of bans marked 'gone'",
+ "Number of bans which are no longer active, either because they"
+ " got checked by the ban-lurker or superseded by newer identical bans."
+ )
+ VSC_F(bans_req, uint64_t, 0, 'g',
+ "Number of bans using req.*",
+ "Number of bans which use req.* variables. These bans can not"
+ " be washed by the ban-lurker."
+ )
+ VSC_F(bans_added, uint64_t, 0, 'c',
+ "Bans added",
+ "Counter of bans added to ban list."
+ )
+ VSC_F(bans_deleted, uint64_t, 0, 'c',
+ "Bans deleted",
+ "Counter of bans deleted from ban list."
+ )
+
+ VSC_F(bans_tested, uint64_t, 0, 'c',
+ "Bans tested against objects",
+ "Count of how many bans and objects have been tested against"
+ " each other."
+ )
+ VSC_F(bans_tests_tested, uint64_t, 0, 'c',
+ "Ban tests tested against objects",
+ "Count of how many tests and objects have been tested against"
+ " each other. 'ban req.url == foo && req.http.host == bar'"
+ " counts as one in 'bans_tested' and as two in 'bans_tests_tested'"
+ )
+ VSC_F(bans_dups, uint64_t, 0, 'c',
+ "Bans superseded by other bans",
+ "Count of bans replaced by later identical bans."
+ )
+
+ /**********************************************************************/
+
+ VSC_F(hcb_nolock, uint64_t, 0, 'a', "HCB Lookups without lock", "")
+ VSC_F(hcb_lock, uint64_t, 0, 'a', "HCB Lookups with lock", "")
+ VSC_F(hcb_insert, uint64_t, 0, 'a', "HCB Inserts", "")
+
+ VSC_F(esi_errors, uint64_t, 0, 'a', "ESI parse errors (unlock)", "")
+ VSC_F(esi_warnings, uint64_t, 0, 'a', "ESI parse warnings (unlock)", "")
+ VSC_F(client_drop_late, uint64_t, 0, 'a', "Connection dropped late", "")
+ VSC_F(uptime, uint64_t, 0, 'a', "Client uptime", "")
+
+ VSC_F(dir_dns_lookups, uint64_t, 0, 'a', "DNS director lookups", "")
+ VSC_F(dir_dns_failed, uint64_t, 0, 'a', "DNS director failed lookups", "")
+ VSC_F(dir_dns_hit, uint64_t, 0, 'a', "DNS director cached lookups hit", "")
+ VSC_F(dir_dns_cache_full, uint64_t, 0, 'a', "DNS director full dnscache", "")
+
+ VSC_F(vmods, uint64_t, 0, 'i', "Loaded VMODs", "")
+
+ VSC_F(n_gzip, uint64_t, 0, 'a', "Gzip operations", "")
+ VSC_F(n_gunzip, uint64_t, 0, 'a', "Gunzip operations", "")
+
+ /**********************************************************************/
+
+ VSC_F(vsm_free, uint64_t, 0, 'g',
+ "Free VSM space",
+ "Number of bytes free in the shared memory used to communicate"
+ " with tools like varnishstat, varnishlog etc."
+ )
+
+ VSC_F(vsm_used, uint64_t, 0, 'g',
+ "Used VSM space",
+ "Number of bytes used in the shared memory used to communicate"
+ " with tools like varnishstat, varnishlog etc."
+ )
+
+ VSC_F(vsm_cooling, uint64_t, 0, 'g',
+ "Cooling VSM space",
+ "Number of bytes which will soon (max 1 minute) be freed"
+ " in the shared memory used to communicate"
+ " with tools like varnishstat, varnishlog etc."
+ )
+
+ VSC_F(vsm_overflow, uint64_t, 0, 'g',
+ "Overflow VSM space",
+ "Number of bytes which does not fit"
+ " in the shared memory used to communicate"
+ " with tools like varnishstat, varnishlog etc."
+ )
+
+ VSC_F(vsm_overflowed, uint64_t, 0, 'c',
+ "Overflowed VSM space",
+ "Total number of bytes which did not fit"
+ " in the shared memory used to communicate"
+ " with tools like varnishstat, varnishlog etc."
+ )
More information about the varnish-commit
mailing list