Provided by: varnish-re2_2.0.0-2build1_amd64 bug

NAME

       vmod_re2 - Varnish Module for access to the Google RE2 regular expression engine

SYNOPSIS

          import re2;

          # regex object interface
          new OBJECT = re2.regex(STRING pattern [, <regex options>])
          BOOL <obj>.match(STRING)
          STRING <obj>.backref(INT ref)
          STRING <obj>.namedref(STRING name)
          STRING <obj>.sub(STRING text, STRING rewrite)
          STRING <obj>.suball(STRING text, STRING rewrite)
          STRING <obj>.extract(STRING text, STRING rewrite)
          INT <obj>.cost()

          # regex function interface
          BOOL re2.match(STRING pattern, STRING subject [, <regex options>])
          STRING re2.backref(INT ref)
          STRING re2.namedref(STRING name)
          STRING re2.sub(STRING pattern, STRING text, STRING rewrite
                         [, <regex options>])
          STRING re2.suball(STRING pattern, STRING text, STRING rewrite
                            [, <regex options>])
          STRING re2.extract(STRING pattern, STRING text, STRING rewrite
                             [, <regex options>])
          INT re2.cost(STRING pattern [, <regex options>])

          # set object interface
          new OBJECT = re2.set([ENUM anchor] [, <regex options>])
          VOID <obj>.add(STRING [, BOOL save] [, BOOL never_capture] [, STRING string]
                         [, BACKEND backend] [, INT integer] [,SUB sub])
          BOOL <obj>.match(STRING)
          INT <obj>.nmatches()
          BOOL <obj>.matched(INT)
          INT <obj>.which([ENUM select])
          STRING <obj>.string([INT n,] [ENUM select])
          BACKEND <obj>.backend([INT n,] [ENUM select])
          INT     <obj>.integer([INT n] [, ENUM select])
          SUB     <obj>.subroutine([INT n] [, ENUM select])
          BOOL    <obj>.check_call([INT n] [, ENUM select])
          STRING <obj>.sub(STRING text, STRING rewrite [, INT n]
                           [, ENUM select])
          STRING <obj>.suball(STRING text, STRING rewrite [, INT n]
                              [, ENUM select])
          STRING <obj>.extract(STRING text, STRING rewrite [, INT n]
                               [, ENUM select])
          BOOL <obj>.saved([ENUM {REGEX, STR, BE, INT, SUB} which] [, INT n]
                           [, ENUM select])
          VOID <obj>.hdr_filter(HTTP [, BOOL])

          # utility function
          STRING re2.quotemeta(STRING)

          # VMOD version
          STRING re2.version()

