Since 0.22.0 the documentation has included an example on using capture groups with rewrite targets: https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target . The example path is:
path: /something/?(.*)
The described behaviour is:
- rewrite.bar.com/something rewrites to rewrite.bar.com/
- rewrite.bar.com/something/ rewrites to rewrite.bar.com/
- rewrite.bar.com/something/new rewrites to rewrite.bar.com/new
While it will work at a glance, this config is misleading because the / is optional (thanks to the ?), so the capture group will also match characters _without_ a separating slash. For example:
- rewrite.bar.com/somethingelse rewrites to rewrite.bar.com/else
(This issue was mentioned previously in another comment: https://github.com/kubernetes/ingress-nginx/issues/3613#issuecomment-458523854)
I believe the simplest way to achieve the desired behaviour is to surround both the separator and capture group with a non-capturing group (?:):
path: /something(?:/(.*))?$
I just tested the path I suggested above and it seems non-capturing groups are not supported by the regex engine (or perhaps only the validator, I'm not sure). The only working option I'm aware of is to specify multiple paths, like so:
paths:
- path: /something
- path: /something/(.*)
Does anyone have a better suggestion?
Just using multiple capture groups seems to work:
path: /something(/(.*))?$
Of course, in the rewrite annotation $2 must be used to reference the capture group.
Not pretty, but it's a working solution.
the docs now suggest using $2 with the following capgroups
path: /something(/|$)(.*)
https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/rewrite#rewrite-target
Most helpful comment
Just using multiple capture groups seems to work:
Of course, in the rewrite annotation
$2must be used to reference the capture group.Not pretty, but it's a working solution.