Server subpaths

1. Caddy version (caddy version):

2.3.0

2. How I run Caddy:

caddy run

a. System environment:

macOS 11.2.1

b. Command:

caddy run

c. Service/unit/compose file:

paste full file contents here

d. My complete Caddyfile or JSON config:

localhost:2015 {
    root /pics/* /Users/ahwulf/test/images
    root /thumbs/* /Users/ahwulf/test/thumbs
    root Art
    file_server
    log {
    	output stdout
 		format console
    }
}

3. The problem I’m having:

everything in Art is served just fine
I want the path /pics/* and /thumbs/* served from an alternate directory but all references to valid files are 404

4. Error messages and/or full log output:

Documents/Blogs % 1.6152373913730931e+09 error http.log.access.log0 handled request {“request”: {“remote_addr”: “[::1]:49479”, “proto”: “HTTP/2.0”, “method”: “GET”, “host”: “localhost:2015”, “uri”: “/pics/the-colorimeter.jpg”, “headers”: {“Accept-Language”: [“en-us”], “Accept-Encoding”: [“gzip, deflate, br”], “Cookie”: [“Webstorm-18384ca5=e20553f3-cba7-4712-8176-b9007ae3dd2f”], “Accept”: [“text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8”], “User-Agent”: [“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15”]}, “tls”: {“resumed”: false, “version”: 772, “cipher_suite”: 4865, “proto”: “h2”, “proto_mutual”: true, “server_name”: “localhost”}}, “common_log”: “::1 - - [08/Mar/2021:16:03:11 -0500] “GET /pics/the-colorimeter.jpg HTTP/2.0” 404 0”, “duration”: 0.000087654, “size”: 0, “status”: 404, “resp_headers”: {“Server”: [“Caddy”]}}

5. What I already tried:

I assume I don’t understand something about how root works, or perhaps I should be doing something else. Supposedly it cascades in some fashion, maybe this is incorrect.

6. Links to relevant resources:

The way file_server works is that the request path is appended to the root, so if your request is /pics/foo.png then it gets appended to /Users/ahwulf/test/images and you end up with /Users/ahwulf/test/images/pics/foo.png, which from what you say is probably not what you want.

My recommended fix is to use handle_path blocks which have built-in prefix stripping logic which will get rid of the part of the request path that you don’t want to keep:

localhost:2015 {
	handle_path /pics* {
		root * /Users/ahwulf/test/images
	}
	handle_path /thumbs* {
		root * /Users/ahwulf/test/thumbs
	}
	handle {
		root Art
	}

	file_server
}

handle and handle_path blocks are mutually exclusive from eachother, so only the first matching one will run, but also in the case of the handle_path ones, a path rewrite will be done to remove the matched part of the path.

1 Like

Ah thanks, that wasn’t clear to me from the docs, now I see what its doing!

1 Like

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