DESCRIPTION

       Varnish Module (VMOD) for access to the Google RE2 regular expression engine.

       Varnish  VCL  uses  the  PCRE  library  (Perl  Compatible  Regular  Expressions)  for  its native regular
       expressions, which runs very efficiently for many common uses of pattern matching in VCL, as attested  by
       years of successful use of PCRE with Varnish.

       But  for certain kinds of patterns, the worst-case running time of the PCRE matcher is exponential in the
       length of the string to be matched. The matcher uses backtracking, implemented with  recursive  calls  to
       the internal match() function. In principle there is no upper bound to the possible depth of backtracking
       and   recursion,   except   as   imposed   by   the  varnishd  runtime  parameters  pcre_match_limit  and
       pcre_match_limit_recursion; matches fail if either of these limits are met. Stack overflow caused by deep
       backtracking has occasionally been the subject of varnishd issues.

       RE2 differs from PCRE in that it limits the syntax of patterns so that  they  always  specify  a  regular
       language  in  the formally strict sense. Most notably, backreferences within a pattern are not permitted,
       for example (foo|bar)\1 to match foofoo and barbar, but not foobar or barfoo. See the link  in  SEE  ALSO
       for the specification of RE2 syntax.

       This  means  that  an RE2 matcher runs as a finite automaton, which guarantees linear running time in the
       length of the matched string. There is no backtracking, and hence no risk  of  deep  recursion  or  stack
       overflow.

       The  relative  advantages  and disadvantages of RE2 and PCRE is a broad subject, beyond the scope of this
       manual. See the references in SEE ALSO for more in-depth discussion.

   regex object and function interfaces
       The VMOD provides regular expression operations by way of the regex object  interface  and  a  functional
       interface.  For  regex  objects,  the  pattern  is  compiled at VCL initialization time, and the compiled
       pattern is re-used for each invocation of its  methods.  Compilation  failures  (due  to  errors  in  the
       pattern)  cause failure at initialization time, and the VCL fails to load. The .backref() and .namedref()
       methods refer back to the last invocation of the .match() method for the same object.

       The functional interface provides the same set of operations, but the pattern is compiled at  runtime  on
       each invocation (and then discarded). Compilation failures are reported as errors in the Varnish log. The
       backref()  and  namedref()  functions  refer back to the last invocation of the match() function, for any
       pattern.

       Compiling a pattern at runtime on each invocation is considerably more costly than  re-using  a  compiled
       pattern.  So  for patterns that are fixed and known at VCL initialization, the object interface should be
       used. The functional interface should only be used for  patterns  whose  contents  are  not  known  until
       runtime.

   set object interface
       set  objects  provide  a shorthand for constructing patterns that consist of an alternation -- a group of
       patterns combined with | for "or". For example:

          import re2;

          sub vcl_init {
                new myset = re2.set();
                myset.add("foo");       # Pattern 1
                myset.add("bar");       # Pattern 2
                myset.add("baz");       # Pattern 3
          }

       myset.match(<string>) can now be used to match a string against the pattern foo|bar|baz. When a match  is
       successful, the matcher has determined all of the patterns that matched. These can then be retrieved with
       the  method  .nmatches()  for the number of matched patterns, and with .matched(n), which returns true if
       the nth pattern matched, where the patterns are numbered in the order in which they were added:

          if (myset.match("foobar")) {
              std.log("Matched " + myset.nmatches() + " patterns");
              if (myset.matched(1)) {
                  # Pattern /foo/ matched
                  call do_foo;
              }
              if (myset.matched(2)) {
                  # Pattern /bar/ matched
                  call do_bar;
              }
              if (myset.matched(3)) {
                  # Pattern /baz/ matched
                  call do_baz;
              }
          }

       An advantage of alternations and sets with RE2, as opposed to an alternation  in  PCRE  or  a  series  of
       separate  matches in an if-elsif-elsif sequence, comes from the fact that the matcher is implemented as a
       state machine. That means that the matcher progresses  through  the  string  to  be  matched  just  once,
       following patterns in the set that match through the state machine, or determining that there is no match
       as  soon  as  there are no more possible paths in the state machine. So a string can be matched against a
       large set of patterns in time that is proportional to  the  length  of  the  string  to  be  matched.  In
       contrast,  PCRE  matches  patterns in an alternation one after another, stopping after the first matching
       pattern, or attempting matches against all of them if  there  is  no  match.  Thus  a  match  against  an
       alternation in PCRE is not unlike an if-elsif-elsif sequence of individual matches, and requires the time
       needed for each individual match, overall in proportion with the number of patterns to be matched.

       Another  advantage  of  the  VMOD's  set  object is the ability to associate strings or backends with the
       patterns added to the set with the .add() method:

          sub vcl_init {
                new prefix = re2.set(anchor=start);
                prefix.add("/foo", string="www.domain1.com");
                prefix.add("/bar", string="www.domain2.com");
                prefix.add("/baz", string="www.domain3.com");
                prefix.add("/quux", string="www.domain4.com");

                new appmatcher = re2.set(anchor=start);
                appmatcher.add("/foo", backend=app1);
                appmatcher.add("/bar", backend=app2);
                appmatcher.add("/baz", backend=app3);
                appmatcher.add("/quux", backend=app4);
          }

       After a successful match, the string or backend associated with the matching  pattern  can  be  retrieved
       with  the  .string() and .backend() methods. This makes it possible, for example, to construct a redirect
       response or choose the backend with code that is both efficient and compact, even with  a  large  set  of
       patterns to be matched:

          # Use the prefix object to construct a redirect response from
          # a matching request URL.
          sub vcl_recv {
              if (prefix.match(req.url)) {
                  # Pass the string associated with the matching pattern
                  # to vcl_synth.
                  return(synth(1301, prefix.string()));
              }
          }

          sub vcl_synth {
              # The string associated with the matching pattern is in
              # resp.reason.
              if (resp.status == 1301) {
                  set resp.http.Location = "http://" + resp.reason + req.url;
                  set resp.status = 301;
                  set resp.reason = "Moved Permanently";
              }
          }

          # Use the appmatcher object to choose a backend based on the
          # request URL prefix.
          sub vcl_recv {
              if (appmatcher.match(req.url)) {
                  set req.backend_hint = appmatcher.backend();
              }
          }

   regex options
       Where  a  pattern  is  compiled  --  in  the  regex  and  set constructors, and in functions that require
       compilation -- options may be specified that  can  affect  the  interpretation  of  the  pattern  or  the
       operation  of  the matcher. There are default values for each option, and it is only necessary to specify
       options in VCL that differ from the defaults. Options specified in a set constructor apply to all of  the
       patterns in the resulting alternation.

       utf8   If  true,  characters  in  a  pattern match Unicode code points, and hence may match more than one
              byte. If false, the pattern and strings to be matched are interpreted as Latin-1 (ISO 8859-1), and
              a pattern character matches exactly one byte. Default is false. Note that this  differs  from  the
              RE2 default.

       posix_syntax
              If  true, patterns are restricted to POSIX (egrep) syntax. Otherwise, the pattern syntax resembles
              that of PCRE, with some deviations. See the link in SEE ALSO for the syntax specification. Default
              is false.  The options perl_classes, word_boundary and  one_line  are  only  consulted  when  this
              option is true.

       longest_match
              If  true,  the  matcher  searches  for the longest possible match where alternatives are possible.
              Otherwise, search for the first match. For example with the pattern a(b|bb) and  the  string  abb,
              abb  matches when longest_match is true, and backref 1 is bb. Otherwise, ab matches, and backref 1
              is b. Default is false.

       max_mem
              An upper bound (in bytes) for the size of the compiled pattern.  If  max_mem  is  too  small,  the
              matcher may fall back to less efficient algorithms, or the pattern may fail to compile. Default is
              the RE2 default (8MB), which should suffice for typical patterns.

       literal
              If  true,  the pattern is interpreted as a literal string, and no regex metacharacters (such as *,
              +, ^ and so forth) have their special meaning. Default is false.

       never_nl
              If true, the newline character \n in a string is never matched, even if it appears in the pattern.
              Default is false.

       dot_nl If true, then the dot character . in a pattern matches everything, including newline. Otherwise, .
              never matches newline. Default is false.

       never_capture
              If true, parentheses in a pattern are interpreted as non-capturing, and  all  invocations  of  the
              backref  and  namedref  methods  or  functions  will  lead to VCL faillure (see ERRORS), including
              backref(0) after a successful  match.  Default  is  false,  except  for  set  objects,  for  which
              never_capture  is always true (and cannot be changed), since back references are not possible with
              sets.

       case_sensitive
              If true, matches are case-sensitive. A pattern can override this option with the (?i) flag, unless
              posix_syntax is true. Default is true.

       The following options are only consulted when posix_syntax is true. If posix_syntax is false, then  these
       features are always enabled and cannot be turned off.

       perl_classes
              If  true,  then  the  perl character classes \d, \s, \w, \D, \S and \W are permitted in a pattern.
              Default is false.

       word_boundary
              If true, the perl assertions \b and \B (word boundary and not  a  word  boundary)  are  permitted.
              Default is false.

       one_line
              If  true, then ^ and $ only match at the beginning and end of the string to be matched, regardless
              of newlines. Otherwise, ^ also matches just after a newline, and $  also  matches  just  before  a
              newline. Default is false.

   new  xregex  =  re2.regex(STRING pattern, BOOL utf8, BOOL posix_syntax, BOOL longest_match, INT max_mem, BOOL
       literal, BOOL never_nl, BOOL dot_nl, BOOL never_capture, BOOL  case_sensitive,  BOOL  perl_classes,  BOOL
       word_boundary, BOOL one_line)
          new xregex = re2.regex(
             STRING pattern,
             BOOL utf8=0,
             BOOL posix_syntax=0,
             BOOL longest_match=0,
             INT max_mem=8388608,
             BOOL literal=0,
             BOOL never_nl=0,
             BOOL dot_nl=0,
             BOOL never_capture=0,
             BOOL case_sensitive=1,
             BOOL perl_classes=0,
             BOOL word_boundary=0,
             BOOL one_line=0
          )

       Create a regex object from pattern and the given options (or option defaults). If the pattern is invalid,
       then VCL will fail to load and the VCC compiler will emit an error message.

       Example:

          sub vcl_init {
              new domainmatcher = re2.regex("^www\.([^.]+)\.com$");
              new maxagematcher = re2.regex("max-age\s*=\s*(\d+)");

              # Group possible subdomains without capturing
              new submatcher = re2.regex("^www\.(domain1|domain2)\.com$",
                                         never_capture=true);
          }

   BOOL xregex.match(STRING)
       Returns  true  if  and  only  if  the compiled regex matches the given string; corresponds to VCL's infix
       operator ~.

       Example:

          if (myregex.match(req.http.Host)) {
             call do_on_match;
          }

   STRING xregex.backref(INT ref, STRING fallback)
          STRING xregex.backref(
                INT ref,
                STRING fallback="**BACKREF METHOD FAILED**"
          )

       Returns the nth captured subexpression from the most recent successful call of the  .match()  method  for
       this  object  in  the  same  client  or  backend context, or a fallback string in case the capture fails.
       Backref 0 indicates the entire matched string. Thus this function behaves like the  \n  notation  in  the
       native VCL functions regsub and regsuball, and the $1, $2 ... variables in Perl.

       Since Varnish client and backend operations run in different threads, .backref() can only refer back to a
       .match()  call  in the same thread. Thus a .backref() call in any of the vcl_backend_* subroutines -- the
       backend context -- refers back to a previous .match() in any of those same subroutines; and a call in any
       of the other VCL subroutines -- the client context -- refers back  to  a  .match()  in  the  same  client
       context.

       .backref()  may  return  fallback  after  a successful match, if no captured group in the matching string
       corresponds to the backref number. For example, when the pattern (a|(b))c matches the string ac, there is
       no backref 2, since nothing matches b in the string. The default value of fallback is  "**BACKREF  METHOD
       FAILED**", but you may set another value (such as the empty string).

       After unsuccessful matches, .backref() invokes VCL failure (see ERRORS).  .backref() always fails after a
       failed match, even if .match() had been called successfully before the failure.

       The VCL infix operators ~ and !~ do not affect this method, nor do the functions regsub or regsuball. Nor
       is  it affected by the matches performed by any other method or function in this VMOD (such as the sub(),
       suball() or extract() methods or functions, or the set object's .match() method).

       .backref() invokes VCL failure under the following conditions, even if a previous  match  was  successful
       and a substring could have been captured (see ERRORS):

       • The fallback string is undefined, for example if set from an unset header variable.

       • The  never_capture option was set to true for this object. In this case, even .backref(0) fails after a
         successful match (otherwise, backref 0 always returns the full matched string).

       • ref (the backref number) is out of range, i.e. it is larger than the highest  number  for  a  capturing
         group in the pattern.

       • .match() was never called for this object prior to calling .backref().

       • There is insufficient workspace for the string to be returned.

       Example:

          if (domainmatcher.match(req.http.Host)) {
             set req.http.X-Domain = domainmatcher.backref(1);
          }

   STRING xregex.namedref(STRING name, STRING fallback)
          STRING xregex.namedref(
                STRING name,
                STRING fallback="**NAMEDREF METHOD FAILED**"
          )

       Returns the captured subexpression designated by name from the most recent successful call to .match() in
       the current context (client or backend).

       Named  capturing  groups  are written in RE2 as: (?P<name>re). (Note that this syntax with P, inspired by
       Python, differs from the notation for named capturing groups in PCRE.) Thus when (?P<foo>.+)bar$  matches
       bazbar, then .namedref("foo") returns baz.

       Note that a named capturing group can also be referenced as a numbered group. So in the previous example,
       .backref(1) also returns baz.

       fallback  is  returned when the named reference did not match. The default fallback is "**NAMEDREF METHOD
       FAILED**".

       Like .backref(), .namedref() is not affected by native VCL regex operations, nor  by  any  other  matches
       performed by methods or functions of the VMOD, except for a prior .match() for the same object.

       .namedref() invokes VCL failure (see ERRORS) if:

       • The fallback string is undefined.

       • name is undefined or the empty string.

       • The never_capture option was set to true.

       • There is no such named group.

       • .match() was not called for this object.

       • There is insufficient workspace for the string to be returned.

       Example:

          sub vcl_init {
                new domainmatcher = re2.regex("^www\.(?P<domain>[^.]+)\.com$");
          }

          sub vcl_recv {
                if (domainmatcher.match(req.http.Host)) {
                   set req.http.X-Domain = domainmatcher.namedref("domain");
                }
          }

   STRING xregex.sub(STRING text, STRING rewrite, STRING fallback)
          STRING xregex.sub(
                STRING text,
                STRING rewrite,
                STRING fallback="**SUB METHOD FAILED**"
          )

       If the compiled pattern for this regex object matches text, then return the result of replacing the first
       match  in  text  with  rewrite.  Within  rewrite,  \1  through  \9 can be used to insert the the numbered
       capturing group from the pattern, and \0 to insert the entire matching text. This method  corresponds  to
       the VCL native function regsub().

       fallback is returned if the pattern does not match text. The default fallback is "**SUB METHOD FAILED**".

       .sub() invokes VCL failure (see ERRORS) if:

       • Any of text, rewrite or fallback are undefined.

       • There is insufficient workspace for the rewritten string.

       Example:

          sub vcl_init {
              new bmatcher = re2.regex("b+");
          }

          sub vcl_recv {
              # If Host contains "www.yabba.dabba.doo.com", then this will
              # set X-Yada to "www.yada.dabba.doo.com".
              set req.http.X-Yada = bmatcher.sub(req.http.Host, "d");
          }

   STRING xregex.suball(STRING text, STRING rewrite, STRING fallback)
          STRING xregex.suball(
                STRING text,
                STRING rewrite,
                STRING fallback="**SUBALL METHOD FAILED**"
          )

       Like  .sub(),  except that all successive non-overlapping matches in text are replaced with rewrite. This
       method corresponds to VCL native regsuball().

       The default fallback is "**SUBALL METHOD FAILED**". .suball() fails under the same conditions as .sub().

       Since only non-overlapping matches are substituted, replacing "ana" within "banana" only results  in  one
       substitution, not two.

       Example:

          sub vcl_init {
              new bmatcher = re2.regex("b+");
          }

          sub vcl_recv {
              # If Host contains "www.yabba.dabba.doo.com", then set X-Yada to
              # "www.yada.dada.doo.com".
              set req.http.X-Yada = bmatcher.suball(req.http.Host, "d");
          }

   STRING xregex.extract(STRING text, STRING rewrite, STRING fallback)
          STRING xregex.extract(
                STRING text,
                STRING rewrite,
                STRING fallback="**EXTRACT METHOD FAILED**"
          )

       If  the  compiled pattern for this regex object matches text, then return rewrite with substitutions from
       the matching portions of text. Non-matching substrings of text are ignored.

       The default fallback is "**EXTRACT METHOD FAILED**". Like .sub() and .suball(), .extract() fails if:

       • Any of text, rewrite or fallback are undefined.

       • There is insufficient workspace for the rewritten string.

       Example:

          sub vcl_init {
              new email = re2.regex("(.*)@([^.]*)");
          }

          sub vcl_deliver {
              # Sets X-UUCP to "kremvax!boris"
              set resp.http.X-UUCP = email.extract("boris@kremvax.ru", "\2!\1");
          }

   INT xregex.cost()
       Return a numeric measurement > 0 for this regex object from  the  RE2  library.   According  to  the  RE2
       documentation:
          ...  a  very  approximate measure of a regexp's "cost". Larger numbers are more expensive than smaller
          numbers.

       The absolute numeric values are opaque and not relevant, but they are meaningful relative to one  another
       --  more  complex  regexen  have  a  higher  cost  than  less  complex regexen. This may be useful during
       development and optimization of regular expressions.

       Example:

          std.log("r1 cost=" + r1.cost() + " r_alt cost=" + r_alt.cost());

REGEX FUNCTIONAL INTERFACE

   BOOL match(STRING pattern, STRING subject, BOOL utf8, BOOL posix_syntax,  BOOL  longest_match,  INT  max_mem,
       BOOL  literal,  BOOL  never_nl,  BOOL dot_nl, BOOL never_capture, BOOL case_sensitive, BOOL perl_classes,
       BOOL word_boundary, BOOL one_line)
          BOOL match(
             STRING pattern,
             STRING subject,
             BOOL utf8=0,
             BOOL posix_syntax=0,
             BOOL longest_match=0,
             INT max_mem=8388608,
             BOOL literal=0,
             BOOL never_nl=0,
             BOOL dot_nl=0,
             BOOL never_capture=0,
             BOOL case_sensitive=1,
             BOOL perl_classes=0,
             BOOL word_boundary=0,
             BOOL one_line=0
          )

       Like the regex.match() method, return true if pattern matches subject, where pattern is compiled with the
       given options (or default options) on each invocation.

       If pattern fails to compile, then VCL failure is invoked (see ERRORS).

       Example:

          # Match the bereq Host header against a backend response header
          if (re2.match(pattern=bereq.http.Host, subject=beresp.http.X-Host)) {
             call do_on_match;
          }

   STRING backref(INT ref, STRING fallback)
          STRING backref(
             INT ref,
             STRING fallback="**BACKREF FUNCTION FAILED**"
          )

       Returns the nth captured subexpression from the most recent successful call of the  match()  function  in
       the current client or backend context, or a fallback string if the capture fails. The default fallback is
       "**BACKREF FUNCTION FAILED**".

       Similarly to the regex.backref() method, fallback is returned if there is no captured group corresponding
       to  the  backref number. The function is not affected by native VCL regex operations, or any other method
       or function of the VMOD except for the match() function.

       The function invokes VCL failure under the same conditions as the corresponding method (see ERRORS):

       • fallback is undefined.

       • never_capture was true in the previous invocation of the match() function.

       • ref is out of range.

       • The match() function was never called in this context, or if the previous match() call failed (returned
         false).

       • The pattern failed to compile for the previous match() call.

       • There is insufficient workspace for the captured subexpression.

       Example:

          # Match against a pattern provided in a beresp header, and capture
          # subexpression 1.
          if (re2.match(pattern=beresp.http.X-Pattern, bereq.http.X-Foo)) {
             set beresp.http.X-Capture = re2.backref(1);
          }

   STRING namedref(STRING name, STRING fallback)
          STRING namedref(
             STRING name,
             STRING fallback="**NAMEDREF FUNCTION FAILED**"
          )

       Returns the captured subexpression designated by name from the most recent successful call to the match()
       function in the current context, or fallback if the  corresponding  group  did  not  match.  The  default
       fallback is "**NAMEDREF FUNCTION FAILED**".

       The function invokes VCL failure under the same conditions as the corresponding method (see ERRORS):

       • fallback is undefined.

       • name is undefined or the empty string.

       • The never_capture option was set to true.

       • There is no such named group.

       • match() was not called in this context, or the previous call failed.

       • The pattern failed to compile for the previous match() call.

       • There is insufficient workspace for the captured expression.

       Example:

          if (re2.match(beresp.http.X-Pattern-With-Names, bereq.http.X-Foo)) {
             set beresp.http.X-Capture = re2.namedref("foo");
          }

   STRING  sub(STRING  pattern, STRING text, STRING rewrite, STRING fallback, BOOL utf8, BOOL posix_syntax, BOOL
       longest_match,  INT  max_mem,  BOOL  literal,  BOOL  never_nl,  BOOL  dot_nl,  BOOL  never_capture,  BOOL
       case_sensitive, BOOL perl_classes, BOOL word_boundary, BOOL one_line)
          STRING sub(
             STRING pattern,
             STRING text,
             STRING rewrite,
             STRING fallback="**SUB FUNCTION FAILED**",
             BOOL utf8=0,
             BOOL posix_syntax=0,
             BOOL longest_match=0,
             INT max_mem=8388608,
             BOOL literal=0,
             BOOL never_nl=0,
             BOOL dot_nl=0,
             BOOL never_capture=0,
             BOOL case_sensitive=1,
             BOOL perl_classes=0,
             BOOL word_boundary=0,
             BOOL one_line=0
          )

       Compiles  pattern with the given options, and if it matches text, then return the result of replacing the
       first match in text with rewrite. As with the regex.sub() method, \0 through \9 may be used in rewrite to
       substitute captured groups from the pattern.

       fallback is returned if the pattern does  not  match  text.  The  default  fallback  is  "**SUB  FUNCTION
       FAILED**".

       sub() invokes VCL failure (see ERRORS) if:

       • pattern cannot be compiled.

       • Any of text, rewrite or fallback are undefined.

       • There is insufficient workspace for the rewritten string.

       Example:

          # If the beresp header X-Sub-Letters contains "b+", and Host contains
          # "www.yabba.dabba.doo.com", then set X-Yada to
          # "www.yada.dabba.doo.com".
          set beresp.http.X-Yada = re2.sub(beresp.http.X-Sub-Letters,
                                           bereq.http.Host, "d");

   STRING  suball(STRING  pattern,  STRING  text, STRING rewrite, STRING fallback, BOOL utf8, BOOL posix_syntax,
       BOOL longest_match, INT max_mem, BOOL literal, BOOL  never_nl,  BOOL  dot_nl,  BOOL  never_capture,  BOOL
       case_sensitive, BOOL perl_classes, BOOL word_boundary, BOOL one_line)
          STRING suball(
             STRING pattern,
             STRING text,
             STRING rewrite,
             STRING fallback="**SUBALL FUNCTION FAILED**",
             BOOL utf8=0,
             BOOL posix_syntax=0,
             BOOL longest_match=0,
             INT max_mem=8388608,
             BOOL literal=0,
             BOOL never_nl=0,
             BOOL dot_nl=0,
             BOOL never_capture=0,
             BOOL case_sensitive=1,
             BOOL perl_classes=0,
             BOOL word_boundary=0,
             BOOL one_line=0
          )

       Like  the  sub()  function,  except  that all successive non-overlapping matches in text are replace with
       rewrite.

       The default fallback is "**SUBALL  FUNCTION  FAILED**".  The  suball()  function  fails  under  the  same
       conditions as sub().

       Example:

          # If the beresp header X-Sub-Letters contains "b+", and Host contains
          # "www.yabba.dabba.doo.com", then set X-Yada to
          # "www.yada.dada.doo.com".
          set beresp.http.X-Yada = re2.suball(beresp.http.X-Sub-Letters,
                                              bereq.http.Host, "d");

   STRING  extract(STRING  pattern,  STRING text, STRING rewrite, STRING fallback, BOOL utf8, BOOL posix_syntax,
       BOOL longest_match, INT max_mem, BOOL literal, BOOL  never_nl,  BOOL  dot_nl,  BOOL  never_capture,  BOOL
       case_sensitive, BOOL perl_classes, BOOL word_boundary, BOOL one_line)
          STRING extract(
             STRING pattern,
             STRING text,
             STRING rewrite,
             STRING fallback="**EXTRACT FUNCTION FAILED**",
             BOOL utf8=0,
             BOOL posix_syntax=0,
             BOOL longest_match=0,
             INT max_mem=8388608,
             BOOL literal=0,
             BOOL never_nl=0,
             BOOL dot_nl=0,
             BOOL never_capture=0,
             BOOL case_sensitive=1,
             BOOL perl_classes=0,
             BOOL word_boundary=0,
             BOOL one_line=0
          )

       Compiles  pattern  with the given options, and if it matches text, then return rewrite with substitutions
       from the matching portions of text, ignoring the non-matching portions.

       The default fallback is "**EXTRACT FUNCTION FAILED**".  The  extract()  function  fails  under  the  same
       conditions as sub() and suball().

       Example:

          # If beresp header X-Params contains "(foo|bar)=(baz|quux)", and the
          # URL contains "bar=quux", then set X-Query to "bar:quux".
          set beresp.http.X-Query = re2.extract(beresp.http.X-Params, bereq.url,
                                                "\1:\2");

   INT  cost(STRING  pattern,  BOOL utf8, BOOL posix_syntax, BOOL longest_match, INT max_mem, BOOL literal, BOOL
       never_nl, BOOL dot_nl, BOOL never_capture, BOOL case_sensitive, BOOL  perl_classes,  BOOL  word_boundary,
       BOOL one_line)
          INT cost(
             STRING pattern,
             BOOL utf8=0,
             BOOL posix_syntax=0,
             BOOL longest_match=0,
             INT max_mem=8388608,
             BOOL literal=0,
             BOOL never_nl=0,
             BOOL dot_nl=0,
             BOOL never_capture=0,
             BOOL case_sensitive=1,
             BOOL perl_classes=0,
             BOOL word_boundary=0,
             BOOL one_line=0
          )

       Like the .cost() method above, return a numeric measurement > 0 from the RE2 library for pattern with the
       given options. More complex regexen have a higher cost than less complex regexen.

       Invokes VCL failure if pattern cannot be compiled (see ERRORS).

       Example:

          std.log("simple cost=" + re2.cost("simple")
                  + " complex cost=" + re2.cost("complex{1,128}"));

   new  xset = re2.set(ENUM anchor, BOOL utf8, BOOL posix_syntax, BOOL longest_match, INT max_mem, BOOL literal,
       BOOL never_nl, BOOL dot_nl, BOOL case_sensitive, BOOL perl_classes, BOOL word_boundary, BOOL one_line)
          new xset = re2.set(
             ENUM {none, start, both} anchor=none,
             BOOL utf8=0,
             BOOL posix_syntax=0,
             BOOL longest_match=0,
             INT max_mem=8388608,
             BOOL literal=0,
             BOOL never_nl=0,
             BOOL dot_nl=0,
             BOOL case_sensitive=1,
             BOOL perl_classes=0,
             BOOL word_boundary=0,
             BOOL one_line=0
          )

       Initialize a set object that represents several patterns combined by alternation -- | for "or".

       Optional parameters control the interpretation of the resulting composed pattern. The anchor parameter is
       an enum that can have the values none, start or both, where none is the default. start  means  that  each
       pattern is matched as if it begins with ^ for start-of-text, and both means that each pattern is anchored
       with  both  ^  at  the  beginning  and  $  for  end-of-text  at  the end. none means that each pattern is
       interpreted as a partial match (although individual patterns within the set may have either of ^ of $).

       For example, if a set is initialized with anchor=both, and the patterns  foo  and  bar  are  added,  then
       matches against the set match a string against ^foo$|^bar$, or equivalently ^(foo|bar)$.

       The  usual  regex options can be set, which then control matching against the resulting composed pattern.
       However, the never_capture option cannot be set, and  is  always  implicitly  true,  since  backrefs  and
       namedrefs are not possible with sets.

       Sets  are  compiled  automatically  when  vcl_init  finishes (or when the deprecated .compile() method is
       called). Compilation fails if any of the added patterns cannot be compiled, or if no patterns were  added
       to the set. It may also fail if the max_mem setting is not large enough for the composed pattern. In that
       case,  the  VCL load will fail with an error message (then consider a larger value for max_mem in the set
       constructor).

       Example:

          sub vcl_init {
                # Initialize a regex set for partial matches
                # with default options
                new foo = re2.set();

                # Initialize a regex set for case insensitive matches
                # with anchors on both ends (^ and $).
                new bar = re2.set(anchor=both, case_sensitive=false);

                # Initialize a regex set using POSIX syntax, but allowing
                # Perl character classes, and anchoring at the left (^).
                new baz = re2.set(anchor=start, posix_syntax=true,
                                  perl_classes=true);
          }

   VOID xset.add(STRING, [STRING string], [BACKEND backend], [BOOL save], [BOOL never_capture],  [INT  integer],
       [SUB sub])
          VOID xset.add(
                STRING,
                [STRING string],
                [BACKEND backend],
                [BOOL save],
                [BOOL never_capture],
                [INT integer],
                [SUB sub]
          )

       Add the given pattern to the set. If the pattern is invalid, .add() fails, and the VCL will fail to load,
       with an error message describing the problem.

       If  values  for the string, backend, integer and/or sub parameters are provided, then these values can be
       retrieved with  the  .string(),  .backend(),  .integer()  and  .subroutine()  methods,  respectively,  as
       described  below.  This  makes  it  possible  to  associate  data with the added pattern after it matches
       successfully. By default the pattern is not associated with any such value.

       If save is true, then the given pattern is compiled and saved as a regex object, just  as  if  the  regex
       constructor  described  above  is  invoked.  This  object  is  stored  internally in the set object as an
       independent matcher, separate from "compound" pattern formed by the set as an alternation of the patterns
       added to it. By default, save is false.

       When the .match() method on the set is successful, and one of the patterns  that  matched  is  associated
       with  a  saved internal regex object, then that object may be used for subsequent method invocations such
       as .sub() on the set object, whose meanings are the same as documented above for regex  objects.  Details
       are described below.

       When  an  internal  regex  object is saved (i.e. when save is true), it is compiled with the same options
       that were provided to the set object in the constructor. The never_capture option  can  also  be  set  to
       false for the individual regex, even though it is implicitly set to true for the full set object (default
       is false).

       .add()  MUST  be  called  in vcl_init, and MAY NOT be called after .compile().  VCL failure is invoked if
       .add() is called in any other subroutine (see ERRORS). If it is called in vcl_init after .compile(), then
       the VCL load will fail with an error message. Note that .compile() is now unnecessary and deprecated.

       When the .matched(INT) method is called after a successful match, the numbering corresponds to the  order
       in  which  patterns were added.  The same is true of the INT arguments that may be given for methods such
       as .string(), .backend() or .sub(), as described below.

       Example:

          sub vcl_init {
              # literal=true means that the dots are interpreted as literal
              # dots, not "match any character".
              new hostmatcher = re2.set(anchor=both, case_sensitive=false,
                                        literal=true);
              hostmatcher.add("www.domain1.com");
              hostmatcher.add("www.domain2.com");
              hostmatcher.add("www.domain3.com");
          }

          # See the documentation of the .string() and .backend() methods
          # below for uses of the parameters string and backend for .add().

   VOID xset.compile()
       This method is deprecated, and will be removed in a future version.  .compile()  may  be  omitted,  since
       compilation now happens automatically when vcl_init finishes.

       Compile the compound pattern represented by the set -- an alternation of all patterns added by .add().

       Compilation  may  fail  for  any  of  the  reasons  described for automatic compilation of set objects as
       described above.

       .compile() MUST be called in vcl_init, and MAY NOT be called more than once for a set object. VCL failure
       is invoked if it is called in any other subroutine. If it is called a second time in  vcl_init,  the  VCL
       load will fail.

   BOOL xset.match(STRING)
       Returns  true if the given string matches the compound pattern represented by the set, i.e. if it matches
       any of the patterns that were added to the set.

       The matcher identifies all of the patterns that were added to the set and match the given  string.  These
       can  be  determined  after  a  successful match using the .matched(INT) and .nmatches() methods described
       below.

       A match may also fail (leading to VCL failure) if the  internal  memory  limit  imposed  by  the  max_mem
       parameter  in  the  constructor is exceeded. (With the default value of max_mem, this ordinarily requires
       very large patterns and/or a very large string to be matched.)  Since about version 2017-12-01,  the  RE2
       library  reports this condition. If matches fail due to the out-of-memory condition, increase the max_mem
       parameter in the constructor.

       Example:

          if (hostmatcher.match(req.http.Host)) {
             call do_when_a_host_matched;
          }

   BOOL xset.matched(INT)
       Returns true after a successful match if the nth pattern that was added to the set is among the  patterns
       that  matched,  false otherwise. The numbering of the patterns corresponds to the order in which patterns
       were added in vcl_init, counting from 1.

       The method refers back to the most recent invocation of .match() for the same object in the  same  client
       or  backend  context. It always returns false, for every value of the parameter, if it is called after an
       unsuccessful match (.match() returned false).

       .matched() invokes VCL failure (see ERRORS) if:

       • The .match() method was not called for this object in the same client or backend scope.

       • The integer parameter is out of range; that is, if it is less than 1 or  greater  than  the  number  of
         patterns added to the set.

       Example:

          if (hostmatcher.match(req.http.Host)) {
              if (hostmatcher.matched(1)) {
                  call do_domain1;
              }
              if (hostmatcher.matched(2)) {
                  call do_domain2;
              }
              if (hostmatcher.matched(3)) {
                  call do_domain3;
              }
          }

   INT xset.nmatches()
       Returns  the  number of patterns that were matched by the most recent invocation of .match() for the same
       object in the same client or backend context. The method always returns 0  after  an  unsuccessful  match
       (.match() returned false).

       If  .match()  was not called for this object in the same client or backend scope, .nmatches() invokes VCL
       failure (see ERRORS).

       Example:

          if (myset.match(req.url)) {
              std.log("URL matched " + myset.nmatches()
                      + " patterns from the set");
          }

   INT xset.which(ENUM {FIRST, LAST, UNIQUE} select=UNIQUE)
       Returns a number indicating which pattern in a set matched in the most recent invocation of  .match()  in
       the  client  or  backend context. The number corresponds to the order in which patterns were added to the
       set in vcl_init, counting from 1.

       If exactly one pattern matched in the most recent .match() call (so that .nmatches() returns 1), and  the
       select ENUM is set to UNIQUE, then the number for that pattern is returned. select defaults to UNIQUE, so
       it can be left out in this case.

       If more than one pattern matched in the most recent .match() call (.nmatches() > 1), then the select ENUM
       determines  the  integer  that  is returned. The values FIRST and LAST specify that, of the patterns that
       matched, the first or last one added via the .add() method is chosen, and the number for that pattern  is
       returned.

       .which() invokes VCL failure (see ERRORS) if:

       • .match()  was  not  called for the set in the current client or backend transaction, or if the previous
         call returned false.

       • More than one pattern in the set matched in the previous .match() call, but the select parameter is set
         to UNIQUE (or left out, since select defaults to UNIQUE).

       Examples:

          sub vcl_init {
              new myset = re2.set();
              myset.add("foo"); # Pattern 1
              myset.add("bar"); # Pattern 2
              myset.add("baz"); # Pattern 3
              myset.compile();
          }

          sub vcl_recv {
              if (myset.match("bar")) {
                  # myset.which() returns 2.
              }
              if (myset.which("foobaz")) {
                  # myset.which() fails and returns 0, with a log
                  #               message indicating that 2 patterns
                  #               matched.
                  # myset.which(FIRST) returns 1.
                  # myset.which(LAST) returns 3.
              }
              if (myset.match("quux")) {
                  # ...
              }
              else {
                  # myset.which() fails and returns 0, with either or
                  # no value for the select ENUM, with a log message
                  # indicating that the previous .match() call was
                  # unsuccessful.
              }

   STRING xset.string(INT n, ENUM select)
          STRING xset.string(
                INT n=0,
                ENUM {FIRST, LAST, UNIQUE} select=UNIQUE
          )

       Returns the string associated with the nth pattern added to the set, or with the pattern in the set  that
       matched  in  the  most  recent  call  to .match() in the same task scope (client or backend context). The
       string set with the string parameter of the .add() method during vcl_init is returned.

       The pattern is identified with the parameters n and select according to these rules, which also hold  for
       all further set methods documented in the following.

       • If  n  >  0, then select the nth pattern added to the set with the .add() method, counting from 1. This
         identifies the nth pattern in any context, regardless of whether .match()  was  called  previously,  or
         whether a previous call returned true or false. The select parameter is ignored in this case.

       • If  n  <=  0,  then  select  a  pattern in the set that matched successfully in the most recent call to
         .match() in the same task scope. Since n is 0 by default, n can be left out for this purpose.

       • If n <= 0 and exactly one pattern in the set matched in the most recent  invocation  of  .match()  (and
         hence .nmatches() returns 1), and select is set to UNIQUE, then select that pattern. select defaults to
         UNIQUE, so when exactly one pattern in the set matched, both n and select can be left out.

       • If  n  <=  0 and more than one pattern matched in the most recent .match() call (.nmatches() > 1), then
         the selection of a pattern is determined by the select parameter. As  with  .which(),  FIRST  and  LAST
         specify the first or last matching pattern added via the .add() method.

       For  the pattern selected by these rules, return the string that was set with the string parameter in the
       .add() method that added the pattern to the set.

       .string() invokes VCL failure (see ERRORS) if:

       • The values of n and select are invalid:

         • n is greater than the number of patterns in the set.

         • n <= 0 (or left to the default), but .match() was not called earlier in the same task  scope  (client
           or backend context).

         • n <= 0, but the previous .match() call returned false.

         • n  <= 0 and the select ENUM is UNIQUE (or default), but more than one pattern matched in the previous
           .match() call.  This can be avoided by checking for .nmatches() == 1.

       • No string was associated with the pattern selected by n and select; that is, the string  parameter  was
         not  set in the .add() call that added the pattern. This can be avoided by checking the .saved() method
         (see below).

       Examples:

          # Match the request URL against a set of patterns, and generate
          # a synthetic redirect response with a Location header derived
          # from the string assoicated with the matching pattern.

          # In the first example, exactly one pattern in the set matches.

          sub vcl_init {
              # With anchor=both, we specify exact matches.
              new matcher = re2.set(anchor=both);
              matcher.add("/foo/bar", "/baz/quux");
              matcher.add("/baz/bar/foo", "/baz/quux/foo");
              matcher.add("/quux/bar/baz/foo", "/baz/quux/foo/bar");
              matcher.compile();
          }

          sub vcl_recv {
              if (matcher.match(req.url)) {
                  # Confirm that there was exactly one match
                  if (matcher.nmatches() != 1) {
                      return(fail);
                  }
                  # Divert to vcl_synth, sending the string associated
                  # with the matching pattern in the "reason" field.
                  return(synth(1301, matcher.string()));
              }
          }

          sub vcl_synth {
              # Construct a redirect response, using the path set in
              # resp.reason.
              if (resp.status == 1301) {
                  set resp.http.Location
                      = "http://otherdomain.org" + resp.reason;
                  set resp.status = 301;
                  set resp.reason = "Moved Permanently";
                  return(deliver);
              }
          }

          # In the second example, the patterns that may match have
          # common prefixes, and more than one pattern may match. We
          # add patterns to the set in a "more specific" to "less
          # specific" order, and we choose the most specific pattern
          # that matches, by specifying the first matching pattern in
          # the set.

          sub vcl_init {
              # With anchor=start, we specify matching prefixes.
              new matcher = re2.set(anchor=start);
              matcher.add("/foo/bar/baz/quux", "/baz/quux");
              matcher.add("/foo/bar/baz", "/baz/quux/foo");
              matcher.add("/foo/bar", "/baz/quux/foo/bar");
              matcher.add("/foo", "/baz");
              matcher.compile();
          }

          sub vcl_recv {
              if (matcher.match(req.url)) {
                  # Select the first matching pattern
                  return(synth(1301, matcher.string(select=FIRST)));
              }
          }

          # vcl_synth is implemented as shown above

   BACKEND xset.backend(INT n, ENUM select)
          BACKEND xset.backend(
                INT n=0,
                ENUM {FIRST, LAST, UNIQUE} select=UNIQUE
          )

       Returns the backend associated with the nth pattern added to the set, or with the pattern in the set that
       matched in the most recent call to .match() in the same task scope (client or backend context).

       The rules for selecting a pattern from the set and its associated backend based on n and select  are  the
       same as described above for .string().

       .backend()  invokes  VCL  failure under the same conditions described for .string() above -- n and select
       are invalid, or no backend was associated with the selected pattern with the .add() method (see ERRORS).

       Example:

          # Choose a backend based on the URL prefix.

          # In this example, assume that backends b1 through b4
          # have been defined.

          sub vcl_init {
              # Use anchor=start to match prefixes.
              # The prefixes are unique, so exactly one will match.
              new matcher = re2.set(anchor=start);
              matcher.add("/foo", backend=b1);
              matcher.add("/bar", backend=b2);
              matcher.add("/baz", backend=b3);
              matcher.add("/quux", backend=b4);
              matcher.compile();
          }

          sub vcl_recv {
              if (matcher.match(req.url)) {
                  # Confirm that there was exactly one match
                  if (matcher.nmatches() != 1) {
                      return(fail);
                  }
                  # Set the backend hint to the backend associated
                  # with the matching pattern.
                  set req.backend_hint = matcher.backend();
              }
          }

   INT xset.integer(INT n, ENUM select)
          INT xset.integer(
                INT n=0,
                ENUM {FIRST, LAST, UNIQUE} select=UNIQUE
          )

       Returns the integer associated with the nth pattern added to the set, or with the pattern in the set that
       matched in the most recent call to .match() in the same task scope.

       The rules for selecting a pattern from the set and its associated integer based on n and select  are  the
       same as described above for .string().

       .integer()  invokes  VCL  failure  under the same error conditions described for .string() above -- n and
       select are invalid, or no integer was associated with the selected pattern with the  .add()  method  (see
       ERRORS).

       Example:

          # Generate redirect responses based on the Host header. In the
          # example, subdomains are removed in the new Location, and the
          # associated integer is used to set the redirect status code.

          sub vcl_init {
              # No more than one pattern can match the same string. So it
              # is safe to call .integer() with default select=UNIQUE in
              # vcl_recv below (no risk of VCL failure).
              new redir = re2.set(anchor=both);
              redir.add("www\.[^.]+\.foo\.com", integer=301, string="www.foo.com");
              redir.add("www\.[^.]+\.bar\.com", integer=302, string="www.bar.com");
              redir.add("www\.[^.]+\.baz\.com", integer=303, string="www.baz.com");
              redir.add("www\.[^.]+\.quux\.com", integer=307, string="www.quux.com");
              redir.compile();
          }

          sub vcl_recv {
              if (redir.match(req.http.Host)) {
                  # Construct a Location header that will be used in the
                  # synthetic redirect response.
                  set req.http.Location = "http://" + redir.string() + req.url;

                  # Set the response status from the associated integer.
                  return( synth(redir.integer()) );
              }
          }

          sub vcl_synth {
              if (resp.status >= 301 && resp.status <= 307) {
                  # We come here from the synth return for the redirect
                  # response. The status code was set from .integer().
                  set resp.http.Location = req.http.Location;
                  return(deliver);
              }
          }

   STRING xset.sub(STRING text, STRING rewrite, STRING fallback, INT n, ENUM select)
          STRING xset.sub(
                STRING text,
                STRING rewrite,
                STRING fallback="**SUB METHOD FAILED**",
                INT n=0,
                ENUM {FIRST, LAST, UNIQUE} select=UNIQUE
          )

       Returns  the  result  of the method call .sub(text, rewrite, fallback), as documented above for the regex
       interface, invoked on the nth pattern added to the set, or on the pattern in the set that matched in  the
       most recent call to .match() in the same task scope.

       .sub()  requires that the pattern it identifies was saved as an internal regex object, by setting save to
       true when it was added with the .add() method.

       The associated pattern is determined by n and select according to the rules given above. If  an  internal
       regex  object  was saved for that pattern, then the result of the .sub() method invoked on that object is
       returned.

       .sub() invokes VCL failkure (see ERRORS) if:

       • The values of n and select are invalid, according to the rules given above.

       • save was false in the .add() method for the pattern identified by n and select; that  is,  no  internal
         regex object was saved on which the .sub() method could have been invoked.

       • The .sub() method invoked on the regex object fails for any of the reasons described for regex.sub().

       Examples:

          # Generate synthethic redirect responses on URLs that match a set of
          # patterns, rewriting the URL according to the matched pattern.

          # In this example, we set the new URL in the redirect location to
          # the path that comes after the prefix of the original req.url.
          sub vcl_init {
              new matcher = re2.set(anchor=start);
              matcher.add("/foo/(.*)", save=true);
              matcher.add("/bar/(.*)", save=true);
              matcher.add("/baz/(.*)", save=true);
              matcher.compile();
          }

          sub vcl_recv {
              if (matcher.match(req.url)) {
                  if (matcher.nmatches() != 1) {
                      return(fail);
                  }
                  return(synth(1301));
              }
          }

          sub vcl_synth {
              if (resp.status == 1301) {
                  # matcher.sub() rewrites the URL to the subpath after the
                  # original prefix.
                  set resp.http.Location
                      = "http://www.otherdomain.org" + matcher.sub(req.url, "/\1");
                  return(deliver);
              }
          }

   STRING xset.suball(STRING text, STRING rewrite, STRING fallback, INT n, ENUM select)
          STRING xset.suball(
                STRING text,
                STRING rewrite,
                STRING fallback="**SUBALL METHOD FAILED**",
                INT n=0,
                ENUM {FIRST, LAST, UNIQUE} select=UNIQUE
          )

       Like  the  .sub()  method,  this  returns the result of calling .suball(text, rewrite, fallback) from the
       regex interface on the nth pattern added to the set, or the pattern  that  most  recently  matched  in  a
       .match() call.

       .suball() is subject to the same conditions as the .sub() method:

       • The pattern to which it is applied is identified by n and select according to the rules given above.

       • It fails if:

         • The pattern that it identifies was not saved with .add(save=true).

         • The values of n or select are invalid.

         • The .suball() method invoked on the saved regex object fails.

       Example:

          # In any URL that matches one of the words given below, replace all
          # occurrences of the matching word with "quux" (for example to
          # rewrite path components or elements of query strings).
          sub vcl_init {
              new matcher = re2.set();
              matcher.add("\bfoo\b", save=true);
              matcher.add("\bbar\b", save=true);
              matcher.add("\bbaz\b", save=true);
              matcher.compile();
          }

          sub vcl_recv {
              if (matcher.match(req.url)) {
                  if (matcher.nmatches() != 1) {
                      return(fail);
                  }
                  set req.url = matcher.suball(req.url, "quux");
              }
          }

   STRING xset.extract(STRING text, STRING rewrite, STRING fallback, INT n, ENUM select)
          STRING xset.extract(
                STRING text,
                STRING rewrite,
                STRING fallback="**EXTRACT METHOD FAILED**",
                INT n=0,
                ENUM {FIRST, LAST, UNIQUE} select=UNIQUE
          )

       Like  the .sub() and .suball() methods, this method returns the result of calling .extract(text, rewrite,
       fallback) from the regex interface on the nth pattern added to the set, or the pattern that most recently
       matched in a .match() call.

       .extract() is subject to the same conditions as the other rewrite methods:

       • The pattern to which it is applied is identified by n and select according to the rules given above.

       • It fails if:

         • The pattern that it identifies was not saved with .add(save=true).

         • The values of n or select are invalid.

         • The .extract() method invoked on the saved regex object fails.

       Example:

          # Rewrite any URL that matches one of the patterns in the set
          # by exchanging the path components.
          sub vcl_init {
              new matcher = re2.set(anchor=both);
              matcher.add("/(foo)/(bar)/", save=true);
              matcher.add("/(bar)/(baz)/", save=true);
              matcher.add("/(baz)/(quux)/", save=true);
              matcher.compile();
          }

          sub vcl_recv {
              if (matcher.match(req.url)) {
                  if (matcher.nmatches() != 1) {
                      return(fail);
                  }
                  set req.url = matcher.extract(req.url, "/\2/\1/");
              }
          }

   SUB xset.subroutine(INT n, ENUM select)
          SUB xset.subroutine(
                INT n=0,
                ENUM {FIRST, LAST, UNIQUE} select=UNIQUE
          )

       Returns the subroutine set by the sub parameter for the element of the set indicated  by  n  and  select,
       according to the rules given above. The subroutine may be invoked with VCL call.

       Note:  you must ensure that the subroutine may invoked legally in the context in which it is called. This
       means that:

       • The subroutine may only refer to VCL elements that are legal in the invocation context. For example, if
         the subroutine only refers to headers in req.http.*, then it may be called in vcl_recv, but not  if  it
         refers to any header in resp.http.*. See vcl-var(7) for the specification of which VCL variables may be
         used in which contexts.

       • Recursive  subroutine calls are not permitted in VCL. The subroutine invocation may not appear anywhere
         in its own call stack.

       For standard subroutine invocations with call, the VCL compiler checks  these  conditions  and  issues  a
       compile-time  error if either one is violated. This is not possible with invocations using .subroutine();
       the error can only be determined at runtime. So  it  is  advisable  to  test  the  use  of  .subroutine()
       carefully  before  using  it  in  production.  You  can  use  the .check_call() method described below to
       determine if the subroutine call is legal.

       .subroutine() invokes VCL failure (See ERRORS) if:

       • The rules for n and select indicate failure.

       • No subroutine was set with the sub parameter in .add().

       • The subroutine is invoked with call, but the call is not legal  in  the  invocation  context,  for  the
         reasons given above.

       Example:

          # Due to the use of resp.http.*, this subroutine may only be invoked
          # in vcl_deliver or vcl_synth, as documented in vcl-var(7). Note
          # that subroutine definitions must appear before vcl_init to
          # permitted for the sub parameter in .add().
          sub resp_sub {
              set resp.http.Call-Me = "but only in deliver or synth";
          }

          sub vcl_init {
              new myset = re2.set();
              myset.add("/foo", sub=resp_sub);
              myset.add("/foo/bar", sub=some_other_sub);
              # ...
          }

          sub vcl_deliver {
              if (myset.match(req.url)) {
                 call myset.subroutine(select=FIRST);
              }
          }

   BOOL xset.check_call(INT n, ENUM select)
          BOOL xset.check_call(
                INT n=0,
                ENUM {FIRST, LAST, UNIQUE} select=UNIQUE
          )

       Returns  true  iff the subroutine returned by .subroutine() for the element of the set indicated by n and
       select may be invoked legally in the current context. The conditions for legal invocation are  documented
       for .subroutine() above.

       .check_call()  never  invokes VCL failure, but rather returns false under conditions for which the use of
       .subroutine() would invoke VCL failure. In that case, a message is emitted to the Vanrish log  using  the
       Notice tag (the same message that would appear with the VCL_Error tag if the subroutine were called).

       Notice messages in the log produced by this VMOD are always prefixed with the string
       ``
       vmod_re2:
       ``
       .

       System Message: WARNING/2 (vmod_re2.man.rst:, line 1748)
              Inline literal start-string without end-string.

       System Message: WARNING/2 (vmod_re2.man.rst:, line 1748)
              Inline literal start-string without end-string.

              Example:

          # Assume that myset is declared as in the example above.
          sub vcl_deliver {
              if (myset.match(req.url)) {
                 if (myset.check_call(select=FIRST)) {
                    call myset.subroutine(select=FIRST);
                 }
                 else {
                    call do_if_resp_sub_is_illegal;
                 }
              }
          }

   BOOL xset.saved(ENUM which, INT n, ENUM select)
          BOOL xset.saved(
                ENUM {REGEX, STR, BE, INT, SUB} which=REGEX,
                INT n=0,
                ENUM {FIRST, LAST, UNIQUE} select=UNIQUE
          )

       Returns true if and only if an object of the type indicated by which was saved at initialization time for
       the  nth  pattern added to the set, or for the pattern indicated by select after the most recent .match()
       call.

       In other words, .saved() returns true:

       • for which=REGEX if the individual regex was saved with .add(save=true) for the indicated pattern

       • for which=STR if a string was stored with the string parameter in .add()

       • for which=BE if a backend was stored with the backend attribute.

       • for which=INT if an integer was stored with the integer attribute.

       • for which=SUB if an integer was stored with the sub attribute.

       The default value of which is REGEX.

       The pattern in the set is identified by n and select according to the rules given above. .saved() invokes
       VCL failure if the values of n or select are invalid (see ERRORS).

       Example:

          sub vcl_init {
              new s = re2.set();
              s.add("1", save=true, string="1", backend=b1);
              s.add("2", save=true, string="2");
              s.add("3", save=true, backend=b3);
              s.add("4", save=true);
              s.add("5", string="5", backend=b5);
              s.add("6", string="6");
              s.add("7", backend=b7);
              s.add("8");
              s.compile();
          }

          # Then the following holds for this set:
          # s.saved(n=1) == true        # for any value of which
          # s.saved(which=REGEX, n=2) == true
          # s.saved(which=STR, n=2)   == true
          # s.saved(which=BE, n=2)    == false
          # s.saved(which=REGEX, n=3) == true
          # s.saved(which=STR, n=3)   == false
          # s.saved(which=BE, n=3)    == true
          # s.saved(which=REGEX, n=4) == true
          # s.saved(which=STR, n=4)   == false
          # s.saved(which=BE, n=4)    == false
          # s.saved(which=REGEX, n=5) == false
          # s.saved(which=STR, n=5)   == true
          # s.saved(which=BE, n=5)    == true
          # s.saved(which=REGEX, n=6) == false
          # s.saved(which=STR, n=6)   == true
          # s.saved(which=BE, n=6)    == false
          # s.saved(which=REGEX, n=7) == false
          # s.saved(which=STR, n=7)   == false
          # s.saved(which=BE, n=7)    == true
          # s.saved(n=8) == false       # for any value of which

          if (s.match("4")) {
             # The fourth pattern has been uniquely matched.
             # So in this context: s.saved() == true
             # Since save=true was used in .add() for the 4th pattern,
             # and which=REGEX by default.
          }

   VOID xset.hdr_filter(HTTP, BOOL whitelist=1)
       Filters the headers in the HTTP object, which may be one of req, resp, bereq, or beresp. In other  words,
       filter the headers in the client or backend request or response.

       If  whitelist is true, then headers that match one of the patterns in the set are retained, and all other
       headers are removed.  Otherwise, headers that match a pattern in the set are removed, and all others  are
       retained. By default, whitelist is true.

       Example:

          sub vcl_init {
                # Header whitelist
                new white = re2.set(anchor=start);
                white.add("Foo:");
                white.add("Bar:");
                white.add("Baz: baz$");
                white.compile();

                # Header blacklist
                new black = re2.set(anchor=start);
                black.add("Chaotic:");
                black.add("Evil:");
                black.add("Wicked: wicked$");
                black.compile();
          }

          sub vcl_recv {
                # Filter the client request header with the whitelist.
                # Headers that do not match any pattern in the set are removed.
                white.hdr_filter(req);
          }

          sub vcl_deliver {
                # Filter the client response header with the blacklist.
                # Headers that match any pattern in the set are removed.
                black.hdr_filter(resp, false);
          }

   STRING quotemeta(STRING)
       Returns  a  copy  of  the  argument  string with all regex metacharacters escaped via backslash. When the
       returned string is used as a regular expression, it will exactly match the original string, regardless of
       any special characters. This function has a purpose similar to a \Q..\E sequence within a regex,  or  the
       literal=true setting in a regex constructor.

       The function invokes VCL failure if there is insufficient workspace for the return string (see ERRORS).

       Example:

          # The following are always true:
          re2.quotemeta("1.5-2.0?") == "1\.5\-2\.0\?"
          re2.match(re2.quotemeta("1.5-2.0?"), "1.5-2.0?")

   STRING version()
       Return the version string for this VMOD.

       Example:

          std.log("Using VMOD re2 version: " + re2.version());

ERRORS

       Functions  and  methods  of  the  VMOD  may  invoke VCL failure under unrecoverable error conditions. The
       effects of VCL failure depend on the VCL subroutine in which it takes place:

       • If invoked during vcl_init, then the VCL load fails, and an error message  is  returned  over  the  CLI
         (reported by varnishadm(1)).

       • If  invoked during any other subroutine besides vcl_synth, then an error message is recorded in the log
         with the VCL_Error tag, further processing is aborted immediately,  and  a  response  with  status  503
         (Service Not Available) is returned with the reason string "VCL failed".

       • If  invoked  during  vcl_synth,  then  further  processing is aborted, the error message is logged with
         VCL_Error, and the client connection is immediately closed -- the client receives no response.

       Errors that lead to VCL failure include:

       • Any regex compilation failure.

       • Out of workspace errors (see LIMITATIONS).

       • Failures reported by the RE2 library for: matches, backrefs, namedrefs, the  rewrite  operations  (sub,
         suball  and  extract),  the .cost() function or method, and the .quotemeta() function. The VMOD detects
         most common errors that would lead to library errors, and invokes VCL failure  in  such  cases  without
         calling the library. But library errors may happen under conditions such as out of memory.

       • Functions  and  methods that require a previous successful match when there was no prior match, or when
         the previous match was unsuccessful.  These include backrefs, namedrefs, and the data retrieval methods
         for set objects.

       • Any of the following parameters are undefined, for example when set from an  unset  header:  fallbacks;
         patterns  for  the regex functions (which are compiled at runtime); the text and rewrite parameters for
         rewrite operations; the name parameter for namedrefs.

       • The name parameter for namedrefs is the empty string.

       • Backref number is out of range (greater than the number of backrefs in the pattern).

       • Backref or namedref attempted when the never_capture option was set to true for the pattern.

       • For set objects:

         • Numeric index (parameter n) is out of range (greater than the number of patterns in the set).

         • Use of select=UNIQUE after more than one pattern was matched.  The .nmatches() can be used  to  check
           for this condition, to avoid VCL failure -- UNIQUE will fail in .namtches() > 1.

         • Retrieval  of data from a set (such as a string, backend etc) by numeric index (n) or "associatively"
           (after a match) when no such object was saved for the corresponding pattern.  Use  the  .saved()  and
           .check_call() methods to check for this.

         • Calling  the  subroutine  returned  by  .subrooutine()  may be illegal, if it is not permitted in the
           subroutine from which it is called, or if it would lead to recursive  calls.  Use  the  .check_call()
           method to check for this.

REQUIREMENTS

       The VMOD requires Varnish since version 6.6, or the master branch. See the source repository for versions
       of the VMOD that are compatible with other Varnish versions.

       It  requires  the  RE2  library,  and  has  been  tested  against  RE2 versions since 2015-06-01 (through
       2021-04-01 at the time of writing).

       If the VMOD is built against versions of RE2 since 2017-12-01,  it  uses  a  version  of  the  set  match
       operation  that  reports  out-of-memory  conditions  during  a match. (Versions of RE2 since June 2019 no
       longer have this error, but nevertheless the different internal call is used for set  matches.)  In  that
       case,  the  VMOD  is  not  compatible with earlier versions of RE2. This is only a problem if the runtime
       version of the library differs from the version against which the VMOD was built. If you  encounter  this
       error, consider re-building the VMOD against the runtime version of RE2, or installing a newer version of
       RE2.

INSTALLATION

       See INSTALL.rst in the source repository.

LIMITATIONS

       The  VMOD  allocates Varnish workspace for captured groups and rewritten strings. If operations fail with
       "insufficient workspace" error messages in the  Varnish  log  (with  the  VCL_Error  tag),  increase  the
       varnishd runtime parameters workspace_client and/or workspace_backend.

       The  RE2  documentation  states  that  successful  matches  are slowed quite a bit when they also capture
       substrings. There is also additional overhead from the VMOD, unless the never_capture flag  is  true,  to
       manage  data  about  captured  groups  in  the  workspace. This overhead is incurred even if there are no
       capturing expressions in a pattern, since it is always possible to call backref(0) to obtain the  matched
       portion of a string.

       So  if  you  are  using  a  pattern  only  to match against strings, and never to capture subexpressions,
       consider setting the never_capture option to true, to eliminate the extra work for both RE2 and the VMOD.

AUTHOR

       • Geoffrey Simmons <geoff@uplex.de>

       UPLEX Nils Goroll Systemoptimierung

SEE ALSO

varnishd(1)

       • vcl(7)

       • VMOD source repository: https://code.uplex.de/uplex-varnish/libvmod-re2

         • Gitlab mirror: https://gitlab.com/uplex/varnish/libvmod-re2

       • RE2 git repo: https://github.com/google/re2

       • RE2 syntax: https://github.com/google/re2/wiki/Syntax

       • "Implementing Regular Expressions": https://swtch.com/~rsc/regexp/

         • Series of articles motivating the design of RE2, with discussion of how RE2 compares with PCRE

COPYRIGHT

          Copyright (c) 2016-2018 UPLEX Nils Goroll Systemoptimierung
          All rights reserved

          Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>

          See LICENSE

                                                                                                     VMOD_RE2(3)