Add .foreach() and .foreach_body() iterators
This MR adds two new methods on regex objects to iterate over all matches in a string or body by calling a VCL subroutine each match:
BOOL <obj>.foreach(STRING, SUB, [, INT limit] [, INT limit_recursion])
BOOL <obj>.foreach_body(req_body | bereq_body | resp_body, SUB,
[, INT limit] [, INT limit_recursion])
Relevant bits of examples to illustrate:
- collect all matches from
req.http.input
inresp.http.all
:
sub myregex_collect {
set resp.http.all += myregex.backref(0);
}
sub vcl_synth {
unset resp.http.all;
myregex.foreach(req.http.input, myregex_collect);
}
- collect two
a
and/orb
keys with their values from&
separated pairs in the request body:
sub vcl_init {
new pattern = re.regex("(?:^|&)(a|b)=([^&]*).*?&(a|b)=([^&]*)",
forbody=true);
}
sub collect {
set resp.http.all +=
pattern.backref(1) + "=" + pattern.backref(2) + "," +
pattern.backref(3) + "=" + pattern.backref(4) + ";";
}
sub vcl_synth {
unset resp.http.all;
if (pattern.foreach_body(req_body, collect)) {
set resp.status = 200;
}
return (deliver);
}
sub vcl_recv {
return (synth(400));
}
Note: The particular examples are super simple and the respective functionality could be achieved more efficiently by other means. The intention here is solely to provide (hopefully) easy to understand illustrations.