Right now rules in requestctl can only support AND and OR as logical connectors. I would like to add AND NOT and OR NOT, so the ability to negate a predicate.
Adding NOT presents some challenges, let me make an example:
pattern@ua/requests AND NOT ipblock@cloud/aws
the best translation of this to VCL would be to do
req.http.User-Agent ~ "requests" && req.http.X-Public-Cloud !~ "aws"
As can be seen, the negation is moved to the next comparison.
now let's take instead a case where the negation is followed by a parenthesis:
pattern@ua/requests AND NOT (pattern@sites/enwiki OR pattern@sites/wikidata)
The VCL in this case should be something like
req.http.User-Agent ~ "requests" && ! (req.http.Host ~ "en.wikipedia.org" || req.http.Host ~ "www.wikidata.org")
We could generalize the approach and just translate NOT to ! and then:
- If the next token is a parens, do nothing
- If the next token is not a parens, surround it with parentheses.
I do think we should only do this once we've moved to translating our DSL to VCL inside requestctl, as this complication would make a template be absolutely completely unreadable.