Site doesn't load without trailing slash + lots of 421 errors

I’m using Caddy (version 0.10.11) and i’m using it as a reverse proxy for various services i have on my local network. My Caddyfile is:

example.com/rutorrent {
  fastcgi / /var/run/php7.0-fpm.sock php
  log stdout
  errors stderr
  gzip
}
example.com/transmission {
  proxy / localhost:9091/trasmission/web/
  log stdout
  errors stderr
  gzip
}
example.com/ipc {
  proxy / 192.168.100.105:8080
}

Everything was working properly until a few days ago when pages started to load without css and/or images. I found this issue and indeed adding a trailing slash to the url i typed in my browser seemed to solve the issue, although being a hacky solution. But then i noticed the websites couldn’t load many of their resources and were getting lots of 421 response codes because Caddy is redirecting, for example, example.com/transmission/web/rpc/foo/bar to example.com/rpc/foo/bar. I didn’t update anything in the last few days so i can’t explain why it worked before but it isn’t working now.
I thought it was a problem with proxies, so i fired up my old rTorrent + ruTorrent setup which i remember working perfectly fine, and again the website wasn’t even loading without adding a / to https://example.com/rutorrent. Added the slash and all the scripts weren’t working.

Any ideas on what would be the culprit?

Hi @plumbe0,

This is a doozy to wrap my head around, but I’ve used Transmission in the past (I’ve been using Cloud-Torrent nowadays).

I believe that Transmission is issuing relative links, and this is a problem with how those are universally handled. Because /transmission is seen as a file beneath /, and /transmission/ is seen as its own directory, we see the following behaviour for the example relative link, ./foo/bar:

URL Result
example.com/transmission example.com/foo/bar
example.com/transmission/ example.com/transmission/foo/bar

Now, while I’m having all sorts of trouble getting RPC working on a different subfolder, I did manage to get the page and all its assets loading properly with the following Caddyfile:

test.whitestrake.net/transmission {
  redir {
    if {uri} is /transmission
    / /transmission/
  }
  proxy / transmission:9091/transmission/web/
  log stdout
  errors stdout
  gzip
}

https://test.whitestrake.net/transmission is a live website as of writing this post, so you can browse to it and check for yourself to see if it’s working as expected (as I mentioned, RPC is not working, so all you get is the actual page itself).

My final thoughts is that if I were you, I would try to put Transmission on its own subdomain and give it the root URI to save myself some headache.


P.S: Avoid using someone else’s registered domain name, such as redacted.com, when hiding your domain name in a publicly posted Caddyfile. The website http://example.com/ is reserved for this purpose, so use that instead. The entire .example TLD is also reserved in this way.

1 Like

Thank you for your help. I’ve set up the Caddyfile following your suggestion and the site indeed loads correctly. Then it couldn’t reach the /rpc endpoint. I later thought i could use the subdomain suggestion and set up my Caddyfile like so:

transmission.example.com {
  basicauth / user pass
  proxy / localhost:9091/transmission/web/ {
    transparent
  }
  log stdout
  errors stderr
  gzip
}

ipc.example.com {
proxy / 192.168.100.106:8080
}

POST requests to /rpc still fails with a 405 error. I feel the transparent isn’t that transparent after all… Any ideas?

I expect that transparent is not particularly necessary. All it does is set some headers - the upstream service needs to know to look for them, otherwise they won’t have any effect.

The web interface and the RPC interface are on different endpoints. You’re proxying all requests on the domain to /transmission/web/, including RPC calls, and the web interface doesn’t handle RPC, hence 405s (method not allowed) when the browser POSTs to it.

Got it working setting the proxy like this:

transmission.example.com {
  basicauth / user pass
  proxy / localhost:9091/transmission/web/ {
    transparent
  }
  log stdout
  errors stderr
  gzip
}

Then one has to remember to visit transmission.example.com/transmission/web/ and not just transmission.example.com.

1 Like

Maybe you could throw this in for people who visit the root of the site by accident? Normal requests will be unaffected:

redir {
  if {path} is /
  / /transmission/web/
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.