[master] c2cb5e7 Add read-only access to the top level request in an ESI tree.

Poul-Henning Kamp phk at FreeBSD.org
Sat May 16 10:38:08 CEST 2015


commit c2cb5e71ac123fce9d4cd94ba09f6b34f6fa1828
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sat May 16 08:36:51 2015 +0000

    Add read-only access to the top level request in an ESI tree.
    
    Patch from daghf (with minor changes)

diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index a453cf3..18631f8 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -475,6 +475,7 @@ vcl_call_method(struct worker *wrk, struct req *req, struct busyobj *bo,
 		vsl = req->vsl;
 		ctx.vcl = req->vcl;
 		ctx.http_req = req->http;
+		ctx.http_req_top = req->top->http;
 		ctx.http_resp = req->resp;
 		ctx.req = req;
 		ctx.now = req->t_prev;
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index 5a12c63..9b4aaff 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -96,6 +96,9 @@ VRT_selecthttp(VRT_CTX, enum gethdr_e where)
 	case HDR_REQ:
 		hp = ctx->http_req;
 		break;
+	case HDR_REQ_TOP:
+		hp = ctx->http_req_top;
+		break;
 	case HDR_BEREQ:
 		hp = ctx->http_bereq;
 		break;
diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c
index 5ae624e..cc302c5 100644
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@ -119,6 +119,10 @@ VRT_HDR_LR(req,    method,	HTTP_HDR_METHOD)
 VRT_HDR_LR(req,    url,		HTTP_HDR_URL)
 VRT_HDR_LR(req,    proto,	HTTP_HDR_PROTO)
 
+VRT_HDR_R(req_top,    method,	HTTP_HDR_METHOD)
+VRT_HDR_R(req_top,    url,	HTTP_HDR_URL)
+VRT_HDR_R(req_top,    proto,	HTTP_HDR_PROTO)
+
 VRT_HDR_LR(resp,   proto,	HTTP_HDR_PROTO)
 VRT_HDR_LR(resp,   reason,	HTTP_HDR_REASON)
 VRT_STATUS_L(resp)
diff --git a/bin/varnishtest/tests/e00030.vtc b/bin/varnishtest/tests/e00030.vtc
new file mode 100644
index 0000000..7779f98
--- /dev/null
+++ b/bin/varnishtest/tests/e00030.vtc
@@ -0,0 +1,76 @@
+varnishtest "Test req_top.* in an ESI context"
+
+varnish v1 -errvcl {Variable 'req_top.url' is read only.} {
+	sub vcl_recv {
+		set req_top.url = "/foo";
+	}
+}
+
+server s1 {
+	rxreq
+	expect req.http.top-url == "/"
+	expect req.http.top-method == "GET"
+	expect req.http.top-proto == "HTTP/1.1"
+	expect req.http.top-foo == "bar"
+	txresp -body {
+		<html>
+		Before include
+		<esi:include src="/a"/>
+		<esi:include src="/b"/>
+		After include
+		</html>
+	}
+
+	rxreq
+	expect req.url == "/a1"
+	expect req.http.top-url == "/"
+	expect req.http.top-method == "GET"
+	expect req.http.top-proto == "HTTP/1.1"
+	expect req.http.top-foo == "bar"
+	txresp -body {
+		Included file
+		<esi:include src="/c"/>
+	}
+
+	rxreq
+	expect req.http.top-url == "/"
+	expect req.http.top-method == "GET"
+	expect req.http.top-proto == "HTTP/1.1"
+	expect req.http.top-foo == "bar"
+	expect req.url == "/b1"
+	txresp
+
+	rxreq
+	expect req.http.top-url == "/"
+	expect req.http.top-method == "GET"
+	expect req.http.top-proto == "HTTP/1.1"
+	expect req.http.top-foo == "bar"
+	expect req.url == "/c2"
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_recv {
+		if (req.esi_level > 0) {
+			set req.url = req.url + req.esi_level;
+		} else {
+			set req.http.foo = "bar";
+		}
+
+		set req.http.top-url = req_top.url;
+		set req.http.top-method = req_top.method;
+		set req.http.top-proto = req_top.proto;
+		set req.http.top-foo = req_top.http.foo;
+	}
+	sub vcl_backend_response {
+		set beresp.do_esi = true;
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 200
+} -run
+
+varnish v1 -expect esi_errors == 0
diff --git a/include/vrt.h b/include/vrt.h
index 785dd8c..dca5902 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -100,6 +100,7 @@ struct vrt_ctx {
 
 	struct req			*req;
 	struct http			*http_req;
+	struct http			*http_req_top;
 	struct http			*http_resp;
 
 	struct busyobj			*bo;
@@ -136,7 +137,8 @@ struct vmod_data {
 
 /***********************************************************************/
 
-enum gethdr_e { HDR_REQ, HDR_RESP, HDR_OBJ, HDR_BEREQ, HDR_BERESP };
+enum gethdr_e { HDR_REQ, HDR_REQ_TOP, HDR_RESP, HDR_OBJ, HDR_BEREQ,
+		HDR_BERESP };
 
 struct gethdr_s {
 	enum gethdr_e	where;
diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py
index f342012..f695dc7 100755
--- a/lib/libvcc/generate.py
+++ b/lib/libvcc/generate.py
@@ -317,6 +317,41 @@ sp_variables = [
 		always (re)fetch from the backend.
 		"""
 	),
+	('req_top.method',
+		'STRING',
+		( 'client',),
+		(), """
+		The request method of the top-level request in a tree
+		of ESI requests. (e.g. "GET", "HEAD").
+		Identical to req.method in non-ESI requests.
+		"""
+	),
+	('req_top.url',
+		'STRING',
+		( 'client',),
+		(), """
+		The requested URL of the top-level request in a tree
+		of ESI requests.
+		Identical to req.url in non-ESI requests.
+		"""
+	),
+	('req_top.http.',
+		'HEADER',
+		( 'client',),
+		(), """
+		HTTP headers of the top-level request in a tree of ESI requests.
+		Identical to req.http. in non-ESI requests.
+		"""
+	),
+	('req_top.proto',
+		'STRING',
+		( 'client',),
+		(), """
+		HTTP protocol version of the top-level request in a tree of
+		ESI requests.
+		Identical to req.proto in non-ESI requests.
+		"""
+	),
 	('bereq',
 		'HTTP',
 		( 'backend',),



More information about the varnish-commit mailing list