.htaccess rules on Caddy

Hello, does anyone know what htaccess rules these would be in caddy?

`
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^ - [L]

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.+).php - [L,R=404]
`

Please fill out the help topic template. It’s very hard to know how to help without proper context for your question.

What version of Caddy are you running? What’s your Caddyfile config? What have you tried? What’s in your logs? What are you trying to do exactly?

By the fact I see .php in what you wrote though, I can only assume you’re looking for the php_fastcgi directive to serve a PHP app.

1 Like

I’m using caddy v2.

I have a PHP application and created my rewrite rules which work fine. However, I’m trying to block direct access to the file.

For example I have a file called organisation-list.php and the rewrite simply rewrites to domain.net/organisations

But, I want to stop people being able to access that page via domain.net/organisation-list.php (a 404 if possible).

Is this possible via caddy?

I got this working with the following:

rewrite /organisation-list.php /404.php
rewrite /organisations /organisation-list.php

That will work, but keep in mind that the server will still reply with a 200 status instead of a 404, which is probably your intent for the first one. Instead you might want error /organization-list.php 404.

Thanks, just did that.

I’m trying to rewrite my URL from domain.net/profile.php?id=&action= to domain.net/profile//

So for example, domain.net/profile.php?id=1&action=edit to domain.net/profile/1/edit but the rewrite documentation doesn’t seem to cover how to do that (or does it?)

I tried the below but I get this error: watcher unable to load latest config {“config_file”: “Caddyfile”, “error”: “adapting config using caddyfile: parsing caddyfile tokens for ‘rewrite’: Caddyfile:35 - Error during parsing: Wrong argument count or unexpected line ending after ‘rewrite’”}

rewrite {
  r ^/profile/([a-zA-Z0-9_\-]*)/([a-zA-Z0-9_\-]*)$
  to /profile.php?id={1}&action={2}
}

That’s Caddy v1 syntax.

Now, you need to use request matchers, specifically the path_regexp matcher, and use it along the rewrite handler.

Thanks, tried the below but get watcher unable to load latest config {"config_file": "Caddyfile", "error": "adapting config using caddyfile: Caddyfile:36: unrecognized directive: path_regexp"}

path_regexp profile /profile/([a-zA-Z0-9_\-]*)/([a-zA-Z0-9_\-]*)$
rewrite /profile/{1}/{2} /profile.php?id={re.profile.1}&action={re.profile.2}

I don’t know if any of this is right.

Please review the request matching docs, specifically the Syntax section. You need to use a named matcher.

@profile {
  path_regexp profile ^/profile/([-\w]+)/([-\w]+)$
}
rewrite @profile /profile.php?id={re.profile.1}&action={re.profile.2}

This worked, thanks! Can you confirm this is the correct way and best practice?

1 Like

Is there any way to have error /*.php 404 except my rewrite rules so .php files cannot be accessed directly?

Looks good. You can save a couple lines by using the single-line named matcher syntax:

@profile path_regexp profile ^/profile/([-\w]+)/([-\w]+)$
rewrite @profile /profile.php?id={re.profile.1}&action={re.profile.2}

You can use named matchers with error as well.

1 Like

Thanks, any idea why no 404 is showing even if I enter a random link? It just shows my index.php.

https:// {
    tls {
        on_demand
    }
    root * /var/www/html
    file_server
    php_fastcgi unix//run/php/php7.4-fpm.sock

handle_errors {
        @404 {
            expression {http.error.status_code} == 404
        }
        rewrite @404 /404.php
        file_server
    }
}
1 Like

That’s how php_fastcgi works – for any request that doesn’t map to a file, it’ll rewrite to index.php.

See this section in the docs for an in depth explanation of how it works:

If you need that requests to unknown files trigger a 404, then you can use the try_files option of php_fastcgi to do so. There’s an example for that at the bottom of that page in the docs.

1 Like

Alright, so in theory I could just show a 404 error for everything except my rewrites which is what I want.

https:// {
    tls {
        on_demand
    }
    root * /var/www/html
    file_server
    php_fastcgi unix//run/php/php7.4-fpm.sock

    error /*.php 404

    @profile {
        path_regexp profile ^/profile/([-\w]+)/([-\w]+)$
    }
    rewrite @profile /profile.php?id={re.profile.1}&action={re.profile.2}
}

Now if I try this, everything shows a 404 including my rewrite?

Did you see the example at the bottom of the php_fastcgi docs? I’m pretty sure that’s exactly what you’re looking for, with =404 in the try_files

When I try

php_fastcgi unix//run/php/php7.4-fpm.sock {
	try_files {path} {path}/index.php =404
}

I get 2021/12/22 00:06:10.404 ERROR watcher unable to load latest config {"config_file": "Caddyfile", "error": "adapting config using caddyfile: parsing caddyfile tokens for 'php_fastcgi': Caddyfile:31 - Error during parsing: unrecognized subdirective try_files"}

You never filled out the help topic template. What version of Caddy are you using? Please make sure you’re on the latest, v2.4.6.

I was on v2.4.5 but .6 works now.

I have the below in my config, is there any way to exclude my rewrites to the 404?

error /*.php 404

    @profile {
        path_regexp profile ^/profile/([-\w]+)/([-\w]+)$
    }
    rewrite @profile /profile.php?id={re.profile.1}&action={re.profile.2}

You can probably just remove error /*.php 404, or change the matcher to exclude /profile.php from matching.