Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upStrip path for reverse proxied requests #3266
Comments
|
I think your suggestions 1 and 2 aren't viable for the reasons you mentioned. I think 3 and 4 are worth exploring some more. I think the naming of If using a placeholder, with your example with This would also only work if we have simple |
Yep, I agree that's a good point. Alternatively, perhaps it would be an idea to refer to
This could also potentially work with other matchers. There's probably a much nicer syntax for this but could this be a feasible idea? Edit: maybe this is a bit clunky on second thoughts... it seems the way NGINX solves this is by the presence (or lack of) a trailing slash in the upstream URL which I think is even more confusing so clearly this is not easy to resolve |
|
I haven't had time to catch up on this whole conversation yet -- I will sooner or later -- but does Edit: Oh, you just want to strip a prefix, right? So what about something like
This is similar to the idea of a (I suppose one idea to make that path argument less confusing is to require that it be suffixed with |
|
@mholt I like that idea. I'll try to implement it real quick. Should be easy. Edit: Bah. Ran into problems with import cycles, not sure how to make an |
|
@mholt @francislavoie Thanks for all the ideas and work on this! Also in answer to the previous question... yes that's right I just want to strip the prefix (the prefix being the bit before |
|
I have a working implementation in #3281 I think, please take a look! |
|
I'd like to share my own use-case for a feature like this here, as well. I have an old path
Although that |
|
This is definitely something we'll address for 2.1. Apparently nginx does not automatically strip the path it matches in a |
|
Thanks @mholt for all your ideas and time (also especially to @francislavoie for the great PR). I'd be really happy to help out with anything, particularly as I think this is an important feature. I get really confused with the NGINX way of doing this so I might get this slightly wrong but here's a shot, the relevant documentation I'm quoting is found here.
Essentially, the path that is matched in the location will be automatically stripped. For instance, for
Here's where it gets tricky... Whilst you can see the reasoning behind this, I think that to someone writing a config the addition of a trailing In summary... location blocks do not strip the matched path in general afaik. However, as a special case, NGINX always tries to strip the path when reverse proxying. However, in some cases like the one above (there are more too in the docs!) it can't work out what to strip so it leaves the whole thing. I think Caddy can definitely take inspiration from making the path really easy to strip, but hopefully in a way that is more intuitive. I assume from NGINX actually making this the default that it is the more common use case so maybe Caddy should even consider doing this too? I also really like the PR as it tries to solve this in the more general case, I left some ideas there which are more loosely inspired by NGINX. Thank you again for the response to this issue, I hope this is helpful P.S. please feel free to correct me if I've got anything wrong! |
|
Ah, emphasis on:
So, if a URI is given, then the path is reworked, otherwise it is left alone. Maybe a |
Exactly, although there are a few more cases given in the docs under which it is left alone (e.g. when the location path is a regular expression).
What would be the behaviour of this, I'm assuming it is specific to reverse proxying? Whilst different from the NGINX approach, I like the idea of addressing this in the general case as it solves cases like the one described by @codecat too. Perhaps stripping is something that could even be added to the path matcher? Alternatively, maybe capture groups could be extended to regular paths so you could write something like
although this may not be too intuitive |
I was thinking those would just always strip the prefix it matches on, then proxy. So it would still be a one-liner, as opposed to |
|
This request looks like #95 that was fixed in Caddy 1. Why not use the same solution? |
Because Caddy v2 is a complete rewrite and does not work the same way as Caddy v1. The solution doesn't apply here. We don't want the |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
That would be cool and a lot simpler than what I suggested! Do you think there is a nice way to generalise this to other directives? I think redirects are also a pretty good example but maybe there are more. |
That's what |
|
I think a decent directive naming for the proxy shortcut could be |
|
Could this perhaps be something that's added for all directives as a one-liner alternative to |
|
Not a fan. Adds too much complexity to the parsing. |
|
Fair enough |


Background
The
reverse_proxydirective does not strip the path of the request before forwarding the request upstream. For example, in the following configuration a request toexample.com/foo/barwill result in an upstream request ofupstream:80/foo/bar(rather thanupstream:80/bar).At least from my experience, I quite often want the path to not be included in the upstream request, as the upstream server is a microservice which is not aware that it is being reverse-proxied. A good example given in #2813 (where this issue originated) is using phpMyAdmin at the URL
/phpmyadmin. Theuridirective can be used to achieve this and the configuration can be changed to something like this.Issue
As this seems to be a relatively common pattern, I imagine configurations like the following will become quite commonplace.
Here there is a lot of duplication of paths, i.e.
/docsis written twice. I would like to avoid this to make the configuration more succinct and because it could very easily lead to errors being accidentally introduced. For instance, if I change/docsto be/documentationI may forget to updateuri strip_prefix /docstouri strip_prefix /documents. In a more complex config like this one you can see how there may be more subtle errors with the api/ path as there is nesting too.Ideas
I suggested a few ideas in #2813 and @francislavoie made some good points, also mentioning that in a lot of cases a subdomain may be preferred. Ideas that I have come up with are...
Change the default behaviour of
reverse_proxyto strip out the path. Then you could simply add it back in by changingreverse_proxy upstream:80toreverse_proxy upstream:80/foo. However, @francislavoie pointed out that this could be a confusing change from the current behaviour in Caddy (both v1 and v2) and may be unintuitive to users who expect the path to be preserved.Add an option to the
reverse_proxydirective to strip the path something like in the following example. However, this seems to go against the good principle that thereverse_proxydirective should not be involved in URL rewrites.{route}perhaps) which would return the current path matched by Caddy. Then it could be used like so to remove the duplication. However, I'm not entirely sure that this expresses clearly what we are trying to achieve.uridirective that allows the currently matched route to be stripped from the path like in the following. It could also take an optional argument of a maximum number of path segments to strip. However, this increases the complexity of theuridirective with more options.I'd be really interested to find out what use cases exist for this and whether there are any other ideas how to do this💡