Commit 999e7bfe authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Cherry-pick std.blobread out of #3123

parent 20de7660
......@@ -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
......@@ -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,
......
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment