[4.0] fb97c67 Extract the bereq->obj creation code to a separate function
Poul-Henning Kamp
phk at FreeBSD.org
Thu Mar 13 10:24:27 CET 2014
commit fb97c67b70fa87dcc2091c05c104bb1e68cff37a
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Feb 18 13:17:18 2014 +0000
Extract the bereq->obj creation code to a separate function
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 31379cf..f044347 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -71,6 +71,119 @@ vbf_release_req(struct busyobj *bo)
}
/*--------------------------------------------------------------------
+ */
+
+static int
+vbf_bereq2obj(struct worker *wrk, struct busyobj *bo)
+{
+ unsigned l;
+ char *b;
+ struct vsb *vary = NULL;
+ int varyl = 0;
+ uint16_t nhttp;
+ struct object *obj;
+ struct http *hp, *hp2;
+
+ l = 0;
+
+ /* Create Vary instructions */
+ if (!(bo->fetch_objcore->flags & OC_F_PRIVATE)) {
+ varyl = VRY_Create(bo, &vary);
+ if (varyl > 0) {
+ AN(vary);
+ assert(varyl == VSB_len(vary));
+ l += varyl;
+ } else if (varyl < 0) {
+ /*
+ * Vary parse error
+ * Complain about it, and make this a pass.
+ */
+ VSLb(bo->vsl, SLT_Error,
+ "Illegal 'Vary' header from backend, "
+ "making this a pass.");
+ bo->uncacheable = 1;
+ AZ(vary);
+ } else
+ /* No vary */
+ AZ(vary);
+ }
+
+ l += http_EstimateWS(bo->beresp,
+ bo->uncacheable ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp);
+
+ if (bo->uncacheable)
+ bo->fetch_objcore->flags |= OC_F_PASS;
+
+ if (bo->uncacheable ||
+ bo->exp.ttl+bo->exp.grace+bo->exp.keep < cache_param->shortlived)
+ bo->storage_hint = TRANSIENT_STORAGE;
+
+ AZ(bo->stats);
+ bo->stats = &wrk->stats;
+ AN(bo->fetch_objcore);
+ obj = STV_NewObject(bo, bo->storage_hint, l, nhttp);
+#if 0
+ // XXX: we shouldn't retry if we're already on Transient
+ if (obj == NULL &&
+ (bo->storage_hint == NULL ||
+ strcmp(bo->storage_hint, TRANSIENT_STORAGE))) {
+#else
+ if (obj == NULL) {
+#endif
+ /*
+ * Try to salvage the transaction by allocating a
+ * shortlived object on Transient storage.
+ */
+ if (bo->exp.ttl > cache_param->shortlived)
+ bo->exp.ttl = cache_param->shortlived;
+ bo->exp.grace = 0.0;
+ bo->exp.keep = 0.0;
+ obj = STV_NewObject(bo, TRANSIENT_STORAGE, l, nhttp);
+ }
+ if (obj == NULL)
+ return (-1);
+
+ CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
+
+ bo->storage_hint = NULL;
+
+ AZ(bo->fetch_obj);
+ bo->fetch_obj = obj;
+
+ if (bo->do_gzip || (bo->is_gzip && !bo->do_gunzip))
+ obj->gziped = 1;
+
+ if (vary != NULL) {
+ obj->vary = (void *)WS_Copy(obj->http->ws,
+ VSB_data(vary), varyl);
+ AN(obj->vary);
+ (void)VRY_Validate(obj->vary);
+ VSB_delete(vary);
+ }
+
+ obj->vxid = bo->vsl->wid;
+ obj->response = bo->err_code;
+ WS_Assert(bo->ws_o);
+
+ /* Filter into object */
+ hp = bo->beresp;
+ hp2 = obj->http;
+
+ hp2->logtag = SLT_ObjMethod;
+ http_FilterResp(hp, hp2, bo->uncacheable ? HTTPH_R_PASS : HTTPH_A_INS);
+ http_CopyHome(hp2);
+
+ if (http_GetHdr(hp, H_Last_Modified, &b))
+ obj->last_modified = VTIM_parse(b);
+ else
+ obj->last_modified = floor(bo->exp.t_origin);
+
+ assert(WRW_IsReleased(wrk));
+
+ return (0);
+}
+
+/*--------------------------------------------------------------------
* Copy req->bereq
*/
@@ -300,12 +413,6 @@ vbf_stp_fetchhdr(struct worker *wrk, struct busyobj *bo)
static enum fetch_step
vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
{
- struct http *hp, *hp2;
- char *b;
- uint16_t nhttp;
- unsigned l;
- struct vsb *vary = NULL;
- int varyl = 0;
struct object *obj;
ssize_t est = -1;
@@ -388,97 +495,14 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
if (bo->htc.body_status == BS_NONE)
bo->do_stream = 0;
- l = 0;
-
- /* Create Vary instructions */
- if (!(bo->fetch_objcore->flags & OC_F_PRIVATE)) {
- varyl = VRY_Create(bo, &vary);
- if (varyl > 0) {
- AN(vary);
- assert(varyl == VSB_len(vary));
- l += varyl;
- } else if (varyl < 0) {
- /*
- * Vary parse error
- * Complain about it, and make this a pass.
- */
- VSLb(bo->vsl, SLT_Error,
- "Illegal 'Vary' header from backend, "
- "making this a pass.");
- bo->uncacheable = 1;
- AZ(vary);
- } else
- /* No vary */
- AZ(vary);
- }
-
- l += http_EstimateWS(bo->beresp,
- bo->uncacheable ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp);
-
- if (bo->uncacheable)
- bo->fetch_objcore->flags |= OC_F_PASS;
-
- if (bo->uncacheable ||
- bo->exp.ttl+bo->exp.grace+bo->exp.keep < cache_param->shortlived)
- bo->storage_hint = TRANSIENT_STORAGE;
-
- AZ(bo->stats);
- bo->stats = &wrk->stats;
- AN(bo->fetch_objcore);
- obj = STV_NewObject(bo, bo->storage_hint, l, nhttp);
- if (obj == NULL) {
- /*
- * Try to salvage the transaction by allocating a
- * shortlived object on Transient storage.
- */
- if (bo->exp.ttl > cache_param->shortlived)
- bo->exp.ttl = cache_param->shortlived;
- bo->exp.grace = 0.0;
- bo->exp.keep = 0.0;
- obj = STV_NewObject(bo, TRANSIENT_STORAGE, l, nhttp);
- }
- if (obj == NULL) {
+ if (vbf_bereq2obj(wrk, bo)) {
bo->stats = NULL;
(void)VFP_Error(bo, "Could not get storage");
VDI_CloseFd(&bo->vbc);
return (F_STP_DONE);
}
- CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
-
- bo->storage_hint = NULL;
-
- AZ(bo->fetch_obj);
- bo->fetch_obj = obj;
-
- if (bo->do_gzip || (bo->is_gzip && !bo->do_gunzip))
- obj->gziped = 1;
-
- if (vary != NULL) {
- obj->vary = (void *)WS_Copy(obj->http->ws,
- VSB_data(vary), varyl);
- AN(obj->vary);
- (void)VRY_Validate(obj->vary);
- VSB_delete(vary);
- }
- obj->vxid = bo->vsl->wid;
- obj->response = bo->err_code;
- WS_Assert(bo->ws_o);
-
- /* Filter into object */
- hp = bo->beresp;
- hp2 = obj->http;
-
- hp2->logtag = SLT_ObjMethod;
- http_FilterResp(hp, hp2, bo->uncacheable ? HTTPH_R_PASS : HTTPH_A_INS);
- http_CopyHome(hp2);
-
- if (http_GetHdr(hp, H_Last_Modified, &b))
- obj->last_modified = VTIM_parse(b);
- else
- obj->last_modified = floor(bo->exp.t_origin);
-
- assert(WRW_IsReleased(wrk));
+ obj = bo->fetch_obj;
/*
* Ready to fetch the body
@@ -514,9 +538,6 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
bo->t_body = VTIM_mono();
- http_Teardown(bo->bereq);
- http_Teardown(bo->beresp);
-
VSLb(bo->vsl, SLT_Fetch_Body, "%u(%s)",
bo->htc.body_status, body_status_2str(bo->htc.body_status));
@@ -606,7 +627,7 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
obj->gzip_last = bo->ims_obj->gzip_last;
obj->gzip_stop = bo->ims_obj->gzip_stop;
- /* XXX: ESI */
+ XXXAZ(bo->ims_obj->esidata);
if (bo->ims_obj->vary != NULL) {
obj->vary = (void *)WS_Copy(obj->http->ws,
@@ -676,6 +697,24 @@ vbf_stp_error(struct worker *wrk, struct busyobj *bo)
{
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+
+ AN(bo->fetch_objcore->flags &= OC_F_BUSY);
+
+ // XXX: reset all beresp flags ?
+
+ HTTP_Setup(bo->beresp, bo->ws, bo->vsl, SLT_BerespMethod);
+ http_SetResp(bo->beresp, "HTTP/1.1", 503, "Backend fetch failed");
+ http_SetHeader(bo->beresp, "Content-Length: 0");
+ http_SetHeader(bo->beresp, "Connection: close");
+
+ bo->exp.ttl = 0;
+ bo->exp.grace = 0;
+ bo->exp.keep = 0;
+
+ VCL_backend_error_method(bo->vcl, wrk, NULL, bo, bo->bereq->ws);
+
+ xxxassert(wrk->handling == VCL_RET_DELIVER);
+
WRONG("");
return (F_STP_DONE);
}
@@ -749,6 +788,9 @@ vbf_fetch_thread(struct worker *wrk, void *priv)
AZ(bo->vbc);
}
+ http_Teardown(bo->bereq);
+ http_Teardown(bo->beresp);
+
if (bo->state == BOS_FAILED)
assert(bo->fetch_objcore->flags & OC_F_FAILED);
More information about the varnish-commit
mailing list