开发者

RewriteRule being greedy

I have been looking for an answer for a few hours now, so sorry if this was asked a ton of times, I missed it.

I basically want to make a rewrite to ignore the first directory. That first dir in the path will be different so I thought I could use a regex. But my regex is matching all the 开发者_运维技巧way to the file name:

RewriteRule ^([a-z]+)?/(.+)$ $2 [L]

this works if I am one level deep:

http://test.domain.com/one/index.php

I get the actual index page of the root. Which is what I want. but if I were to go deeper:

http://test.domain.com/one/two/anotherfile.php

I get a message saying /anotherfile.php was not found, because it is looking in the root for it. So it seems my regex is not stopping after the last [a-z]. I appreciate any help.

This is Apache2 if that matters at all.


The rewrite engine repeats all the rules until the URI is the same before and after an iteration through the rules. Given the rule, RewriteRule ^([a-z]+)?/(.+)$ $2 [L], and the input: http://test.domain.com/one/index.php, this is what's happening:

  1. The leading slash (prefix) is removed from the URI: one/index.php
  2. The rule is applied, URI matches ^([a-z]+)?/(.+)$
  3. URI is rewritten to /index.php
  4. Internal redirect, new URI (/index.php) doesn't match old URI (/one/index.php) and is run back through the rewrite rules
  5. leading slash is removed
  6. The rule is applied, URI does not match ^([a-z]+)?/(.+)$
  7. URI is not rewritten. new URI (/index.php) is same as old URI before being run through the rewrite engine (/index.php), rewriting stops

Resulting URI is /index.php

But with the input: http://test.domain.com/one/two/anotherfile.php

  1. The leading slash (prefix) is removed from the URI: one/two/anotherfile.php
  2. The rule is applied, URI matches ^([a-z]+)?/(.+)$
  3. URI is rewritten to /two/anotherfile.php
  4. Internal redirect, new URI (/two/anotherfile.php) doesn't match old URI (/one/two/anotherfile.php) and is run back through the rewrite rules
  5. leading slash is removed (two/anotherfile.php)
  6. The rule is appled, URI matches ^([a-z]+)?/(.+)$
  7. URI is rewritten to /anotherfile.php
  8. Internal redirect, new URI (/anotherfile.php) doesn't match old URI (/two/anotherfile.php) and is run back through the rewrite rules
  9. leading slash is removed (anotherfile.php)
  10. The rule is applied, URI does not match ^([a-z]+)?/(.+)$
  11. URI is not rewritten. new URI (/anotherfile.php) is same as old URI before being run through the rewrite engine (/anotherfile.php), rewriting stops

Resulting URI is /anotherfile.php

The [L] doesn't stop the resulting URI from being put back through the rewrite engine, it just stops the rewriting process for the current iteration. You need to change the regular expression or add some kind of rewrite condition. One possibility is adding RewriteRule ^[a-z+]/([a-z]+)?/(.+)$ $2 [L] before the one that you have so that 2 deep directories get handled separately.


Hmmmm...

Throwing some thoughts out there:

  1. I thought there might be recursive RewriteRule-ing... but I'm not sure, since you put the 'last' rule in there. However, this is the only logical thing I think could explain what is happening.

    1. This is different from your Regex not stopping--this would be Apache continuing on long after we've told it to give up.
  2. If Apache isn't stopping, I'm not sure what recourse you have. Perhaps RewriteCond, DPI (DPI discards PATH_INFO ), analyzing THE_REQUEST, or more?

Sorry I couldn't be of more help. I hope you worked around this in the past year.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