[master] 3edd1f7 Make synth {} work in vcl_backend_response{}

Poul-Henning Kamp phk at FreeBSD.org
Mon Mar 10 15:37:14 CET 2014


commit 3edd1f7b0d83f9baaa20c01109e8c0e4bd43c20b
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Mar 10 14:36:45 2014 +0000

    Make synth {} work in vcl_backend_response{}

diff --git a/bin/varnishd/builtin.vcl b/bin/varnishd/builtin.vcl
index a6a126d..a0eb015 100644
--- a/bin/varnishd/builtin.vcl
+++ b/bin/varnishd/builtin.vcl
@@ -182,6 +182,26 @@ sub vcl_backend_response {
 }
 
 sub vcl_backend_error {
+    set beresp.http.Content-Type = "text/html; charset=utf-8";
+    set beresp.http.Retry-After = "5";
+    synthetic {"
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+  <head>
+    <title>"} + beresp.status + " " + beresp.reason + {"</title>
+  </head>
+  <body>
+    <h1>Error "} + beresp.status + " " + beresp.reason + {"</h1>
+    <p>"} + beresp.reason + {"</p>
+    <h3>Guru Meditation:</h3>
+    <p>XID: "} + bereq.xid + {"</p>
+    <hr>
+    <p>Varnish cache server</p>
+  </body>
+</html>
+"};
     return (deliver);
 }
 
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 5b4028d..a954316 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -579,6 +579,8 @@ struct busyobj {
 
 	/* Workspace for object only needed during fetch */
 	struct ws		ws_o[1];
+
+	struct vsb		*synth_body;
 };
 
 /* Object structure --------------------------------------------------*/
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index b42674a..9368385 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -640,28 +640,33 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
 static enum fetch_step
 vbf_stp_error(struct worker *wrk, struct busyobj *bo)
 {
+	struct storage *st;
+	ssize_t l;
+
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 
 	AN(bo->fetch_objcore->flags & OC_F_BUSY);
 
+	AZ(bo->synth_body);
+	bo->synth_body = VSB_new_auto();
+	AN(bo->synth_body);
+
 	// 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.t_origin = VTIM_real();
 	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);
+	AZ(VSB_finish(bo->synth_body));
 
-	http_PrintfHeader(bo->beresp, "Content-Length: %jd", (intmax_t)0);
-	http_PrintfHeader(bo->beresp, "X-XXXPHK: yes");
+	xxxassert(wrk->handling == VCL_RET_DELIVER);
 
 	if (vbf_beresp2obj(bo)) {
 		VBO_setstate(bo, BOS_FAILED);
@@ -669,9 +674,29 @@ vbf_stp_error(struct worker *wrk, struct busyobj *bo)
 		return (F_STP_DONE);
 	}
 
+	l = VSB_len(bo->synth_body);
+	if (l > 0) {
+		st = VFP_GetStorage(bo, l);
+		if (st != NULL) {
+			if (st->space < l) {
+				VSLb(bo->vsl, SLT_Error,
+				    "No space for %zd bytes of synth body", l);
+			} else {
+				memcpy(st->ptr, VSB_data(bo->synth_body), l);
+				st->len = l;
+				VBO_extend(bo, l);
+			}
+		}
+	}
+	VSB_delete(bo->synth_body);
+	bo->synth_body = NULL;
+
 	HSH_Unbusy(&wrk->stats, bo->fetch_obj->objcore);
+
 	VBO_setstate(bo, BOS_FINISHED);
+
 	HSH_Complete(bo->fetch_obj->objcore);
+
 	return (F_STP_DONE);
 }
 
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index f78f140..95a37b0 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -377,9 +377,14 @@ VRT_synth_page(const struct vrt_ctx *ctx, unsigned flags, const char *str, ...)
 
 	(void)flags;
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
-	CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
-	CHECK_OBJ_NOTNULL(ctx->req->obj, OBJECT_MAGIC);
-	vsb = SMS_Makesynth(ctx->req->obj);
+	if (ctx->method == VCL_MET_BACKEND_ERROR) {
+		CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
+		vsb = ctx->bo->synth_body;
+	} else {
+		CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
+		CHECK_OBJ_NOTNULL(ctx->req->obj, OBJECT_MAGIC);
+		vsb = SMS_Makesynth(ctx->req->obj);
+	}
 	AN(vsb);
 
 	va_start(ap, str);
@@ -391,8 +396,10 @@ VRT_synth_page(const struct vrt_ctx *ctx, unsigned flags, const char *str, ...)
 		p = va_arg(ap, const char *);
 	}
 	va_end(ap);
-	SMS_Finish(ctx->req->obj);
-	http_Unset(ctx->req->obj->http, H_Content_Length);
+	if (ctx->method != VCL_MET_BACKEND_ERROR) {
+		SMS_Finish(ctx->req->obj);
+		http_Unset(ctx->req->obj->http, H_Content_Length);
+	}
 }
 
 /*--------------------------------------------------------------------*/
diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c
index 2c79c0e..b6e2835 100644
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@ -466,7 +466,7 @@ VRT_DO_EXP(beresp, ctx->bo->exp, ttl, 0, ctx->bo->exp.t_origin,)
 VRT_DO_EXP(beresp, ctx->bo->exp, keep, 0, ctx->bo->exp.t_origin,)
 
 /*--------------------------------------------------------------------
- * req.xid
+ * [be]req.xid
  */
 
 const char *
@@ -480,6 +480,17 @@ VRT_r_req_xid(const struct vrt_ctx *ctx)
 	    ctx->req->vsl->wid & VSL_IDENTMASK));
 }
 
+const char *
+VRT_r_bereq_xid(const struct vrt_ctx *ctx)
+{
+
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
+
+	return (WS_Printf(ctx->bo->bereq->ws, "%u",
+	    ctx->bo->vsl->wid & VSL_IDENTMASK));
+}
+
 /*--------------------------------------------------------------------*/
 
 #define REQ_BOOL(hash_var)					\
diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py
index 8c9461a..c3f26ff 100755
--- a/lib/libvcc/generate.py
+++ b/lib/libvcc/generate.py
@@ -296,6 +296,13 @@ The client's IP address.
 		always (re)fetch from the backend.
 		"""
 	),
+	('bereq.xid',
+		'STRING',
+		( 'backend',),
+		( ), """
+		Unique ID of this request.
+		"""
+	),
 	('bereq.retries',
 		'INT',
 		( 'backend',),
diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c
index 35f88f8..0026ad4 100644
--- a/lib/libvcc/vcc_action.c
+++ b/lib/libvcc/vcc_action.c
@@ -421,7 +421,8 @@ static struct action_table {
 	{ "return",		parse_return },
 	{ "rollback",		parse_rollback },
 	{ "set",		parse_set },
-	{ "synthetic",		parse_synthetic, VCL_MET_ERROR },
+	{ "synthetic",		parse_synthetic,
+		VCL_MET_ERROR | VCL_MET_BACKEND_ERROR },
 	{ "unset",		parse_unset },
 	{ NULL,			NULL }
 };



More information about the varnish-commit mailing list