Skip to content

Add .foreach() and .foreach_body() iterators

Nils Goroll requested to merge iterators into master

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 in resp.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/or b 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.

Merge request reports