
phk at varnish-cache
Aug 8, 2012, 3:06 AM
Post #1 of 1
(60 views)
Permalink
|
|
[master] d9a9ecd Doing rollback in a esi:include request would roll back to the original ESI processed request, rather than to the included requests.
|
|
commit d9a9ecd999f78123ac6ef5dfa8fd4aac38130c26 Author: Poul-Henning Kamp <phk [at] FreeBSD> Date: Wed Aug 8 10:04:57 2012 +0000 Doing rollback in a esi:include request would roll back to the original ESI processed request, rather than to the included requests. Fix by allocating/cloning a new request for the esi:include transactions. Testcase by: scoof Fixes #1168 diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index a6e5f11..daef6a9 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -42,80 +42,93 @@ /*--------------------------------------------------------------------*/ static void -ved_include(struct req *req, const char *src, const char *host) +ved_include(struct req *preq, const char *src, const char *host) { - struct object *obj; struct worker *wrk; - char *sp_ws_wm; + struct req *req; char *wrk_ws_wm; - unsigned sxid, res_mode; int i; - wrk = req->wrk; + wrk = preq->wrk; - if (req->esi_level >= cache_param->max_esi_depth) + if (preq->esi_level >= cache_param->max_esi_depth) return; - req->esi_level++; (void)WRW_FlushRelease(wrk); - obj = req->obj; - req->obj = NULL; - res_mode = req->res_mode; - - /* Reset request to status before we started messing with it */ - HTTP_Copy(req->http, req->http0); - /* Take a workspace snapshot */ - sp_ws_wm = WS_Snapshot(req->ws); wrk_ws_wm = WS_Snapshot(wrk->aws); /* XXX ? */ - http_SetH(req->http, HTTP_HDR_URL, src); + req = SES_GetReq(preq->sp); + req->esi_level = preq->esi_level + 1; + + HTTP_Copy(req->http0, preq->http0); + + req->http0->conds = 0; + + HTTP_Setup(req->http, req->ws, req->vsl, HTTP_Req); + + http_SetH(req->http0, HTTP_HDR_URL, src); if (host != NULL && *host != '\0') { - http_Unset(req->http, H_Host); - http_Unset(req->http, H_If_Modified_Since); - http_SetHeader(req->http, host); + http_Unset(req->http0, H_Host); + http_SetHeader(req->http0, host); } + + http_ForceGet(req->http0); + http_Unset(req->http0, H_If_Modified_Since); + + /* Client content already taken care of */ + http_Unset(req->http0, H_Content_Length); + + /* Reset request to status before we started messing with it */ + HTTP_Copy(req->http, req->http0); + + req->vcl = preq->vcl; + preq->vcl = NULL; + req->wrk = preq->wrk; + /* * XXX: We should decide if we should cache the director * XXX: or not (for session/backend coupling). Until then * XXX: make sure we don't trip up the check in vcl_recv. */ - req->director = NULL; req->req_step = R_STP_RECV; - http_ForceGet(req->http); + req->t_req = preq->t_req; + req->gzip_resp = preq->gzip_resp; + req->crc = preq->crc; + req->l_crc = preq->l_crc; - /* Don't do conditionals */ - req->http->conds = 0; - http_Unset(req->http, H_If_Modified_Since); + THR_SetRequest(req); - /* Client content already taken care of */ - http_Unset(req->http, H_Content_Length); - - sxid = req->xid; while (1) { req->wrk = wrk; i = CNT_Request(wrk, req); if (i == 1) break; + DSL(0x20, SLT_Debug, req->sp->vsl_id, + "loop waiting for ESI (%d)", i); assert(i == 2); AZ(req->wrk); - DSL(0x20, SLT_Debug, req->sp->vsl_id, "loop waiting for ESI"); (void)usleep(10000); } - req->xid = sxid; - req->wrk = wrk; - req->esi_level--; - req->obj = obj; - req->res_mode = res_mode; /* Reset the workspace */ - WS_Reset(req->ws, sp_ws_wm); WS_Reset(wrk->aws, wrk_ws_wm); /* XXX ? */ - WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_resp); - if (req->res_mode & RES_CHUNKED) - WRW_Chunked(req->wrk); + WRW_Reserve(preq->wrk, &preq->sp->fd, preq->vsl, preq->t_resp); + if (preq->res_mode & RES_CHUNKED) + WRW_Chunked(preq->wrk); + + preq->vcl = req->vcl; + req->vcl = NULL; + + preq->crc = req->crc; + preq->l_crc = req->l_crc; + + req->wrk = NULL; + + THR_SetRequest(preq); + SES_ReleaseReq(req); } /*--------------------------------------------------------------------*/ diff --git a/bin/varnishtest/tests/r01168.vtc b/bin/varnishtest/tests/r01168.vtc new file mode 100644 index 0000000..fb0a0c5 --- /dev/null +++ b/bin/varnishtest/tests/r01168.vtc @@ -0,0 +1,26 @@ +varnishtest "Test ESI rollback interaction" + +server s1 { + rxreq + expect req.url == "/" + txresp -body {<esi:include src="/esi"/>} + + rxreq + expect req.url == "/esi" + txresp -body "1" +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + rollback; + } + sub vcl_fetch { + set beresp.do_esi = true; + } +} -start + +client c1 { + txreq + rxresp + expect resp.bodylen == 1 +} -run _______________________________________________ varnish-commit mailing list varnish-commit [at] varnish-cache https://www.varnish-cache.org/lists/mailman/listinfo/varnish-commit
|