Expectation: List of contents under the root of the file_server
Actual result: Empty response:
> curl -v 'http://localhost:2015/doc'
* Trying 127.0.0.1:2015...
* Connected to localhost (127.0.0.1) port 2015 (#0)
> GET /doc HTTP/1.1
> Host: localhost:2015
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: Caddy
< Date: Sat, 22 Jan 2022 16:36:33 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
4. Error messages and/or full log output:
> caddy run
2022/01/22 16:36:05.597 INFO using adjacent Caddyfile
2022/01/22 16:36:05.600 INFO admin admin endpoint started {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2022/01/22 16:36:05.600 INFO http server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server {"server_name": "srv0", "http_port": 2015}
2022/01/22 16:36:05.600 INFO tls.cache.maintenance started background certificate maintenance {"cache": "0xc000480000"}
2022/01/22 16:36:05.600 INFO tls cleaning storage unit {"description": "FileStorage:/home/TheDcoder/.local/share/caddy"}
2022/01/22 16:36:05.601 INFO tls finished cleaning storage units
2022/01/22 16:36:05.601 INFO autosaved config (load with --resume flag) {"file": "/home/TheDcoder/.local/share/caddy/autosave.json"}
2022/01/22 16:36:05.601 INFO serving initial configuration
5. What I already tried:
Reading lots of documentation but I couldn’t figure out the issue. I am sure I am missing something very obvious…
Your path matcher /doc/* does not match the request /doc because it’s missing the trailing slash. You can change it to /doc* so that it matches.
You’ve only configured Caddy to handle requests to that path, so anything else will return an empty response – Caddy worked as it was configured, i.e. to do nothing.
Also, keep in mind that the file server works by taking the defined root and appending the request path to it. So for a request like /doc/index.html, your root of /usr/share/doc will get joined with the path and Caddy will look for the file at /usr/share/doc/doc/index.html. To fix this, you can use the handle_path directive which will strip the given path prefix before running the handlers within.
(I used handle instead of handle_path as the latter doesn’t support named matchers)
I tested that the path is being matched correctly with a response handler, but the file_server still doesn’t seem to be working, not sure what’s wrong this time, I get the same empty response
P.S The reason why I have a complex configuration is because I am testing several scenarios and this is the minimal configuration I could make which reproduces the issue I am encountering. For example I will be using different site handlers so I can’t simply use a global file_server.
Your branch fixed the issue with directory listing
Addendum: Out of curiosity I tested the same configuration on my ARMv7 Pi with the caddy package from Arch Linux ARM repository and it works out of the box, so the issue might be something related to how it’s being built by certain distributors.
Now I just need to figure out why the paths are relative to the site root (localhost:2015/foo) instead of the /doc handle (localhost:2015/doc/foo)… perhaps uri strip_prefix shouldn’t be used here?
How do I serve a file_server with an arbitrary root on a certain handler/path?
So, we found in a github issue that the problem had just already been fixed on the master branch, a fix that hasn’t been in a release yet.
I think you’re running into this bug:
Essentially, you need to make sure that requests to /doc get redirected to /doc/ for it to work. Using uri strip_prefix is currently preventing that from happening. So you’ll need to add another line to your config:
Unrelated to this topic, but I think this bug is not limited to file_server, I experience the same issue with php_fastcgi where it indirectly redirects to index.php on the upper path when the last / isn’t supplied in the URL, redir does fix the issue.