Reverse proxy trailing slash redirects

Hello, I’m reverse proxying an external site and it’s working fine except when I access it without a trailing slash: /forums results in a 301 redirect from the upstream server to /forums/ but _with the upstream hostname. This works fine when I did this with apache (the redirect header used the downstream/proxied hostname).

I’m running caddy via docker (caddy/caddy:alpine) on docker v19.03.5 and docker-compose v1.24.1 on macOS Catalina v10.15.2.

My Caddyfile reads:

www.29th.local {
  tls /etc/caddy/certs/29th.local.crt /etc/caddy/certs/29th.local.key

  reverse_proxy /forums* 29th.dreamhosters.com:443 {
    header_up Host 29th.dreamhosters.com
    header_up X-Real-IP {http.request.remote.host}
    header_up X-Forwarded-For {http.request.remote.host}
    header_up X-Forwarded-Port {http.request.port}
    header_up X-Forwarded-Proto {http.request.scheme}

    transport http {
      tls
    }
  }

Any suggestions for how I might get this to work?

Hmm. I think adding a redirect before it hits the proxy, so that Caddy does the redirect, might work.

redir /forums /forums/

This will do a path match for exactly /forums, and if so, redirect to /forums/.

https://caddyserver.com/docs/caddyfile/directives/redir

2 Likes

Thanks that fixed it.

1 Like

@francislavoie I’ve just noticed this is a problem for all the other routes as well. I’m reverse proxying github pages, so any links to, say, /about, get redirected by github pages’ server to xyz.github.io/about/. Somehow the redirect header is the masked hostname in nginx so it’s not a problem there. Is there, perhaps, a header that nginx passes with proxy_pass that I need to explicitly add with Caddy so that github pages’ server respects my hostname?

Hmm.

Since Caddy won’t know which pages should and shouldn’t have a trailing slash, this is a bit trickier.

An idea would be to use a regex to modify the Location header as its coming back upstream from the proxy.

See the https://caddyserver.com/docs/caddyfile/directives/reverse_proxy header_down directive, you could replace the domain.

It might look something like:

header_down Location //xyz.github.io/ //www.29th.local/

I’m not certain that exact regex will work, but you could give it a shot.

All that said, are you aware that you can set a custom domain for Github Pages? https://help.github.com/en/github/working-with-github-pages/managing-a-custom-domain-for-your-github-pages-site This might be a better approach than reverse proxying, depending on what you’re trying to do.

1 Like

Isn’t there a directive in other web servers that can rewrite the hostname in Location response headers?

FWIW, Caddy 2 can do this too. Not sure if it can via Caddyfile (actually I think it can do replacements though, too!) – can anyone spend a minute to find out? I’m preeettttty sure I baked in this capability already.

Only relevant thing in the JSON that I could see is this, unless I’m mistaken:

https://caddyserver.com/docs/json/apps/http/servers/routes/handle/reverse_proxy/headers/response/replace/search_regexp/

1 Like

Ding ding ding, that should do it, no?

Yeah but that’s the same as the header_down regex I gave, no?

1 Like

Oh, yeah :slight_smile: You are right. I missed that somehow. That should do it.