Rewrite to fastcgi
I want httpd to work like this:
- Visit http://example.com/ => use /index.php
- Visit http://example.com/foo => foo is not a file or directory => use /index.php
- Visit http://example.com/bar => bar is a file => use /bar
- Visit http://example.com/bar/baz => baz is not a file or directory => use /index.php
- Visit http://example.com/quux1 => quux1 is a directory but listings are not allowed => 403 forbidden
- Visit http://example.com/quux2 => quux2 is a directory and listings are allowed => 200 with listing
In Nginx you do that with a :
location / {
try_files $uri /index.php$is_args$args;
}
In Apache you would do that with a:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
I think this is not possible with httpd right now and I am trying to make a patch to support this. This would make a lot of PHP CMS'es, frameworks, ... work
there is diff to achieve that.
https://marc.info/?l=openbsd-tech&m=148094767011911&w=2
i never tested it.
Can't this be done now with rewrite?
hello, apologies for the necro. is this patch still the way to do this, or is it possible with the current rewrite?
hello, apologies for the necro. is this patch still the way to do this, or is it possible with the current rewrite?
I'm not sure, check it out, the documentation in OpenBSD is really complete: https://man.openbsd.org/httpd.conf#request https://man.openbsd.org/httpd.conf#EXAMPLES
Using the Symfony 5 documentation as a reference, I've come up with this:
server "example.org" {
listen on * port 80
alias www.example.org
root "/htdocs/example/public/"
directory index index.php
location found "/index.php" {
fastcgi socket "/run/php-fpm.sock"
}
location found "*.php" {
block return 403
}
location not found "*" {
request rewrite "/index.php"
}
}
I've tested it thoroughly to catch any edge cases, and it seems pretty solid.
Explanation for the location blocks:
- Only
index.php(the front controller) goes to fastcgi. - Any other PHP file is blocked
- Anything else not found, redirect to
index.php.
UPDATE: it's missing one thing:
After you deploy to production, make sure that you cannot access the index.php script (i.e. http://example.com/index.php).
That is recommended to conceal that you're running PHP.
New and improved :)
# application front controller
location found "/index.php" {
fastcgi socket "/run/php-fpm.sock"
}
# fallback to front controller if the location doesn't exist
location not found "*" {
request rewrite "/index.php"
}
# fallback to front controller if the location is an existing directory
location found "**/" {
request rewrite "/index.php"
}
# if the requested path doesn't match any of the locations above,
# httpd will just serve the resource (e.g. images, css, js, etc.)
This handles some edge cases the older one didn't, like when you try to access an existing directory (e.g. /css/) and httpd spits out an ugly 404 response page.
I just haven't yet tested it with directory auto index enabled. I'm not sure if it's possible for us to handle this nicely. A feature request for httpd to do this for us would be nice.