Varnish Cache Plus

File

Varnish 6.0

Description

vmod_file allows for Varnish to act as a file server as well as a means to interact with the file system from VCL.

The backend allows the serving of static files through Varnish. The backend request URL is appended to the vmod’s root directory to form a file path. If the file path resolves to a regular file and is readable to the Varnish child process, it is used as the source for this backend fetch operation. Files served this way are treated in the same manner as if they were fetched from a real backend, and so will be cached in memory according to the current configuration. TTL, grace and keep works just like it would normally as well.

The following headers are added based on the resolved files attributes: Last-Modified, Content-type and Content-Length.

If the file could not be read for any reason (e.g. not found, access restrictions or resolved outside of the root directory of the vmod), an appropriate error response is synthesized.

This VMOD includes a standard set of file operations and an ACL. All file objects must allow at least one path in the ACL. To use executable files, a mode of x, varnishd must be started with -p allow_exec=true.

Examples

Serve a local file system

  import file;

  sub vcl_init {
    new root = file.init("/var/www/html/");
  }

  sub vcl_backend_fetch {
    # Set the file system as the backend
    set bereq.backend = root.backend();
  }

Return the uptime of the server

  import file;

  sub vcl_init {
      new fs = file.init();
      fs.allow("/usr/bin/uptime", "x");
  }

  sub vcl_recv {
      if (req.method == "UPTIME") {
          return (synth(200, "UPTIME"));
      }
  }

  sub vcl_synth {
      if (resp.reason == "UPTIME") {
          synthetic(fs.exec("/usr/bin/uptime"));
          if (fs.exec_get_errorcode() != 0) {
                     set resp.status = 404;
          }
          return (deliver);
      }
  }

Functions

init

OBJECT file.init(STRING rootdir = NULL, STRING mimedb = "/etc/mime.types", BOOL disable_symlinks = false)

  • Description

    Creates a file system root. The rootdir is the base of the file system hierarchy.

  • Return

    An object to reference the file system through.

    • roodir

      (Optional) The path of the root directory. When set, each path used in the functions bellow (except for .exec()) will be prepended with this root directory. Otherwise each path will be considered absolute or relative, depending on a leading slash. Defaults to NULL.

    • mimedb

      The path to the mimedb. Defaults to /etc/mime.types.

    • disable_symlinks

      Should symlinks be allowed in any of the function calls below? Defaults to false.

backend

BACKEND .backend()

  • Description

    Return a backend reference to this root for use during fetch.

  • Return

    A backend object for varnish to get the file from.

allow

VOID .allow(STRING path, STRING mode = "r")

  • Description

    Allow path to be accessed from functions that access files through mode. At least one path must be added to allow for the object to work correctly.

    • path

      The path to add to allow access to. This path can be a glob.

    • mode

      (Optional) What type of access should this file have? This can be any combination of read (r), write (w), or execute (x). Defaults to r.

deny

VOID .deny(STRING path, STRING mode = "rwx")

  • Description

    Deny path access from functions that access files through mode.

    • path

      The path to add to deny access to. This path can be a glob.

    • mode

      What type of access should this file have? This can be any combination of read (r), write (w), or execute (x). Defaults to rwx.

read

STRING .read(STRING file, STRING def = NULL)

  • Description

    Read file and return it as a string. If file does not exist or does not pass the ACL, def is returned.

  • Return

    A string with the contents of file.

    • file

      The file to read.

    • def

      (Optional) The string to return if there was an error reading the file. Defaults to NULL.

read_blob

BLOB .read(STRING file, STRING def = NULL)

  • Description

    Read file and return it in a blob. If file does not exist or does not pass the ACL, def is returned.

  • Return

    A blob with the contents of file.

    • file

      The file to read.

    • def

      (Optional) The contents of the blob to return if there was an error reading the file. Defaults to NULL.

read_into_synth

VOID .read_into_synth(STRING file, STRING def = NULL)

  • Description

    Return a file as a synthetic response body. Only accessible through vcl_synth and vcl_backend_error. If file does not exist or does not pass the ACL, def is returned.

    • file

      The file to read.

    • def

      The string to return if there was an error reading the file. Defaults to NULL.

write

INT .write(STRING file, STRING str, BOOL create_dir = false, INT dir_perm = 755)

  • Description

    Write to a file, file, consisting of str. If create_dir = true and a directory above the file does not exist it will be created with permission dir_perm. Must Pass ACL.

  • Return

    The number of bytes written. On failure, return -1.

    • file

      The path to the file to write. If the file doesn’t exist, it will be created.

    • str

      The contents to write to the file.

    • create_dir

      If true, create the path to the file if any of the sub directories do not exist. Defaults to false.

    • dir_perm

      The permission of the directory that will be created if create_dir = true. Defaults to 755.

write_blob

INT .write(STRING file, BLOB blb, BOOL create_dir = false, INT dir_perm = 755)

  • Description

    Write to a file, file, with the contents of blb. If create_dir = true and a directory above the file does not exist it will be created with permission dir_perm. Must Pass ACL.

  • Return

    The number of bytes written. On failure, return -1.

    • file

      The path to the file to write. If the file doesn’t exist, it will be created.

    • blb

      The object holding the contents to write to the file.

    • create_dir

      If true, create the path to the file if any of the sub directories do not exist. Defaults to false.

    • dir_perm

      The permission of the directory that will be created if create_dir = true. Defaults to 755.

write_req_body

