Reverse proxy rewrite of X-Accel-Redirct for static files doesn't decode url for use as a file path

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

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