Rewriting of changing URL paths

1. The problem I’m having:

I’m trying to figure out how to use file_server with the browse option to rewrite some URLs when the path is changed.

The existing URL structure is as follows:

/xplane/charts/DAPS-2024-MAR-21/(.*)
/xplane/charts/ERSA-2024-MAR-21/(.*)

When the revision of these documents changes, the filename will stay the same, but the path will change - ie to something like DAPS-2024-JUN-01 etc.

In Apache, I’ve done this via mod_rewrite with:

## Redirect old ERSA / DAPS to new ones...
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^/xplane/charts/ERSA.+/(.*)$ /xplane/charts/ERSA-2024-MAR-21/$1 [R,L]

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^/xplane/charts/DAPS.+/(.*)$ /xplane/charts/DAPS-2024-MAR-21/$1 [R,L]

Ideally, I’d love to have Caddy discover what path the file exists at automatically, but I can set this manually like the apache config if required.

3. Caddy version:

Docker Hub caddy:latest - which as of this moment is:
v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

My Caddyfile:

So far, the parts related to this, I just have:

        file_server /xplane/charts/* {
                browse
        }

This allows me to browse the directories I need, but obviously, no rewriting happening yet.

You need a path_regexp matcher paired with the rewrite directive.

@ersa path_regexp ^/xplane/charts/ERSA.+/(.*)$
rewrite @ersa /xplane/charts/ERSA-2024-MAR-21/{re.1}

@daps path_regexp ^/xplane/charts/DAPS.+/(.*)$
rewrite @daps /xplane/charts/DAPS-2024-MAR-21/{re.1}
1 Like

Thanks for the reply - I did try this, but it doesn’t redirect to the new files - it just makes the new file available at the old location.

I did try:

@ersa path_regexp ^/xplane/charts/ERSA.+/(.*)$
redir @ersa /xplane/charts/ERSA-2024-MAR-21/{re.1}

@daps path_regexp ^/xplane/charts/DAPS.+/(.*)$
redir @daps /xplane/charts/DAPS-2024-MAR-21/{re.1}

However this also does a redirect for the files that exist - therefore causing a redirect loop.

The apache config emits a 301 redirect to the new file.

Given we could in theory test for the actual file to exist or not (the !-f in the apache rule) and only issue a redir if the file doesn’t exist.

I haven’t managed to figure out how to meet these conditions though - essentially it would be a combination of path_regexp and either files or try_files maybe?

I just can’t seem to figure out a syntax that works.

EDIT: I did get the following to be almost there, but I can’t browse the directory listings anymore…

@ersa {
        path_regexp ^/xplane/charts/ERSA.+/(.*)$
        not file
}
redir @ersa /xplane/charts/ERSA-2024-MAR-21/{re.1}

@daps {
        path_regexp ^/xplane/charts/DAPS.+/(.*)$
        not file
}
redir @daps /xplane/charts/DAPS-2024-MAR-21/{re.1}

ie if a directory was browsed like: /xplane/charts/DAPS-2023-JAN-01/ is visited, it should also be rewritten to /xplane/charts/DAPS-2024-MAR-21/

Ok, after quite a while of trial and error, I think I’ve got a properly working config for this…

handle /xplane/charts/* {
        vars {
                cycle "2024-MAR-21"
        }
        @daps {
                not file
                not path /xplane/charts/DAPS-{vars.cycle}/
                path_regexp ^/xplane/charts/DAPS.+/(.*)$
        }
        @ersa {
                not file
                not path /xplane/charts/ERSA-{vars.cycle}/
                path_regexp ^/xplane/charts/ERSA.+/(.*)$
        }

        redir @daps /xplane/charts/DAPS-{vars.cycle}/{re.1} permanent
        redir @ersa /xplane/charts/ERSA-{vars.cycle}/{re.1} permanent

        file_server {
                browse
        }
}

However, it doesn’t seem like the {vars.cycle} seems to match in the not path directives, which leads to a redirect loop when trying to browse the directory.

If I replace {vars.cycle} with 2024-MAR-21 in the not path lines, then it seems to work properly.

Are there limitations in the path match for using variables or is this a bug? :expressionless:

Fwiw, I think this is probably either a bug, or not implemented feature.

Logged an issue here: vars not expanded in path directives · Issue #6387 · caddyserver/caddy · GitHub