[experimental-ims] f1dfb81 Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache into experimental-ims

Geoff Simmons geoff at varnish-cache.org
Tue Feb 14 17:49:35 CET 2012


commit f1dfb81ad5f1ef6e6818fef892223caac6609f99
Merge: 99f0d07 d2b5440
Author: Geoff Simmons <geoff at uplex.de>
Date:   Tue Feb 14 17:11:17 2012 +0100

    Merge branch 'master' of ssh://git.varnish-cache.org/git/varnish-cache into experimental-ims
    
    Also calling http_CopyHome(beresp) to ensure that header contents are copied from stale_obj
    into beresp (pointed out by phk).

diff --cc bin/varnishd/cache/cache.h
index 4009337,42788c3..52aaaa5
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@@ -811,27 -803,17 +805,23 @@@ unsigned http_Write(struct worker *w, c
  void http_SetResp(struct http *to, const char *proto, uint16_t status,
      const char *response);
  void http_FilterReq(const struct sess *sp, unsigned how);
- void http_FilterResp(const struct sess *sp, const struct http *fm, struct http *to,
-     unsigned how);
+ void http_FilterResp(const struct http *fm, struct http *to, unsigned how);
+ void http_PutProtocol(const struct http *to, const char *protocol);
 +
 +/* Check if a refresh should be done */
 +void http_CheckRefresh(struct sess *sp);
 +/* Check if we got 304 response */
 +void http_Check304(struct sess *sp, struct busyobj *busyobj);
 +
- void http_PutProtocol(struct worker *w, unsigned vsl_id, const struct http *to,
-     const char *protocol);
  void http_PutStatus(struct http *to, uint16_t status);
- void http_PutResponse(struct worker *w, unsigned vsl_id, const struct http *to,
-     const char *response);
- void http_PrintfHeader(struct worker *w, unsigned vsl_id, struct http *to,
-     const char *fmt, ...)
-     __printflike(4, 5);
- void http_SetHeader(struct worker *w, unsigned vsl_id, struct http *to,
-     const char *hdr);
+ void http_PutResponse(const struct http *to, const char *response);
+ void http_PrintfHeader(struct http *to, const char *fmt, ...)
+     __printflike(2, 3);
+ void http_SetHeader(struct http *to, const char *hdr);
  void http_SetH(const struct http *to, unsigned n, const char *fm);
  void http_ForceGet(const struct http *to);
- void http_Setup(struct http *ht, struct ws *ws);
+ void http_Setup(struct http *ht, struct ws *ws, struct vsl_log *);
+ void http_Teardown(struct http *ht);
  int http_GetHdr(const struct http *hp, const char *hdr, char **ptr);
  int http_GetHdrData(const struct http *hp, const char *hdr,
      const char *field, char **ptr);
diff --cc bin/varnishd/cache/cache_center.c
index f46a68c,0be9304..c86a301
--- a/bin/varnishd/cache/cache_center.c
+++ b/bin/varnishd/cache/cache_center.c
@@@ -862,11 -836,10 +860,11 @@@ cnt_prepfetch(struct sess *sp, struct w
  	hp2 = req->obj->http;
  
  	hp2->logtag = HTTP_Obj;
- 	http_FilterResp(sp, hp, hp2, pass ? HTTPH_R_PASS : HTTPH_A_INS);
- 	http_CopyHome(wrk, sp->vsl_id, hp2);
+ 	http_FilterResp(hp, hp2, pass ? HTTPH_R_PASS : HTTPH_A_INS);
+ 	http_CopyHome(hp2);
  
 -	if (http_GetHdr(hp, H_Last_Modified, &b))
 +	if (http_GetHdr(hp, H_Last_Modified, &b)
 +            || http_GetHdr(req->obj->http, H_Last_Modified, &b))
  		req->obj->last_modified = VTIM_parse(b);
  	else
  		req->obj->last_modified = floor(bo->exp.entered);
@@@ -922,27 -895,8 +920,27 @@@ cnt_fetchbody(struct sess *sp, struct w
  	/* Use unmodified headers*/
  	i = FetchBody(wrk, req->obj);
  
 +	/*
 +	 * If a stale_obj was found, dup its storage into the new obj,
 +	 * reset Content-Length from the size of the storage, and discard
 +	 * the stale_obj.
 +	 */
 +	if (bo->stale_obj) {
 +		STV_dup(sp, bo->stale_obj, req->obj);
 +		assert(bo->stale_obj->len == req->obj->len);
 +		
 +		http_Unset(req->obj->http, H_Content_Length);
- 		http_PrintfHeader(sp->wrk, sp->fd, req->obj->http,
- 		    "Content-Length: %u", req->obj->len);
++		http_PrintfHeader(req->obj->http, "Content-Length: %lu",
++		    req->obj->len);
 +		
 +		EXP_Clr(&bo->stale_obj->exp);
 +		EXP_Rearm(bo->stale_obj);
- 		HSH_Deref(sp->wrk, NULL, &bo->stale_obj);
++		HSH_Deref(&sp->wrk->stats, NULL, &bo->stale_obj);
 +		AZ(bo->stale_obj);
 +	}
 +
- 	http_Setup(bo->bereq, NULL);
- 	http_Setup(bo->beresp, NULL);
+ 	http_Teardown(bo->bereq);
+ 	http_Teardown(bo->beresp);
  	bo->vfp = NULL;
  	assert(WRW_IsReleased(wrk));
  	AZ(bo->vbc);
@@@ -991,11 -945,6 +989,7 @@@ cnt_streambody(struct sess *sp, struct 
  	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
  
  	CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC);
 +	AZ(wrk->busyobj->stale_obj);
- 	memset(&sctx, 0, sizeof sctx);
- 	sctx.magic = STREAM_CTX_MAGIC;
- 	AZ(wrk->sctx);
- 	wrk->sctx = &sctx;
  
  	RES_StreamStart(sp);
  
@@@ -1237,9 -1185,7 +1230,10 @@@ cnt_lookup(struct sess *sp, struct work
  	if (oc->flags & OC_F_PASS) {
  		wrk->stats.cache_hitpass++;
  		WSP(sp, SLT_HitPass, "%u", req->obj->xid);
- 		(void)HSH_Deref(wrk, NULL, &req->obj);
+ 		(void)HSH_Deref(&wrk->stats, NULL, &req->obj);
 +                if (wrk->busyobj != NULL && wrk->busyobj->stale_obj != NULL)
-                     (void)HSH_Deref(wrk, NULL, &wrk->busyobj->stale_obj);
++                    (void)HSH_Deref(&wrk->stats, NULL,
++			&wrk->busyobj->stale_obj);
  		AZ(req->objcore);
  		sp->step = STP_PASS;
  		return (0);
@@@ -1277,11 -1223,7 +1271,9 @@@ cnt_miss(struct sess *sp, struct worke
  	CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC);
  	AZ(req->obj);
  
- 	if (!wrk->busyobj->stale_obj) {
- 		WS_Reset(wrk->ws, NULL);
++	if (!wrk->busyobj->stale_obj)
 +		wrk->busyobj = VBO_GetBusyObj(wrk);
- 	}
- 	http_Setup(wrk->busyobj->bereq, wrk->ws);
+ 	http_Setup(wrk->busyobj->bereq, wrk->busyobj->ws, wrk->busyobj->vsl);
  	http_FilterReq(sp, HTTPH_R_FETCH);
  	http_ForceGet(wrk->busyobj->bereq);
  	if (cache_param->http_gzip_support) {
@@@ -1291,16 -1233,9 +1283,15 @@@
  		 * the minority of clients which don't.
  		 */
  		http_Unset(wrk->busyobj->bereq, H_Accept_Encoding);
- 		http_SetHeader(wrk, sp->vsl_id, wrk->busyobj->bereq,
- 		    "Accept-Encoding: gzip");
+ 		http_SetHeader(wrk->busyobj->bereq, "Accept-Encoding: gzip");
  	}
  
 +        /* If a candidate for a conditional backend request was found,
 +         * add If-Modified-Since and/or If-None-Match to the bereq.
 +         */
 +        if (wrk->busyobj->stale_obj)
 +                http_CheckRefresh(sp);
 +
  	VCL_miss_method(sp);
  
  	if (req->handling == VCL_RET_FETCH) {
diff --cc bin/varnishd/cache/cache_hash.c
index 9585e7a,7188ff4..c13eb70
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@@ -357,11 -353,10 +357,11 @@@ HSH_Lookup(struct sess *sp, struct objh
  			continue;
  		}
  
- 		o = oc_getobj(sp->wrk, oc);
+ 		o = oc_getobj(&sp->wrk->stats, oc);
  		CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
  
 -		if (o->exp.ttl <= 0.)
 +		if (o->exp.ttl <= 0. && o->exp.grace <= 0.
 +		    && o->exp.keep <= 0.)
  			continue;
  		if (BAN_CheckObject(o, sp))
  			continue;
@@@ -477,18 -453,8 +477,19 @@@
  
  	AZ(wrk->busyobj);
  	wrk->busyobj = VBO_GetBusyObj(wrk);
+ 	wrk->busyobj->vsl->wid = sp->vsl_id;
  
 +        /* 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(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++;
 +                wrk->busyobj->stale_obj = stale_o;
 +        }
 +
  	VRY_Validate(sp->req->vary_b);
  	if (sp->req->vary_l != NULL)
  		wrk->busyobj->vary = sp->req->vary_b;
diff --cc bin/varnishd/cache/cache_http.c
index ac922b8,de71ada..03f3974
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@@ -779,25 -784,6 +787,24 @@@ http_SetResp(struct http *to, const cha
  	http_SetH(to, HTTP_HDR_RESPONSE, response);
  }
  
 +static void
- http_copyheader(struct worker *w, unsigned vsl_id, struct http *to,
-     const struct http *fm, unsigned n)
++http_copyheader(struct http *to, const struct http *fm, unsigned n)
 +{
 +
 +	CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC);
 +	CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
 +	assert(n < fm->shd);
 +	Tcheck(fm->hd[n]);
 +	if (to->nhd < to->shd) {
 +		to->hd[to->nhd] = fm->hd[n];
 +		to->hdf[to->nhd] = 0;
 +		to->nhd++;
 +	} else  {
 +		VSC_C_main->losthdr++;
- 		WSLR(w, SLT_LostHeader, vsl_id, fm->hd[n]);
++		WSLR(to->vsl, SLT_LostHeader, -1, fm->hd[n]);
 +	}
 +}
 +
  /*--------------------------------------------------------------------
   * Estimate how much workspace we need to Filter this header according
   * to 'how'.
@@@ -850,38 -835,16 +856,42 @@@ http_filterfields(struct http *to, cons
  			continue;
  #include "tbl/http_headers.h"
  #undef HTTPH
- 		http_copyheader(w, vsl_id, to, fm, u);
 -		Tcheck(fm->hd[u]);
 -		if (to->nhd < to->shd) {
 -			to->hd[to->nhd] = fm->hd[u];
 -			to->hdf[to->nhd] = 0;
 -			to->nhd++;
 -		} else  {
 -			VSC_C_main->losthdr++;
 -			WSLR(to->vsl, SLT_LostHeader, -1, fm->hd[u]);
 -		}
++		http_copyheader(to, fm, u);
 +	}
 +}
 +
 +/*---------------------------------------------------------------------
 + * Same as http_FilterFields but keep any existing hdrs in fm.
 + * Furthermore, before copy, check if fm already has that hdr, and if so
 + * do not copy.  Used for 304 refresh processing.
 + */
 +
 +/* XXX: uplex/GS: Also, don't filter according to the "how" bitmap in
 + *      http_headers.h. We only use this to copy from one cached object to
 + *      another, so if a header made into the first object, we want it.
++ * NB: This assumes that http_EstimateWS(to) has already been called
++ *     (so that http_CopyHome() does not run short of workspace).
 + */
 +
 +void
 +http_FilterMissingFields(struct worker *w, int fd, struct http *to,
 +    const struct http *fm)
 +{
 +	unsigned u;
 +	unsigned hdrlen;
 +
 +	CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC);
 +	CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
 +	for (u = HTTP_HDR_FIRST; u < fm->nhd; u++) {
 +		if (fm->hd[u].b == NULL)
 +			continue;
 +                hdrlen = strchr(fm->hd[u].b, ':') - fm->hd[u].b;
 +                if (http_findhdr(to, hdrlen, fm->hd[u].b))
 +                    continue;
-                 http_copyheader(w, fd, to, fm, u);
++                http_copyheader(to, fm, u);
  	}
++	/* Copy header contents, presupposes http_EstimateWS(to) */
++	http_CopyHome(to);
  }
  
  /*--------------------------------------------------------------------*/
@@@ -901,94 -864,10 +911,94 @@@ http_FilterReq(const struct sess *sp, u
  		http_SetH(hp, HTTP_HDR_PROTO, "HTTP/1.1");
  	else
  		http_linkh(hp, sp->req->http, HTTP_HDR_PROTO);
- 	http_filterfields(sp->wrk, sp->vsl_id, hp, sp->req->http, how);
- 	http_PrintfHeader(sp->wrk, sp->vsl_id, hp,
- 	    "X-Varnish: %u", sp->req->xid);
+ 	http_filterfields(hp, sp->req->http, how);
+ 	http_PrintfHeader(hp, "X-Varnish: %u", sp->req->xid);
  }
  
 +/*-------------------------------------------------------------------
 + * This function checks if a stale_obj was found in HSH_Lookup().
 + * If so, add the appropriate headers for backend validation.
 + */
 +
 +void
 +http_CheckRefresh(struct sess *sp)
 +{
 +	struct object *freshen_obj;
 +	struct http *obj_hp, *bereq_hp;
 +	char *p;
 +
 +	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 +	CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
 +	CHECK_OBJ_NOTNULL(sp->wrk->busyobj, BUSYOBJ_MAGIC);
 +	freshen_obj = sp->wrk->busyobj->stale_obj;
 +	CHECK_OBJ_NOTNULL(freshen_obj, OBJECT_MAGIC);
 +	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);
++		http_PrintfHeader(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);
++		http_PrintfHeader(bereq_hp, "If-Modified-Since: %s", p);
 +}
 +
 +/*-------------------------------------------------------------------
 + * Called after fetch for a backend conditional request.  Check
 + * response and handle as needed.
++ * NB: Assumes that http_EstimateWS(beresp) has already been called
++ *     (in cnt_prepfetch(), while this is called in cnt_fetch()).
 + */
 +
 +void
 +http_Check304(struct sess *sp, struct busyobj *busyobj)
 +{
 +	struct object *o_stale;
 +	char *p;
 +
 +	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 +	CHECK_OBJ_NOTNULL(busyobj, BUSYOBJ_MAGIC);
 +	o_stale = busyobj->stale_obj;
 +	CHECK_OBJ_NOTNULL(o_stale, OBJECT_MAGIC);
 +
 +	if (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(busyobj->bereq, H_If_Modified_Since, &p)
 +		|| http_GetHdr(busyobj->bereq, H_If_None_Match, &p))
 +		sp->wrk->stats.fetch_not_validated++;
 +
 +	    /* Discard the stale object */
 +	    /* XXX: just deref, or force expire? */
- 	    HSH_Deref(sp->wrk, NULL, &busyobj->stale_obj);
++	    HSH_Deref(&sp->wrk->stats, NULL, &busyobj->stale_obj);
 +	    AZ(busyobj->stale_obj);
 +	    return;
 +	}
 +
 +	/* 
 +	 * Copy headers we need from the stale object into the 304 response
++	 * http_EstimateWS(beresp) must have been called before this.
 +	 */
 +	http_FilterMissingFields(sp->wrk, sp->fd, busyobj->beresp,
 +	    o_stale->http);
 +
 +	http_SetResp(busyobj->beresp, "HTTP/1.1", 200, "Ok Not Modified");
 +	http_SetH(busyobj->beresp, HTTP_HDR_REQ, "GET");
 +	http_linkh(busyobj->beresp, 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?
 +	 *      What about do_esi and do_g(un)zip?
 +	 */
 +	busyobj->is_gzip = o_stale->gziped;
 +
 +        AZ(o_stale->objcore->flags & OC_F_BUSY);
 +}
 +
  /*--------------------------------------------------------------------*/
  
  void



More information about the varnish-commit mailing list