I’m inclined to think this issue lies with the upstream server.
I’ve tried to demonstrate Caddy’s behaviour here with a simple Caddyfile:
~/Projects/test
➜ caddy version
v2.1.1 h1:X9k1+ehZPYYrSqBvf/ocUgdLSRIuiNiMo7CvyGUQKeA=
~/Projects/test
➜ cat Caddyfile
http://:8081 {
log
respond "{uri}" 200
}
http://dashboard.example.com:8080 {
rewrite * /dashboard{uri}
reverse_proxy localhost:8081
}
http://api.example.com:8080 {
rewrite * /api{uri}
reverse_proxy localhost:8081
}
So we’re only getting 200 responses with a body containing the requested URI. Otherwise we’re replicating identical behaviour to your other sites. A good request is one where the URI is prefixed with the subdomain of the requested site. Giving it a quick shot:
~/Projects/test
➜ curl http://api.example.com:8080/stuff --resolve api.example.com:8080:127.0.0.1
/api/stuff⏎
2020/07/29 16:39:14.644 INFO http.log.access handled request {"request": {"method": "GET", "uri": "/api/stuff", "proto": "HTTP/1.1", "remote_addr": "[::1]:53165", "host": "api.example.com:8080", "headers": {"User-Agent": ["curl/7.64.1"], "Accept": ["*/*"], "X-Forwarded-For": ["127.0.0.1"], "X-Forwarded-Proto": ["http"], "Accept-Encoding": ["gzip"]}}, "common_log": "::1 - - [30/Jul/2020:02:39:14 +1000] \"GET /api/stuff HTTP/1.1\" 200 10", "duration": 0.000052311, "size": 10, "status": 200, "resp_headers": {"Server": ["Caddy"], "Content-Type": []}}
~/Projects/test
➜ curl http://dashboard.example.com:8080/stuff --resolve dashboard.example.com:8080:127.0.0.1
/dashboard/stuff⏎
2020/07/29 16:39:18.317 INFO http.log.access handled request {"request": {"method": "GET", "uri": "/dashboard/stuff", "proto": "HTTP/1.1", "remote_addr": "[::1]:53167", "host": "dashboard.example.com:8080", "headers": {"X-Forwarded-For": ["127.0.0.1"], "X-Forwarded-Proto": ["http"], "Accept-Encoding": ["gzip"], "User-Agent": ["curl/7.64.1"], "Accept": ["*/*"]}}, "common_log": "::1 - - [30/Jul/2020:02:39:18 +1000] \"GET /dashboard/stuff HTTP/1.1\" 200 16", "duration": 0.000037235, "size": 16, "status": 200, "resp_headers": {"Content-Type": [], "Server": ["Caddy"]}}
Everything is checking out, in terms of server behaviour. How the upstream is discriminating between the two is unclear to me. A client requesting /dashboard/foo
to a site with no rewriting should result in an identical path to a client requesting /foo
to a site that appends /dashboard
, as shown above.