Forum Moderators: phranque

Message Too Old, No Replies

Easy rewrite driving me crazy

weird behavior with trailing slash

         

pixeltierra

5:29 am on Oct 3, 2007 (gmt 0)

10+ Year Member



I simply want to hide one level of the directory structure. So instead of this:

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?

g1smd

9:22 am on Oct 3, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Your code is for a rewrite. I assume that links on the page point only to domain.com/dir/file.php and domain.com/dir/ and domain.com/dir type URLs.

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?

pixeltierra

2:45 am on Oct 4, 2007 (gmt 0)

10+ Year Member



g1smd: Tried to sticky you, but your sticky box is full. Not sure you realize this.

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.

jdMorgan

1:35 pm on Oct 4, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Rule order is important, and it appears that your rules are not in the right order.

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

pixeltierra

2:55 pm on Oct 4, 2007 (gmt 0)

10+ Year Member



Thank you for your help gentlemen (and/or ladies). I have it all working now (will explain in a moment). But first:

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]

jdMorgan

9:09 pm on Oct 4, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



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

g1smd

11:12 pm on Oct 4, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Yeah, clear the cache after every change you make.

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.

pixeltierra

6:46 am on Oct 5, 2007 (gmt 0)

10+ Year Member




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 : )

g1smd

7:31 pm on Oct 5, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If the directory is exposed you can always do a redirect like this:

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.