Forum Moderators: phranque
domain.com/hide_me/dir/file.php
I want this:
domain.com/dir/file.php
The following rule seems to do the trick:
RewriteCond %{HTTP_HOST} domain\.com
RewriteRule ^(.*)$ hide_me/$1 [L]
Except for one weird situation
If I enter:
domain.com/dir/ (notice ending forward slash)
I get:
domain.com/dir/ no problem.
However if I enter
domain.com/dir (notice no slash)
I get
domain.com/hide_me/dir.
I don't understand this behavior. Can anyone enlighten me?
It is probably interacting with something else that you have in there (maybe the process that adds a trailing / back on to URL requests that don't already have one).
Have you used Live HTTP headers to see the chain of events? What does it show? Does it do one step or several steps?
Anyway, I can't for the life of me figure this out. I've always thought Apache's approach to rewrites was overly cryptic and quirky. Does anyone have any ideas why this might be happening?
The problem (to recap) is that the hidden directory comes unhidden when the final slash is not included in a directory path (see above). It's very very odd and I'd like it not to be happening.
Put the 'add-a-slash' redirect before the internal rewrite.
Generally, put external redirect rules first, ordering them from most-specific to least, then follow those with your internal rewrites, again from most-specific to least.
For example, put one-of-a-kind old-URL redirects first, then the redirects that match several pages (or directories) at once, ending up with a blanket domain canonicalization redirect (e.g. all non-www pages redirect to www.example.com).
Then follow those redirect lines with your one-of-a-kind URL internal rewrites, ending up with -- say, a rewrite of all other requests to your WordPress script.
Be sure to use the [L] flag on all RewriteRules unless you have a specific reason not to.
Note that in order to enforce sequential execution, all of your rewrites and redirects must use mod_rewrite. If you mix mod_alias and mod_rewrite directives, the server will either execute all mod_alias directives first, followed by all mod_rewrite directives, or in less-frequent cases, do it the other way, with mod_rewrite executed before mod_alias. This depends on the server configuration. I mention this as the second-most-likely cause of a problem such as you describe. (mod_alias is the module that implements Redirect, RedirectMatch, RedirectPermanent, etc.)
Jim
I have had a very painful realization that has take me years to learn. It seems that most my woes with mod-rewrite are probably the cause of the Firefox browser. Or maybe I'm a huge idiot. It appears that Firefox (maybe all browsers) is actually caching information dealing with re-writes. It became apparent after I had no hair left to pull out and thought I was really going crazy, and had no other remedy except the last resort of a programmer, which is to try crazy s**t. So I tried loading the site in another computer, and low and behold, it worked just as I thought the rewrite should! Then I again loaded it on mine, and the da*n thing showed an infinite loop redirect error! How could this be? I cleared my cache and suddenly it worked right!
So LET MY MISERY BE LESSON TO YOU ALL. If a rewrite isn't working the way you think it should, try clearing your cache. Maybe they teach this in computer school, but I never went.
I settled on the solution of implementing an 'add trailing slash to dirs' rule. Here she is in all her glory:
# If requested URL-path does not end with a slash
RewriteCond $1 !/$
# and has no '.' in it (denoting a file extension)
RewriteCond $1 !\.
# Then add a trailing slash and externally redirect
RewriteRule (.+) http://%{HTTP_HOST}/$1/ [R=301,L]
This fixes the issue, but still does not explain why the urls below behave very differently with mod rewrite:
domain.com/dir
domain.com/dir/
I'm sure some genius out there knows why this is. Please enlighten the rest of us?
[edited by: jdMorgan at 9:11 pm (utc) on Oct. 4, 2007]
[edit reason] Formatting [/edit]
This fixes the issue, but still does not explain why the urls below behave very differently with mod rewrite:domain.com/dir
domain.com/dir/
I'm sorry, but this isn't clear. How do these URLs behave differently now?
How did you test?
What were the results?
How do those results differ from your expectations?
And of course, we're all flushing our caches after changing the code, now... :)
Jim
I have several browsers on each machine, so I try it on another browser once I think I have got everything working - just in case.
Additionally you should always use a HTTP header Checker to really see what is going on. There are several online resources as well as the Live HTTP Headers extension for Mozilla-based browsers that can help you.
I'm sorry, but this isn't clear. How do these URLs behave differently now?How did you test?
What were the results?
How do those results differ from your expectations?
I can't explain it any better than my original message. But in plain English this is the deal: When trying to hide a directory with mod-rewrite the following urls had very different effects, where I would expect them to have the same effect:
1) domain.com/dir/
2) domain.com/dir
Item '1' above worked fine, but item '2' exposed the directory, as shown in the original post above.
Thank you both for your help and input. I should go buy a book on Apache mod rewrite. I've been looking at the official site for mod-rewrite for years, and every time I seem to understand less and less : )
RewriteRule (hide/this/)?(.*) http://www.domain.com/$1
RewriteRule (.*)(hide/this)? http://www.domain.com/$1
or something like that (as a part of the existing rules).
Be careful with the "/" placement within the rule, to avoid removing or adding them unless necessary.