[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