Treat internal and external routes differently

1. The problem I’m having:

I want to map human readable URLS that may include filesystem characters to valid HTML pages. So I create HTML files with path hashed/<hex encoded name>. There is a mapping file with the route -> hex encoded name called prettyurls in the root directory.

Most routes do not need to be mapped, only the ones with problematic characters.

prettyurls could contain eg

"/routine/==>" "/hashed/1a2b3c4d"
...

In the Caddyfile I have

   root * /usr/share/caddy

  map {path} {npath} {
    import /usr/share/caddy/assets/prettyurls
  }

  try_files {npath}.html {path}.html {path}

This all works.

But now I want to send a 403 response if there is a URL /hashed/1a2b3c4d from a user. The /hashed/* routines are an internal implementation detail.

So I add the following to the Caddy file

  error /hashed* 403

The problem is that the external /hashed/1a2b3c4d route is rejected (as desired) but the internal /hashed/1a2b3c4d which is generated from /routine/==> using the map directive is also rejected (not desired).

Is there a way to achieve both of these aims?

I think that somehow the mapped routes should be made internal using rewrite but its not clear to me from V2 docs how only mapped routes are made internal.

2. Error messages and/or full log output:

3. Caddy version:

v2.6.4

4. How I installed and ran Caddy:

a. System environment:

docker

b. Command:

c. Service/unit/compose file:

d. My complete Caddy config:

:80 {
	log {
		output stdout
	}

  error /hashed* 403

	root * /usr/share/caddy

  map {path} {npath} {
    import /usr/share/caddy/assets/prettyurls
  }

  try_files {npath}.html {path}.html {path}

	uri /type/* replace :: /

	# Enable the static file server.
	file_server

	handle_errors {
		@404 {
			expression {http.error.status_code} == 404
		}
		@403 {
			expression {http.error.status_code} == 403
		}
		rewrite @404 /404.html
		rewrite @403 /403.html
		file_server
	}
}

5. Links to relevant resources:

What you’d need to do is wrap the rewrite stuff in a route block to control the order the directive execute (by default they’re sorted according to Caddyfile Directives — Caddy Documentation) and put your error handler first before the try_files rewrite.

1 Like

Here’s part of the new Caddyfile that seems to work:

  root * /usr/share/caddy

  map {path} {npath} {
    import /usr/share/caddy/assets/prettyurls
  }

  route {
    error /hashed* 403
    try_files {npath}.html {path}.html {path}
  }

  file_server

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

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.