Well, what I’m trying to do is prevent users from accessing profile.php directly (or any files that way). For example, they can access domain.net/profile/1/edit but not domain.net/profile.php
Okay, then you’ll probably need to wrap the error
and rewrite
in a route
to make sure they run in that order – by default, directives are sorted according to this directive order: Caddyfile Directives — Caddy Documentation
route {
error /*.php 404
@profile path_regexp profile ^/profile/([-\w]+)/([-\w]+)$
rewrite @profile /profile.php?id={re.profile.1}&action={re.profile.2}
}
But honestly, the way you’re doing it is not great, all modern PHP frameworks use index.php
as the entrypoint, and put the webroot one directory deeper to isolate it from the rest of the actual scripts for your app. Then you can use a PHP router (there’s plenty of implementations, take a look at FastRoute for example) which would parse the path and trigger the right handler.
This approach is a security best-practice, because it’s essentially “deny everything by default, but only allow the routes I define”, whereas the way you have it, it’s the other way around, everything is allowed except for the rewrites you wrote in Caddy. It’s risky and error-prone. Some crafty individuals are more likely find ways to get past the rules you write.
That works perfectly, you my friend are a legend. Thanks so much.
I’ll take a look at FastRoute.
Just one more question, am I missing something to get the 404 to be a php file? Currently only 404.html works, not a 404.php
handle_errors {
@404 {
expression {http.error.status_code} == 404
}
rewrite @404 /404.php
file_server
}
Yeah, you’d need to use php_fastcgi
again in the error handler.
Hmm, yeah I tried that but if I do that I just get a default 404 page and not the 404.php.
handle_errors {
@404 {
expression {http.error.status_code} == 404
}
rewrite @404 /404.php
file_server
php_fastcgi unix//run/php/php7.4-fpm.sock
}
Either way, you’re probably better off implementing a router in your PHP app, then your router can make the decision to output the 404 contents if none of the routes match.
I’ve implemented PHP Router and it works exactly how I need it to. Thanks for your suggestion. Can finally move all my code to Caddy servers
One last thing, any change you know what the Caddyfile would be for this .htaccess:
RewriteEngine On
# Remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{REQUEST_URI} !(\.png|\.jpg|\.gif|\.jpeg|\.zip|\.css|\.svg|\.js)$
RewriteCond %{REQUEST_URI} !^/app/ajax/
RewriteRule (.*) app/routes.php [QSA,L]
Want to remove the trailing slash but most importantly, forward all traffic to use routes.php except the ajax folder and those file extensions.
@excludes {
not path /app/ajax /assets/*
}
rewrite @excludes /app/routes.php
Tried this so far (not sure about trailing slash yet).
EDIT
Resolved by using
php_fastcgi unix//run/php/php7.4-fpm.sock {
index /app/routes.php
}
Not sure how to remove the trailing slash though.
Trailing slashes are common enough that they’re in our docs:
I’m trying to do this for all URLs, what am I doing wrong here?
redir {path}{uri}/ {path}{uri}
redir /{path}/ /{path}
redir /{URI}/ /{URI}
This topic was automatically closed after 30 days. New replies are no longer allowed.