[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