I expected ABC and 99 as I did not reference anything like with ${1}. I assumed that without references also regexp lines let the mapping act like “found something, now simply set the desired value to the destination/placeholder”.
Do I misunderstand the directive? Changing the regexp to something more specific is not my point of confusion here, just why it acts more like search/replace.
Please provide a complete example to reproduce what you’re seeing.
And next time, please fill out the help topic template. Your post is lacking critical information that we need to make sure we’re on the same page, such as the Caddy version, how you’re running Caddy, etc.
So basically, we’re using the Regexp.ReplaceAllString function to perform the replacements, and apparently the way it works is that if the match doesn’t completely cover the input string, then it appends the remainder of the input to the output.
By fully consuming the rest of the input with .*, then it has the desired result.
Yeah, you can use (?i) at the start of your regexp string to enable case insensitive mode. For example, ~(?i)(/xyz).* will match /xyz and /XYZ
thanks for giving it a try. So I guess I have to rethink what I try to accomplish (more on that below).
I thought I can use the map to set variables when the regexp fires and use the result in a boolean way in other directives e.g. to trigger errors or handle rewrites. Like in the nginx map.
Yeah, you can use (?i) at the start of your regexp string to enable case insensitive mode. For example, ~(?i)(/xyz).* will match /xyz and /XYZ
Perfect! It would be great if the docs could always have a small hint like “… to enable case insensitive mod place a (?i) at the start of your regular expression” wherever regexes are available or mentioned. There are not so much flavours out there but it would certainly help to know how to accomplish it. What do you think?
So I found this post on market visibility and also this older one about wep app integration. Using the mentioned 6G/7G firewall myself with both Apache and nginx projects I thought about doing the conversion of it for Caddy. While some are trivial to migrate like HTTP verbs blocking others look more difficult. For example I wanted to use the map directive to inspect the {query} variable.
I took me 'bout two hours to find out that I did not map the result to a simple value like 1 but something like 1=longqueryfoundbyregexp. The handle_errors etc. I wrote then never fired.
I’m not sure if it makes sense to rewrite the regexes of the 7G firewall just to work around the ReplaceAllString way. It might result unwanted side effects. Maybe I ask the author up front if he has a test suite to mitigate this.
I am a bit surprised by that result too. Why are we putting the value of {host} into {my_placeholder}? That seems like a bug, isn’t it Francis? (I know I wrote the code, but what was I thinking? Tell me, Francis. )
Maybe, but I’d rather just link to the re2 syntax.
Anyway, maybe we need to not use ReplaceAllString…
I just finished a little bash script that can sed-transform the 7G rules file for Nginx (that already uses a map similar to Caddy). Only two of the regexp patterns throw an error so far which is interesting to watch in regex101.com because those lines might be incorrect anyway.
Running something like curl -I "https://localhost/?path=../../../etc/passwd"currently results in (I prepared a header output) 7g-query: path=../../../15 where 15 should be/could be the final result.
Thank you! I built the latest caddy with your patch. The initial tests look good, but I have one result where the destination variable is concatenated multiple times with the value. (e.g. expected value “3”, got “333333” such as if 6 matches would result in such a concatenation). This could definitely be a bug on my test setup. I will dive into that soon when I have more time.
When i look at the patch I assume the current implementation is “For each match of the regex in the content … Apply the captured submatches to the template and append the output to the result” (to quote the docs).
Hah, and I also noticed a silly conceptual bug in my example file: “do not use the same destination variable in multiple maps in combination with default values”: in one map a matched pattern sets the variable to 1 while in a following map the same variable is (re-)set to the given default 0 because no pattern matched