[master] f06ed26 Rewrite the example for std.fileread(), and verify it with a test.

Geoff Simmons geoff at uplex.de
Sat Feb 10 11:10:14 UTC 2018


commit f06ed2639b3b2cc2bf9fbb7572d8df7dd47f3cca
Author: Geoff Simmons <geoff at uplex.de>
Date:   Sat Feb 10 12:07:53 2018 +0100

    Rewrite the example for std.fileread(), and verify it with a test.
    
    After it was reported on #varnish that following the previous
    example may lead to invalid response headers.

diff --git a/bin/varnishtest/tests/m00004.vtc b/bin/varnishtest/tests/m00004.vtc
index bb3ba56..70bf0ff 100644
--- a/bin/varnishtest/tests/m00004.vtc
+++ b/bin/varnishtest/tests/m00004.vtc
@@ -4,10 +4,11 @@ shell {
 	printf "File One" > "${tmpdir}/m00004_file_one"
 	printf "File Two" > "${tmpdir}/m00004_file_two"
 	printf "File Three" > "${tmpdir}/m00004_file_three"
+	printf "File Four\n" > "${tmpdir}/m00004_file_four"
 }
 
 server s1 {
-	loop 3 {
+	loop 4 {
 		rxreq
 		txresp -hdr "foo: bar" -bodylen 4
 	}
@@ -16,6 +17,20 @@ server s1 {
 varnish v1 -vcl+backend {
 	import std;
 
+	sub vcl_recv {
+		if (req.url == "/five") {
+			return(synth(200));
+		}
+	}
+
+	sub vcl_backend_response {
+		if (bereq.url == "/four") {
+			set beresp.http.served-by
+			    = regsub(std.fileread("${tmpdir}/m00004_file_four"),
+			             "\R$", "");
+		}
+	}
+
 	sub vcl_deliver {
 		if (req.url == "/one") {
 			set resp.http.one = std.fileread("${tmpdir}/m00004_file_one");
@@ -25,6 +40,12 @@ varnish v1 -vcl+backend {
 			set resp.http.three = std.fileread("${tmpdir}/m00004_file_three");
 		}
 	}
+
+	sub vcl_synth {
+		synthetic("Response was served by "
+		          + std.fileread("${tmpdir}/m00004_file_four"));
+		return(deliver);
+	}
 } -start
 
 client c1 {
@@ -48,11 +69,37 @@ client c1 {
 	expect resp.bodylen == "4"
 	expect resp.http.foo == "bar"
 	expect resp.http.three == "File Three"
+
+	txreq -url "/four"
+	rxresp
+	expect resp.status == 200
+	expect resp.bodylen == "4"
+	expect resp.http.foo == "bar"
+	expect resp.http.served-by == "File Four"
+
+	txreq -url "/five"
+	rxresp
+	expect resp.status == 200
+	expect resp.body == "Response was served by File Four\n"
 } -run
 
 varnish v1 -vcl+backend {
 	import std;
 
+	sub vcl_recv {
+		if (req.url == "/five") {
+			return(synth(200));
+		}
+	}
+
+	sub vcl_backend_response {
+		if (bereq.url == "/four") {
+			set beresp.http.served-by
+			    = regsub(std.fileread("${tmpdir}/m00004_file_four"),
+			             "\R$", "");
+		}
+	}
+
 	sub vcl_deliver {
 		if (req.url == "/one") {
 			set resp.http.one = std.fileread("${tmpdir}/m00004_file_one");
@@ -62,6 +109,12 @@ varnish v1 -vcl+backend {
 			set resp.http.three = std.fileread("${tmpdir}/m00004_file_three");
 		}
 	}
+
+	sub vcl_synth {
+		synthetic("Response was served by "
+		          + std.fileread("${tmpdir}/m00004_file_four"));
+		return(deliver);
+	}
 }
 
 varnish v1 -cli "vcl.list"
diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc
index 16dd85f..178b0b7 100644
--- a/lib/libvmod_std/vmod.vcc
+++ b/lib/libvmod_std/vmod.vcc
@@ -111,7 +111,14 @@ Description
 	function the caching in the function doesn't take this into
 	account. Also, files are not re-read.
 Example
-	set beresp.http.served-by = std.fileread("/etc/hostname");
+	synthetic("Response was served by " + std.fileread("/etc/hostname"));
+
+Consider that the entire contents of the file appear in the string
+that is returned, including newlines that may result in invalid
+headers if ``std.fileread()`` is used to form a header. In that case,
+you may need to modify the string, for example with ``regsub()``::
+
+  set beresp.http.served-by = regsub(std.fileread("/etc/hostname"), "\R$", "");
 
 $Function BOOL file_exists(STRING path)
 


More information about the varnish-commit mailing list