[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