INT .write_req_body(STRING file_path, BOOL create_dir = false, INT dir_perm = 755)

  • Description

    Write to a file, file_path, the request body. If create_dir = true and a directory above the file does not exist it will be created with permission dir_perm. This can only can be called in vcl_recv. std.cache_req_body() must be called before using this.

  • Return

    The number of bytes written. On failure, return -1.

    • file_path

      The path to the file to write. If it doesn’t exist, it will be created.

    • create_dir

      If true, create the path to the file if any of the sub directories do not exist. Defaults to false.

    • dir_perm

      The permission of the directory that will be created if create_dir = true. Defaults to 755.

delete

BOOL .delete(STRING path, BOOL recursive = false)

  • Description

    Delete a path. If a directory is to be deleted, recursive must be set to true. path must pass the ACL.

  • Return

    true on success. On failure or if the path is a directory and recursive = false, return false.

    • file

      The file to delete.

exec

STRING .exec(STRING path, STRANDS arguments = NULL, STRING checksum = NULL, DURATION timeout = 60s, BOOL output_stdout = true, BOOL output_stderr = true, STRING def = NULL)

  • Description

    Run a binary or script and return the output in string. Must pass the ACL. Scripts must have execute permission and contain a first line of:

     #! interpreter [optional-arg]
    
  • Return

    A string of the contents of the output of the binary or script.

    • path

      The path to the binary or script. This path is always considered to be absolute.

    • arguments

      (Optional) Arguments for the script or binary. Defaults to NULL.

    • checksum

      (Optional) Compare the script or binary against the given checksum. If the checksum fails. the binary or script is not run. The checksum format is sha256 Defaults to NULL.

    • timeout

      (Optional) How long should the binary or script run before being timedout. If it is less than 0 the request will fail. If it is equal to 0 never timeout. Defaults to 60s.

    • output_stdout

      (Optional) Should the output of stdout be returned? Defaults to true.

    • output_stderr

      (Optional) Should the output of stderr be returned? Defaults to true.

    • deff

      (Optional) String to return if there is an error. Defaults to NULL.

exec_get_errorcode

INT .exec_get_errorcode()

  • Description

Get the response code from the previous .exec() call. This value is -1 until the binary or script is called in .exec() and produces a response code.

  • Return

If .exec() has not been called, the request will fail. Otherwise return the response code from the .exec() call.

exists

BOOL .exists(STRING path, STRING mode, ENUM {FILE, DIR, BOTH} type = FILE)

  • Description

    Check if the path exists.

  • Return

    Return true if the path exists and passes the ACL, otherwise return false.

    • path

      The path to check if it exists.

    • mode

      What access type should this path have? This can be any combination of read (r), write (w), or execute (x). Defaults to r.

    • type

      Choose to limit the scope of this function to only files, only directories or both files and directories. Defaults to FILE.

lastaccess

TIME .lastaccess(STRING path, ENUM {FILE, DIR, BOTH} type = FILE)

  • Description

    Return the time (Unix time) that the path was last accessed. This time is updated when the following system functions are called: execve(2), mknod(2), pipe(2), utime(2), and read(2) (of more than zero bytes).

  • Return

    The time since the path had last been accessed. If path does not exist or does not pass the ACL, return 0.

    • path

      The path to get the last access time from.

    • type

      Choose to limit the scope of this function to only files, only directories or both files and directories. Defaults to FILE.

lastmodified

TIME .lastmodified(STRING path, ENUM {FILE, DIR, BOTH} type = FILE)

  • Description

    Return the time (Unix time) that the path was last modified. This time is updated when the following system functions are called: mknod(2), truncate(2), utime(2), and write(2) (of more than zero bytes).

  • Return

    The time since the path had last been modified. If path does not exist or does not pass the ACL , return 0.

    • path

      The path to get the last modified time from.

    • type

      Choose to limit the scope of this function to only files, only directories or both files and directories. Defaults to FILE.

laststatus

TIME .laststatus(STRING path, ENUM {FILE, DIR, BOTH} type = FILE)

  • Description

    Return the time (Unix time) that path last had a status change. This time is updated by writing or setting inode information (i.e., owner, group, link count, mode, etc.).

  • Return

    The time since the path last had a status change. If path does not exist or does not pass the ACL, return 0.

    • path

      The path to get the last status change time from.

    • type

      Choose to limit the scope of this function to only files, only directories or both files and directories. Defaults to FILE.

size

BYTES .size(STRING path, ENUM {FILE, DIR, BOTH} type = FILE)

  • Description

    Return the size of the path in bytes.

  • Return

    The number of bytes that the file contains. If path does not exist or does not pass the ACL, return -1.

    • path

      The path to get the size of.

    • type

      Choose to limit the scope of this function to only files, only directories or both files and directories. Defaults to FILE.

arg

STRING file.arg(STRING str)

  • Description

Allow a string literal to be used with STRANDS so it can be read in .exec() arguments.

  • Return

The string literal in a format that can be read by strands.

  • arg

    String literal (i.e "argument").

split_args

STRANDS file.split_args(STRING str)

  • Description

Turn a string into a STRANDS object to be read in .exec() arguments. The string is broken up in two ways, by whitespace or matching quotes. Quotes will be de deliminated by a matching quote followed by any whitespace character or the end of the string. Both single and double quotes are supported. This can be used to pass in multiple arguments to .exec().

  • Return

The string broken into individual strings.

  • arg

    String to break up. (i.e -q 'ReqURL ~ "/abcd"')