3

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?

Asterius
  • 2,180
  • 2
  • 19
  • 27
  • 1
    related : http://stackoverflow.com/questions/7798099/how-to-block-multiple-mod-rewrite-passes-or-infinite-loops-in-a-htaccess-cont – ben75 Jun 23 '14 at 08:35

1 Answers1

1

/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.

Tom McClure
  • 6,699
  • 1
  • 21
  • 21
  • Well, I cannot provide the exact fix I used anymore, but the answer you provide is indeed the way I explored. Thanks! – Asterius Oct 16 '14 at 09:05
  • This blog post addresses an extremely similar case: http://www.jeremytunnell.com/posts/mod_rewrite-attempting-to-bend-rewritemap-rewritecond-and-rewriterule-to-my-will – Tom McClure Oct 16 '14 at 20:20