V2: Having trouble with rewrite

1. My Caddy version (caddy -version):

v2.0.0-beta9 (from github)

2. How I run Caddy:

caddy adapt --config caddyfile

a. System environment:

running on opensuse tumbleweed

b. Command:

paste command here

c. Service/unit/compose file:

paste full file contents here

d. My complete Caddyfile:

domain.com, www.domain.com

templates
encode gzip
file_server
root * /home/html
php_fastcgi unix//tmp/php.sock

rewrite / {
regexp ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$
to /index.php?vid={1}&mid={2}&document_srl={3}
}

3. The problem Iā€™m having:

I cannot adapt caddyfile.

4. Error messages and/or full log output:

adapt: parsing caddyfile tokens for ā€˜rewriteā€™: Caddyfile:9 - Error during parsing: Wrong argument count or unexpected line ending after ā€˜rewriteā€™

5. What I already tried:

FYI, original apache rewrite was:
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?vid=$1&mid=$2&document_srl=$3 [L,QSA]

converted for nginx from apache rewrite was:
rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ /index.php?vid=$1&mid=$2&document_srl=$3 last;

and I read about some forum articles but I cannot understand why Iā€™m failing to adapt my config.

I tried to rewrite it by using matcher, but thereā€™s no luck too.

6. Links to relevant resources:

Hi @nginx_x, welcome to the Caddy community.

Using a matcher should be the way to go here. The rewrite youā€™re using is v1-specific configuration and wonā€™t work in v2. Can you post the config you tried with the matcher?

Thanks for your reply.

I tried a matcher method like this:

matcher a {
path_regexp ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$
}
rewrite a to /index.php?vid={1}&mid={2}&document_srl={3}

ā€œtoā€ isnā€™t a literal ā€œtoā€, you want to replace it with the destination.

rewrite a /index.php?vid={1}&mid={2}&document_srl={3}

So I tested this configuration :

but caddy returned an error:

Can you tell me where I made a mistake?

Iā€™m actually seeing two problems here. First is the arg count issue, which Iā€™m not sure about. That should be the correct method to use rewrite. It may be a different error provoking this error message.

I hit up @francislavoie for second set of eyes on this and he pointed out a second issue, which is that to address the capture groups, you actually need different placeholders in v2:

If you are using regexp matchers, capture groups (both named and numeric) are available as well:

{http.matchers.PATH_REGEXP.PATTERN_NAME.CAPTURE_GROUP_NAME}

Replacing:

  • PATH_REGEXP with the name of the matcher that has the regular expression.
  • PATTERN_NAME with the lower-cased name you gave the pattern.
  • CAPTURE_GROUP_NAME with the name or index number of the capture group in the regular expression.

ā€”GitHub - caddyserver/caddy: Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

So {1} in the rewrite target should be {http.matchers.a.???.1}, where ??? should be a name youā€™ve given for the regex - but the documentation doesnā€™t specify a method to name a regex in a matcher. The regex name is able to be provided in JSON configuration, so you might need to change away from the Caddyfile to JSON to get it working until we sort that question out.

Perhaps @matt can provide some insight into this - both the error and the regex name?

1 Like

Okay, hereā€™s nothing I can do, for now :sob: because I donā€™t familiar with JSON things. That makes me painful!

Thanks a lot, and I will wait.

1 Like

I ninja edited it in after the initial post, but if youā€™d like, you could try learning the JSON configuration and setting it up that way. You can adapt the Caddyfile without the rewrite in it to start with, then add the rewrite configuration in JSON, which should be fully functional. Otherwise, yeah, hang ten, weā€™ll look into it.

Okay, I will figure it out, with JSON way, according to v2 Documentation posted on Github.

but Iā€™m not sure about it :0 because it looks very hard. thanks anyway!

Bit of advice - Google one of those online JSON editors, theyā€™ll keep your structure nice and neat and present it to you in a way thatā€™s easy to read.

1 Like

Oh, sorry everyone. Lemme try to help.

Fair warning: itā€™s well after midnight and I should be asleep. I havenā€™t tested this config but I have verified that it loads successfully.

This is probably what you want:

localhost

templates
encode gzip
file_server
root * /home/html
php_fastcgi unix//tmp/php.sock

matcher foo {
	path_regexp myregex ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$
}
rewrite match:foo /index.php?vid={http.matchers.path_regexp.myregex.1}&mid={http.matchers.path_regexp.myregex.2}&document_srl={http.matchers.path_regexp.myregex.3}

Yes, itā€™s undocumented that regexes can have names specified before them. My bad. Will fix that now.

Also, yes, I agree these placeholders are WAY too long, I will have to see how we can trim them down. The Caddyfile gives us the option to make ā€œshorthandā€ placeholders. It already has several: Home Ā· caddyserver/caddy Wiki Ā· GitHub - we might be able to make some that work for these cases (like {myregex.2} and just assume that itā€™s a path regex? I dunno).

Sorry it wasnā€™t clear. Keep the conversation going so I can work on improving it this week.

(Thank you for using v2 while it is still in beta!!)

1 Like

So Iā€™ve found my typo, which caused parsing error. I tried to call a matcher by just name, but I need to call it by match:name! That was a simple misunderstanding of documentation. :wink:

And your example helped me a lot. Finally, Iā€™ve just got to activate my little website, after rewriting 17 rules. This is one-time work so I donā€™t have anything to complain.

But, it would be lovely if I call rewrite target as {1} {2} just like old days.

(And I found that I cannot use matcher {} in one line, so I seperated into 3 lines like you did.)

1 Like

Glad to hear it is working for you!

Iā€™m wanting to improve this, both the documentation and the implementation. What would make matchers easier?

I would love this too, but the problem is, how does it know which regex the capture numbers are referring to? Matchers in Caddy 2 can have more than one regexā€¦

Ah yes, we like to keep things consistent and clean. :slight_smile:

After many thoughts, I think current system is sufficiently effective, at least for me.

I considered some ideas:

  1. call matcher by matcher:name, not match:name, for intuitive use
  • it is not a crucial factor, and I donā€™t think it will be effective that much.
  1. maybe caddy v2 could implement two method at the same time, like using matcher(current) and just one regexp-specific rewrite(maybe, rrewrite).
  • but would it be worth it? Idk
  1. Maybe the confusion is coming from matcherā€™s versatility and flexibility, or lack of basic example conf which Iā€™ve mentioned in Github Issue #2858
  • Some of real world examples will be a great addition to documentation, sometimes I feel the docs are presenting syntax only.
  • But I donā€™t have any more specific thoughts, maybe due to lack of caddy experience(I used caddy just for 2 week!). I need to dig into caddy a lot more if I want to propose an alternative implementation.
1 Like

Thank you for your thoughtful consideration of this, @nginx_x ā€“ really appreciate it.

I can understand the disparity between the matcher directive and using the matchers with match: instead of matcher:. I will think about it tooā€¦ but yeah, not sure if it will be that effective.

Like you, I am not sure this would be worth itā€¦

Yes, I agree! The best documentation has 4 parts:

  • Tutorials
  • How-to
  • Explanation
  • Reference

We only have an ad-hoc reference for Caddy 2, we havenā€™t written its documentation yet. :slight_smile: Will definitely get to that soon, itā€™s a requirement before we launch it.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.