Welcome! Log In Create A New Profile

Advanced

Re: rewrite and map ??interfering regexps

Maxim Dounin
April 26, 2020 12:30PM
Hello!

On Sun, Apr 26, 2020 at 01:49:19PM +0100, Norman Gray wrote:

> Greetings.
>
> I'm trying to do some fairly intricate URI rewriting, and the behaviour of
> the 'rewrite' statement does not correspond to anything I can explain from
> the docs.
>
> The goal is that /A/foo/modified is rewritten to /_newroot/foo and
> /B/foo/modified to /_defaultroot/foo. I hope to achieve this with
>
> map $uri $modroot {
> default _defaultroot;
> ~^/A _newroot;
> }
>
> and
>
> location ~ /modified$ {
> rewrite ^(.+)/modified$ /$modroot/-$1-;
> }
>
> (in the real config, /_newroot is reverse-proxied to a web service, so that
> the URIs it handles end up grafted on to selected trees; the 'map' is
> intended to select/limit which URIs are passed on to this service).
>
> The complete nginx.conf is at the bottom.
>
> Looking in the error log, when I retrieve /hello/modified I find
>
> 2020/04/26 12:23:28 [notice] 63328#0: *5 "^(.+)/modified$" matches
> "/hello/modified", client: 127.0.0.1, server: localhost, request: "GET
> /hello/modified HTTP/1.1", host: "localhost"
> 2020/04/26 12:23:28 [notice] 63328#0: *5 rewritten data:
> "/_defaultroot/-/hello-", args: "", client: 127.0.0.1, server: localhost,
> request: "GET /hello/modified HTTP/1.1", host: "localhost"
>
> ...which is fine: the map defines $modroot as /_defaultroot, and the rewrite
> captures the /hello.
>
> But retrieving /A/hello/modified,
>
> 2020/04/26 13:00:51 [notice] 63828#0: *6 "^(.+)/modified$" matches
> "/A/hello/modified", client: 127.0.0.1, server: localhost, request: "GET
> /A/hello/modified HTTP/1.1", host: "localhost"
> 2020/04/26 13:00:51 [notice] 63828#0: *6 rewritten data: "/_newroot/--",
> args: "", client: 127.0.0.1, server: localhost, request: "GET
> /A/hello/modified HTTP/1.1", host: "localhost"
>
> I would expect this to be rewritten to /_newroot/-/A/hello-
>
> Here, the map has defined $modroot as /_newroot (which is correct). The
> 'rewrite' _has_ matched, but the $1 in that line appears to be empty. Note
> the '+' in the regexp: there is supposed be be a string of non-zero length
> in there (ie, this is ruling out that I'm inadvertently matching, and
> replacing, an empty string, as a result of being somehow confused about
> where in the string '^' is matching).
>
> It's as if the regexp match in the 'map' is somehow interfering with the
> group-capturing in the 'rewrite'.
>
> As a workaround, I can get this to work with ^(?<newprefix>/A) in the 'map',
> and using $newprefix in the 'rewrite', but that's fiddly/ugly and more
> confusing than localising the rewriting to the 'rewrite' statement.
>
> Am I misunderstanding how 'rewrite' matches things, or is there an issue
> here?

The issue is that $1..$N variables as used by the second argument
of the rewrite directive are from the last regular expression
matched. And the last regular expression is not the one from the
first argument of the rewrite directive when using a variable
from map with regular expressions. Relevant ticket is here:

https://trac.nginx.org/nginx/ticket/564

Unfortunately, there is no obvious solution. On the other hand,
this is something relatively easy to work around.

--
Maxim Dounin
http://mdounin.ru/
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Subject Author Posted

rewrite and map ??interfering regexps

Norman Gray April 26, 2020 08:50AM

Re: rewrite and map ??interfering regexps

Maxim Dounin April 26, 2020 12:30PM

Re: rewrite and map ??interfering regexps

Norman Gray April 26, 2020 03:04PM

Re: rewrite and map ??interfering regexps

J.R. April 26, 2020 04:30PM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 234
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready