[master] 999e7bfe9 Cherry-pick std.blobread out of #3123

Poul-Henning Kamp phk at FreeBSD.org
Mon Aug 17 11:25:07 UTC 2020


commit 999e7bfe9802451617cbedb0d2c7a01f3af27a55
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Aug 17 11:24:08 2020 +0000

    Cherry-pick std.blobread out of #3123

diff --git a/bin/varnishtest/tests/r01145.vtc b/bin/varnishtest/tests/r01145.vtc
index ee33bb0c8..c1d33ead1 100644
--- a/bin/varnishtest/tests/r01145.vtc
+++ b/bin/varnishtest/tests/r01145.vtc
@@ -19,6 +19,7 @@ varnish v1 -vcl+backend {
 
 	sub vcl_deliver {
 	    set resp.http.foo = std.fileread("${tmpdir}" + req.url);
+	    set resp.http.fooblob = std.blobread("${tmpdir}" + req.url);
 	}
 } -start
 
@@ -27,17 +28,18 @@ client c1 {
 	txreq -url "/one"
 	rxresp
 	expect resp.http.foo == "File One"
+	expect resp.http.fooblob == :RmlsZSBPbmU=:
 
 	txreq -url "/two"
 	rxresp
 	expect resp.http.foo == "File Two"
+	expect resp.http.fooblob == :RmlsZSBUd28=:
 
 	txreq -url "/three"
 	rxresp
 	expect resp.http.foo == "File Three"
+	expect resp.http.fooblob == :RmlsZSBUaHJlZQ==:
 } -run
 
 client c1 -run
 client c1 -run
-
-
diff --git a/lib/libvmod_std/vmod_std.vcc b/lib/libvmod_std/vmod_std.vcc
index 8f8c7cacf..961e90ae1 100644
--- a/lib/libvmod_std/vmod_std.vcc
+++ b/lib/libvmod_std/vmod_std.vcc
@@ -187,10 +187,13 @@ File(system) functions
 
 $Function STRING fileread(PRIV_CALL, STRING)
 
-Reads a file and returns a string with the content. The result is
-cached indefinitely per filename.
+Reads a text file and returns a string with the content.
 
-This function should not be used for reading binary files.
+The entire file is cached on the first call, and subsequent calls
+will return this cached contents, even if the file has changed in
+the meantime.
+
+For binary files, use std.blobread() instead.
 
 Example::
 
@@ -204,6 +207,14 @@ case, you may need to modify the string, for example with
 
   set beresp.http.served-by = regsub(std.fileread("/etc/hostname"), "\R$", "");
 
+$Function BLOB blobread(PRIV_CALL, STRING)
+
+Reads any file and returns a blob with the content.
+
+The entire file is cached on the first call, and subsequent calls
+will return this cached contents, even if the file has changed in
+the meantime.
+
 $Function BOOL file_exists(STRING path)
 
 Returns ``true`` if path or the file pointed to by path exists,
diff --git a/lib/libvmod_std/vmod_std_fileread.c b/lib/libvmod_std/vmod_std_fileread.c
index 0e9f5cadc..df7a160d1 100644
--- a/lib/libvmod_std/vmod_std_fileread.c
+++ b/lib/libvmod_std/vmod_std_fileread.c
@@ -54,7 +54,8 @@ struct frfile {
 	unsigned			magic;
 #define CACHED_FILE_MAGIC 0xa8e9d87a
 	char				*file_name;
-	char				*contents;
+	void				*contents;
+	struct vrt_blob			blob[1];
 	int				refcount;
 	VTAILQ_ENTRY(frfile)		list;
 };
@@ -82,14 +83,13 @@ free_frfile(void *ptr)
 	}
 }
 
-VCL_STRING v_matchproto_(td_std_fileread)
-vmod_fileread(VRT_CTX, struct vmod_priv *priv,
-    VCL_STRING file_name)
+static struct frfile *
+find_frfile(struct vmod_priv *priv, VCL_STRING file_name)
 {
 	struct frfile *frf = NULL;
 	char *s;
+	ssize_t sz;
 
-	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	AN(priv);
 
 	if (file_name == NULL)
@@ -98,7 +98,7 @@ vmod_fileread(VRT_CTX, struct vmod_priv *priv,
 	if (priv->priv != NULL) {
 		CAST_OBJ_NOTNULL(frf, priv->priv, CACHED_FILE_MAGIC);
 		if (!strcmp(file_name, frf->file_name))
-			return (frf->contents);
+			return (frf);
 	}
 
 	AZ(pthread_mutex_lock(&frmtx));
@@ -114,22 +114,52 @@ vmod_fileread(VRT_CTX, struct vmod_priv *priv,
 	if (frf != NULL) {
 		priv->free = free_frfile;
 		priv->priv = frf;
-		return (frf->contents);
+		return (frf);
 	}
 
-	s = VFIL_readfile(NULL, file_name, NULL);
+	s = VFIL_readfile(NULL, file_name, &sz);
 	if (s != NULL) {
+		assert(sz > 0);
 		ALLOC_OBJ(frf, CACHED_FILE_MAGIC);
 		AN(frf);
-		frf->file_name = strdup(file_name);
-		AN(frf->file_name);
+		REPLACE(frf->file_name, file_name);
 		frf->refcount = 1;
 		frf->contents = s;
+		frf->blob->blob = s;
+		frf->blob->len = (size_t)sz;
 		priv->free = free_frfile;
 		priv->priv = frf;
 		AZ(pthread_mutex_lock(&frmtx));
 		VTAILQ_INSERT_HEAD(&frlist, frf, list);
 		AZ(pthread_mutex_unlock(&frmtx));
 	}
-	return (s);
+	return (frf);
+}
+
+VCL_STRING v_matchproto_(td_std_fileread)
+vmod_fileread(VRT_CTX, struct vmod_priv *priv, VCL_STRING file_name)
+{
+	struct frfile *frf;
+
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	AN(priv);
+
+	frf = find_frfile(priv, file_name);
+	if (frf == NULL)
+		return (NULL);
+	return (frf->contents);
+}
+
+VCL_BLOB v_matchproto_(td_std_blobread)
+vmod_blobread(VRT_CTX, struct vmod_priv *priv, VCL_STRING file_name)
+{
+	struct frfile *frf;
+
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	AN(priv);
+
+	frf = find_frfile(priv, file_name);
+	if (frf == NULL)
+		return (NULL);
+	return (frf->blob);
 }


More information about the varnish-commit mailing list