1. Caddy version (caddy version
):
2.4.1
2. How I run Caddy:
I run caddy in a docker container proxying a django app, also in a docker container, with a Caddyfile for configs.
a. System environment:
PopOS (Ubuntu) 20.04, Docker
b. Command:
docker-compose up
c. Service/unit/compose file:
version: '3'
services:
caddy:
image: caddy:2
container_name: caddy
restart: always
networks:
default:
proxy:
ports:
- 80:80
- 443:443
- 8080:8080
env_file:
- ./envs/.env.common
- ${ENV_FILE}
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- ./caddy/data:/data
- ./caddy/config:/config
- ./app/static:/static
- ./app/media:/media
echo:
image: jcrimtitan/services:latest
container_name: echo
restart: always
expose:
- "8080"
- "443"
- "80"
volumes:
- ./app:/opt/app
env_file:
- ./envs/.env.common
- ${ENV_FILE}
networks:
proxy:
depends_on:
- caddy
command: app.wsgi
d. My complete Caddyfile or JSON config:
{
debug
}
echo.app.localhost {
reverse_proxy echo:8080 {
# Catch x-accel-redirect header for Django Sendfile and redirect
# to the /media dir (header always contains path to a /media file)
@accel header X-Accel-Redirect *
handle_response @accel {
root * /
rewrite {http.reverse_proxy.header.X-Accel-Redirect}
file_server
}
}
handle_path /static/* {
root * /static/
file_server
}
}
3. The problem I’m having:
The files being served by Django Sendfile sometimes contain spaces, which are url encoded in the request. When Caddy receives something like this: /media/211699CostSegReport05-22-21.pdf
(a path with no spaces), it rewrites the request and servers the file correctly. However, if the filepath has spaces (The filepath on the system is /media/211699 Cost Seg Report 05-22-21.pdf
) then caddy will receive this: /media/211699%2520Cost%2520Seg%2520Report%252005-22-21%252013%253A03.pdf
, and the request will fail. I would expect Caddy to rewrite the header as a usable filepath before redirecting.
4. Error messages and/or full log output:
{"level":"debug","ts":1622056649.8914535,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"echo:8080","request":{"remote_addr":"192.168.192.1:34754","proto":"HTTP/2.0","method":"GET","host":"echo.app.localhost","uri":"/attachments/retrieve/274890/","headers":{"Te":["trailers"],"X-Forwarded-For":["192.168.192.1"],"User-Agent":["Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"],"Accept-Language":["en-US,en;q=0.5"],"Dnt":["1"],"Sec-Gpc":["1"],"X-Forwarded-Proto":["https"],"Accept-Encoding":["gzip, deflate, br"],,"Upgrade-Insecure-Requests":["1"]},"tls":{"resumed":true,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"app.localhost"}},"headers":{"X-Accel-Redirect":["/media/211699%20Cost%20Seg%20Report%2005-22-21%2013%3A03.pdf"],"Content-Disposition":["inline; filename=\"211699 Cost Seg Report 05-22-21 13:03.pdf\""],"Server-Timing":["TimerPanel_utime;dur=279.3689999999991;desc=\"User CPU time\", TimerPanel_stime;dur=11.874000000000162;desc=\"System CPU time\", TimerPanel_total;dur=291.24299999999926;desc=\"Total CPU time\", TimerPanel_total_time;dur=300.1978397369385;desc=\"Elapsed time\", SQLPanel_sql_time;dur=8.519411087036133;desc=\"SQL 11 queries\", CachePanel_total_time;dur=0;desc=\"Cache 0 Calls\""],"Vary":["Cookie"],"Server":["gunicorn"],"Connection":["keep-alive"],"Content-Type":["application/pdf"],"Content-Length":["2011562"]},"status":200}
caddy | {"level":"debug","ts":1622056649.8915482,"logger":"http.handlers.reverse_proxy","msg":"handling response","handler":0}
caddy | {"level":"debug","ts":1622056649.8915887,"logger":"http.handlers.rewrite","msg":"rewrote request","request":{"remote_addr":"192.168.192.1:34754","proto":"HTTP/2.0","method":"GET","host":"echo.app.localhost","uri":"/attachments/retrieve/274890/","headers":{"Accept-Encoding":["gzip, deflate, br"],,"Upgrade-Insecure-Requests":["1"],"Dnt":["1"],"Sec-Gpc":["1"],"Te":["trailers"],"X-Forwarded-For":["192.168.192.1"],"User-Agent":["Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"],"Accept-Language":["en-US,en;q=0.5"],"X-Forwarded-Proto":["https"]},"tls":{"resumed":true,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"app.localhost"}},"method":"GET","uri":"/media/211699%2520Cost%2520Seg%2520Report%252005-22-21%252013%253A03.pdf"}
caddy | {"level":"debug","ts":1622056649.891666,"logger":"http.handlers.file_server","msg":"sanitized path join","site_root":"/","request_path":"/my_dir/211699%20Cost%20Seg%20Report%2005-22-21%2013%3A03.pdf","result":"/media/211699%20Cost%20Seg%20Report%2005-22-21%2013%3A03.pdf"}
5. What I already tried:
I tried toying with try_file and the rewrite directives
6. Links to relevant resources:
The X-Accel-Redirect header for Caddyfile was just fixed in 2.4.1