greggman
(Greggman)
August 27, 2017, 12:10pm
1
Caddy is doing a great job of making me feel udderly incompetent
How can I redirect based on the path. My goal is this
http?://<notpear.test.com><port>/pear/??? -> http?://pear.test.com:<port>/pear/???
http?://<notapple.test.com><port>/apple/??? -> http?://apple.test.com:<port>/apple/???
In other words if you try to access the pear
folder and you’re not coming from the pear
domain then redir to the pear
domain. Similarly for apple
folder and domain
http://test.com/pear/ -> http://pear.test.com/pear/
http://test.com/pear/foo -> http://pear.test.com/pear/foo
http://test.com/apple/foo -> http://apple.test.com/apple
http://apple.test.com/pear/foo -> http://pear.test.com/pear/foo
First off I can’t get the simplest check to work
redir 301 {
if {hostonly} not_starts_with pear
pear/ {scheme}://pear.test.com{uri}
}
Seems to have no effect. I guess I don’t really understand how it redir works
Under apache in the /pear
folder I have this in a .htaccess
RewriteCond %{HTTP_HOST} !^pear\.test\.com$ [NC]
RewriteRule ^(.*)$ https://pear.test.com/pear/$1 [L,R=permanent]
Basically if you made it to the pear folder but you’re not coming from the pear domain then redirect to the pear domain. I have a similar .htaccess
.
Is that possible in caddy? I see redir says only exact matches work so maybe that’s why I’m stuck? I saw something somewhere else about paths that don’t start with /
matching everything that starts with the path but maybe redir doesn’t support that?
Caddy’s config works on the basis of labels. Any directives you put under a label apply for that label.
So for any site you want to be redirecting away from if they try to request /pear
, you need to add your redirect.
It would look like this:
test.com {
...
redir /pear https://pear.test.com:<port>/pear{uri}
}
apple.test.com {
...
redir /pear https://pear.test.com:<port>/pear{uri}
}
#etc...
Alternately if your sites are all under one label:
test.com, apple.test.com {
...
redir {
if {host} not_starts_with pear
/pear https://pear.test.com:<port>/pear{uri}
}
}
greggman
(Greggman)
August 27, 2017, 2:13pm
3
So I tried this
http://test.com:8080 {
root public_html
redir pear http://pears.test.com:8080{uri} 301
redir apple http://apple.test.com:8080{uri} 301
}
http://apple.test.com:8080 {
root public_html
redir pear http://pears.test.com:8080{uri} 301
}
http://pears.test.com:8080 {
root public_html
redir apple http://apple.test.com:8080{uri} 301
}
and this
http://test.com:8080 {
root public_html
redir pear/ http://pears.test.com:8080{uri} 301
redir apple/ http://apple.test.com:8080{uri} 301
}
http://apple.test.com:8080 {
root public_html
redir pear/ http://pears.test.com:8080{uri} 301
}
http://pears.test.com:8080 {
root public_html
redir apple/ http://apple.test.com:8080{uri} 301
}
and this
http://test.com:8080 {
root public_html
redir /pear/ http://pears.test.com:8080{uri} 301
redir /apple/ http://apple.test.com:8080{uri} 301
}
http://apple.test.com:8080 {
root public_html
redir /pear/ http://pears.test.com:8080{uri} 301
}
http://pears.test.com:8080 {
root public_html
redir /apple/ http://apple.test.com:8080{uri} 301
}
and this
http://test.com:8080 {
root public_html
redir /pear http://pears.test.com:8080{uri} 301
redir /apple http://apple.test.com:8080{uri} 301
}
http://apple.test.com:8080 {
root public_html
redir /pear http://pears.test.com:8080{uri} 301
}
http://pears.test.com:8080 {
root public_html
redir /apple http://apple.test.com:8080{uri} 301
}
And none of them really work. To make it clear the different between the 4 are
/path
/path/
path
path/
None of them redirect all paths, they only redirect the exact path which means only the first 2 work but for 2 absolute urls.
Is there anyway to redirect for all paths under a folder?
matt
(Matt Holt)
August 27, 2017, 2:29pm
4
That indicates you’re probably missing a closing brace, or your Caddyfile is malformed. I’m guessing test.com is actually a site address. What’s your full Caddyfile?
greggman
(Greggman)
August 27, 2017, 2:32pm
5
Sorry, was in the process of updating my response after deleting it but discourse has no way to edit and undelete in one action. Instead undelete being a separate action means the message I was trying to hide is visible while I’m fixing it
from is always an exact match, except when it is /
(a catch-all).
The path will always start with a leading slash, so you can eliminate any version that doesn’t have one.
That leaves you with /pear
and /pear/
, which are both valid, and a client may request either. Your options for handling both are:
redir /pear [desination]
redir /pear/ [destination]
or:
redir {
if {path} starts_with /pear
/ [destination]
}
The latter option becomes more attractive if you have a large section of possible locations that can be grouped under one basepath, but with only two (trailing slash vs. no trailing slash), they’re equally verbose, and while I personally lean towards the former as a matter of readability / principle, it’s entirely up to you.
greggman
(Greggman)
August 28, 2017, 12:45am
7
Thank you for the example, I’m getting closer to understanding.
Still back to my initial goal which is anything under /pear
goes to pear.test.com
and anything under /apple
goes to apple.test.com
I tried this
http://pear.test.com:8080 {
redir {
if {path} starts_with /apple/
/ http://apple.test.com:8080{uri} 301
}
}
http://apple.test.com:8080 {
redir {
if {path} starts_with /pear/
/ http://pear.test.com:8080{uri} 301
}
}
http://test.com:8080 {
redir {
if {path} starts_with /apple/
/ http://apple.test.com:8080{uri} 301
}
redir {
if {path} starts_with /pear/
/ http://pear.test.com:8080{uri} 301
}
}
The first 2 sections work but the last one gets
Caddyfile:22 - Parse error: rule with duplicate 'from' value: / -> http://apple.test.com:8080{uri}
Is there a way to handle that case?
Oh, that.
There is a way to handle that, but it’s not pretty. I understand the devs are working on a solution for this particular check.
It involves a lot of rewrites, which won’t run into the same check.
http://pear.test.com:8080 {
rewrite {
if {path} starts_with /apple
to /redir-pear-to-apple/
}
redir /redir-pear-to-apple/ http://apple.test.com:8080{uri}
}
http://apple.test.com:8080 {
rewrite {
if {path} starts_with /pear
to /redir-apple-to-pear/
}
redir /redir-apple-to-pear/ http://pear.test.com:8080{uri}
}
http://test.com:8080 {
rewrite {
if {path} starts_with /apple
to /redir-test-to-apple/
}
redir /redir-test-to-apple/ http://apple.test.com:8080{uri}
rewrite {
if {path} starts_with /pear
to /redir-test-to-pear/
}
redir /redir-test-to-pear/ http://pear.test.com:8080{uri}
}
P.S: Don’t check starts_with /apple/
, it will not catch requests for /apple
- checking starts_with /apple
will catch both.
1 Like
matt
(Matt Holt)
August 28, 2017, 2:39am
9
(Yes, I’m pushing for a change by the next release that will disable the duplication check for redir rules containing an if
statement. That should resolve the issue. And I have encountered this problem too so it’s bugging me as well.)
3 Likes
system
(system)
Closed
November 26, 2017, 6:08am
11
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.