I am trying to figure out how to take a service on the backend that requires /api/index.php?some=query and make that work on the front end at /index.php?some=query. I can’t find anywhere in Google or the docs how to do this - or at least don’t know what to search for.
4. Error messages and/or full log output:
INFO using adjacent Caddyfile
Error: adapting config using caddyfile: parsing caddyfile tokens for 'rewrite': Caddyfile:56 - Error during parsing: Wrong argument count or unexpected line ending after '^/api/([^/]*)$'
This gives me no output but at least I am not getting the default Apache page (404) from the upstream. When I explicitly enter https://test1.camdenacres.stream/index.php I get a download dialog and a zero byte file.
Thank you… that moves the ball forward a tad. The site loads index.php from /. Now the issue is the upstream wants to call /api from the index.php so the upstream calls are failing with /api/api/index.php?some=thing as /api is duplicated. Is there any intelligence on the Caddy side to only add /api in the upstream request when /api is missing?
The expanded php_fastcgi route example seems like a hint, but everything references PHP having file locally vs upstream - and the upstream Apache is dping that sort of work already.
Are you sure you want to use reverse_proxy here? If it’s a PHP app you’re proxing to, why not run php-fpm and use Caddy’s php_fastcgi? Then you could add /api to the webroot and it should do what you expect.
That said, you can use a path matcher with the not matcher to only rewrite when the path doesn’t match:
I understand XY problems. reverse_proxy is the hammer I have so to speak. I thought this would be simple enough, but seemingly not. The app expects the route /api and sends everything through index.php. So for what that is worth.
The root option of php_fastcgi controls the filesystem path being passed to the php-fpm service.
If you don’t actually have an api directory in the root of your filesystem, then that will of course not work. Where are your PHP files actually stored on your system?
You don’t need to specify split and index, those are already the defaults.
Also, you should use the rootdirective instead of the root option of php_fastcgi so that file_server knows the location to find static files to serve, and to avoid repeating the root in php_fastcgi. The root option of php_fastcgi is useful though if your php-fpm service has a different view of the filesystem than Caddy (i.e. is running in a container where the PHP source files are in a different path than what Caddy has access to).
The PHP files and the entire app all live on an upstream Apache server. This is where my brain hurts and I thought I could get away with a simple reverse_proxy. The Apache server has all the directives to deal with static files vs routes back to the index. Caddy is a server in front of all of that acting as a gateway where we land TLS. So truly the only job I need Caddy to do is TLS and to make /api appear at / for clients - though as we see that’s no that easy with how PHP works.
I should add I tried
@notApi not path /api*
rewrite @notApi /api{uri}
This seems close… however the upstream is still seeing / rather than /api on all subsequent requests. That is, on the first request index.php loads from /api (and looks like / to the browser). Then a POST is sent and arrives at the upstream correctly as /api/index.php. Then the next GET to /index.php?some=thing shows to the upstream as /index.php?some=thing instead of /api/index.php?some=thing and thus 404s.
Fair enough. If you’re doing a lot of legacy rewrites and such, it can be hard to clean up.
Hmm, that shouldn’t happen. What’s in your logs? What’s your whole config at this point? Turn on the debug global option to increase the amount of details in the logs and show us what happens on that subsequent request. I don’t understand why the rewrite wouldn’t happen.
I am back to this. It seems I missed a very important detail embarrassingly enough.
Using this:
@notApi not path /api*
rewrite @notApi /api{uri}
This is what I get in Apache.
192.168.30.14 - - [16/Jan/2023:11:07:08 -0500] "GET /api/ HTTP/1.1" 200 1987 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:108.0) Gecko/20100101 Firefox/108.0"
192.168.30.14 - - [16/Jan/2023:11:07:27 -0500] "POST /api/index.php HTTP/1.1" 302 576 "https://api.internal.dev/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:108.0) Gecko/20100101 Firefox/108.0"
192.168.30.14 - - [16/Jan/2023:11:07:27 -0500] "GET /api.php?action=getall.view HTTP/1.1" 404 444 "https://api.internal.dev/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:108.0) Gecko/20100101 Firefox/108.0"
The actual backend index is api.php and the POST to authenticate is going to index.php. So I am not sure what to do about that. Why would the POST go to an index that doesn’t exist?
Again, what’s your entire config at this point? Did you turn on the debug global option? What’s in your Caddy logs after doing that and making some requests?
We need a better picture of your setup to move forwards.
I convinced the upstream admins to create a new internally accessible vhost that puts the API at the root of the site so a vanilla reverse_proxy would work.