I want to associate user Ids to a specific application Id like:
<user_id> <app_id>
615 1
616 7
617 3
618 3
My URIs looks like:
/<app_id>/<user_id>/...
Now, I want to be able to easily change the application without impacting the user bookmarks. In my example, I want both
/1/615/index.html or /3/615/index.html
to be served as
/1/615/index.html
With the following rule, I get infinite loop:
RewriteMap map dbm:user-application.map
RewriteRule ^/([0-9]+)/([0-9]+)/(.*)$ /${map:$2}/$2/$3 [R,L]
...
#other proxy code to forward request to applications
I understand that after the redirection, Apache will always execute the same rule. I then tried to add a rewrite condition to block the loop, like
RewriteMap map dbm:user-application.map
RewriteCond %{REQUEST_URI} !^/${map:$2}
RewriteRule ^/([0-9]+)/([0-9]+)/(.*)$ /${map:$2}/$2/$3 [R,L]
If I read correctly my rewrite logs, I can see that the variable !^/${map:$2} is not replaced in the condition pattern, but checked "as it". And then the condition is always true, and I still get my infinite loop.
Any idea to block the loop as soon as the application id match my map?
/3/615/index.html is correctly redirecting to /1/615/index.html
The problem is that you are redirecting /1/615/index.html to /1/615/index.html as well - you want to detect the case in which the map transform is a no-op and not redirect at all in that case.
If you don't care about the user-facing URL, just change the [R,L] to [L] (removing the R) and you should be fine since it won't trigger a new round-trip from the client.
You're right that the $2 backreference won't work in a RewriteCond expression; this is because the RewriteRule hasn't yet been evaluated. You might be able to use %n - style backreferences to a regex in a previous RewriteCond...
RewriteCond {%REQUEST_URI} ^/([0-9]+)/
RewriteCond {%REQUEST_URI} !^/${map:%1}
But I have not tested this, so YMMV.