Attached.

OK?




On Thu, Jul 24, 2014 at 12:08 PM, Poul-Henning Kamp <[email protected]>
wrote:

> In message <[email protected]>, "Poul-Henning Kamp"
> writes:
> >We chatted about this on IRC today, and this is just to keep everybody
> >in the loop:
> >
> >In general, I'm trying to slim down VCC to be "just the language" and
> >'rollback' is one of the remaining bits I'd like to get out of there,
> >so the new improved rollback goes into vmod.std.
> >
> >We leave the "rollback" which VCC implements alone for 4.x
> >
> >I have added a new VMOD data type "HTTP", which returns an entire
> >HTTP request/response (struct http *), so that somebody can now
> >implement the rollback functionality in vmod.std, so the end result
> >will become:
> >
> >       std.collect(req)
> >
> >       std.collect(bereq)
>
> and that of course should been:
>
>         std.rollback(req)
>         std.rollback(bereq)
>
>
> --
> Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
> [email protected]         | TCP/IP since RFC 956
> FreeBSD committer       | BSD since 4.3-tahoe
> Never attribute to malice what can adequately be explained by incompetence.
>
> _______________________________________________
> varnish-dev mailing list
> [email protected]
> https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
>
 bin/varnishd/cache/cache.h       |  1 +
 bin/varnishd/cache/cache_fetch.c |  7 ++--
 bin/varnishtest/tests/m00017.vtc | 69 ++++++++++++++++++++++++++++++++++++++++
 bin/varnishtest/tests/r01512.vtc | 56 ++++++++++++++++++++++++++++++++
 lib/libvmod_std/vmod.vcc         |  7 ++++
 lib/libvmod_std/vmod_std.c       | 19 +++++++++++
 6 files changed, 156 insertions(+), 3 deletions(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index f711959..3c39064 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -491,6 +491,7 @@ struct busyobj {
 	enum busyobj_state_e	state;
 
 	struct ws		ws[1];
+	char 			*ws0;
 	struct vbc		*vbc;
 	struct http		*bereq0;
 	struct http		*bereq;
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index e0320fc..6c525f8 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -215,6 +215,10 @@ vbf_stp_mkbereq(const struct worker *wrk, struct busyobj *bo)
 		}
 	}
 
+	HTTP_Setup(bo->bereq, bo->ws, bo->vsl, SLT_BereqMethod);
+	bo->ws0 = WS_Snapshot(bo->ws);
+	HTTP_Copy(bo->bereq, bo->bereq0);
+
 	VBO_setstate(bo, BOS_REQ_DONE);
 	return (F_STP_STARTFETCH);
 }
@@ -262,9 +266,6 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
 	else
 		AZ(bo->req);
 
-	HTTP_Setup(bo->bereq, bo->ws, bo->vsl, SLT_BereqMethod);
-	HTTP_Copy(bo->bereq, bo->bereq0);
-
 	http_PrintfHeader(bo->bereq, "X-Varnish: %u", VXID(bo->vsl->wid));
 
 	VCL_backend_fetch_method(bo->vcl, wrk, NULL, bo, bo->bereq->ws);
diff --git a/bin/varnishtest/tests/m00017.vtc b/bin/varnishtest/tests/m00017.vtc
new file mode 100644
index 0000000..5622ec0
--- /dev/null
+++ b/bin/varnishtest/tests/m00017.vtc
@@ -0,0 +1,69 @@
+varnishtest "Test std.rollback"
+
+server s1 {
+	rxreq
+	expect req.url == "/foo"
+	expect req.http.foobar == "bar"
+	txresp -status 400
+	accept
+	rxreq
+	expect req.url == "/bar"
+	expect req.http.foobar == "foo"
+	txresp
+	accept
+	rxreq
+	expect req.url == "/baz"
+	expect req.http.foobar == "qux"
+	txresp -status 400
+	accept
+	rxreq
+	expect req.url == "/qux"
+	expect req.http.foobar == "baz"
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	import ${vmod_std};
+
+	sub vcl_recv {
+		if (req.url == "/foo") {
+			set req.http.foobar = "bar";
+		}
+	}
+
+	sub vcl_deliver {
+		if (resp.status == 400) {
+			std.rollback(req);
+			set req.url = "/bar";
+			return (restart);
+		}
+	}
+} -start
+
+client c1 {
+	txreq -url "/foo" -hdr "foobar: foo"
+	rxresp
+} -run
+
+varnish v1 -vcl+backend {
+	import ${vmod_std};
+
+	sub vcl_backend_fetch {
+		if (bereq.url == "/baz") {
+			set bereq.http.foobar = "qux";
+		}
+	}
+
+	sub vcl_backend_response {
+		if (beresp.status == 400) {
+			std.rollback(bereq);
+			set bereq.url = "/qux";
+			return (retry);
+		}
+	}
+}
+
+client c1 {
+	txreq -url "/baz" -hdr "foobar: baz"
+	rxresp
+} -run
diff --git a/bin/varnishtest/tests/r01512.vtc b/bin/varnishtest/tests/r01512.vtc
new file mode 100644
index 0000000..71496a2
--- /dev/null
+++ b/bin/varnishtest/tests/r01512.vtc
@@ -0,0 +1,56 @@
+varnishtest "Regression test for #1512"
+
+# First test bereq changes across v_b_r and v_b_f
+
+server s1 {
+	rxreq
+	txresp -status 700
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_backend_fetch {
+		if (bereq.http.x-abandon == "1") {
+			return (abandon);
+		}
+	}
+	sub vcl_backend_response {
+		if (beresp.status == 700) {
+			set bereq.http.x-abandon = "1";
+			return (retry);
+		}
+	}
+	sub vcl_synth {
+		set resp.status = 701;
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 701
+} -run
+
+# Then across v_b_e and v_b_f
+
+varnish v1 -vcl {
+	backend bad { .host = "${bad_ip}"; }
+	sub vcl_backend_fetch {
+		set bereq.backend = bad;
+		if (bereq.http.x-abandon == "2") {
+			return (abandon);
+		}
+	}
+	sub vcl_backend_error {
+		set bereq.http.x-abandon = "2";
+		return (retry);
+	}
+	sub vcl_synth {
+		set resp.status = 702;
+	}
+}
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 702
+} -run
diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc
index fbee007..5bcc403 100644
--- a/lib/libvmod_std/vmod.vcc
+++ b/lib/libvmod_std/vmod.vcc
@@ -174,6 +174,13 @@ $Function INT port(IP)
 Description
 	Returns the port number of an IP address.
 
+$Function VOID rollback(HTTP)
+
+Description
+	Restore *h* HTTP headers to their original state.
+Example
+	std.rollback(bereq);
+
 $Function VOID timestamp(STRING)
 
 Description
diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c
index 718fb71..513feb2 100644
--- a/lib/libvmod_std/vmod_std.c
+++ b/lib/libvmod_std/vmod_std.c
@@ -205,6 +205,25 @@ vmod_port(const struct vrt_ctx *ctx, VCL_IP ip)
 	return (VSA_Port(ip));
 }
 
+VCL_VOID __match_proto__(td_std_rollback)
+vmod_rollback(const struct vrt_ctx *ctx, VCL_HTTP hp)
+{
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+
+	if (hp == ctx->http_req) {
+		CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
+		HTTP_Copy(ctx->req->http, ctx->req->http0);
+		WS_Reset(ctx->req->ws, ctx->req->ws_req);
+	} else if (hp == ctx->http_bereq) {
+		CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
+		HTTP_Copy(ctx->bo->bereq, ctx->bo->bereq0);
+		WS_Reset(ctx->bo->bereq->ws, ctx->bo->ws0);
+		WS_Reset(ctx->bo->ws, ctx->bo->ws0);
+	} else
+		WRONG("rollback 'hp' invalid");
+}
+
 VCL_VOID __match_proto__(td_std_timestamp)
 vmod_timestamp(const struct vrt_ctx *ctx, VCL_STRING label)
 {
_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev

Reply via email to