Forum Moderators: phranque
I'm fairly new to writing rules in for my .htaccess file.
What I'm trying to do is to serve a 302 redirect to a page IF the ip address is outside of a range X AND the requested file is not in the root folder, folder Y, OR is the index file in the root.
302 Redirect if (ip address outside of range X && (requested file not in (root ¦¦ folder Y) ¦¦ is index file in root ))
This is what I have so far:
RewriteCond %{HTTP_HOST} ^123\.123\.123\.123 # IP Not In Range
RewriteCond ___ # Request is not in root or folder Y
RewriteCond ___ # Request is not index file in root
RewriteRule ^(.*)$ /file.php [R=302,L] # 302 Redirect to this page
Any ideas on how I can fill in the blanks, or any caviots I'm missing?
Thanks
# If requesting client is not within 192.168.123.0 - 192.168.123.31
RewriteCond %{REMOTE_ADDR}!^192\.168\.123\.([12]?[0-9]¦3[01])$
# And requested URL-path is not in root (if $1 contains a slash, it's not in root)
RewriteCond $1 /
# But also not in folder Y
RewriteCond $1 !^Y/
RewriteRule ^(.*)$ http://www.example.com/file.php [R=302,L]
#
# If requesting client is not within 192.168.123.0 - 192.168.123.31
RewriteCond %{REMOTE_ADDR}!^192\.168\.123\.([12]?[0-9]¦3[01])$
# And "/" or index.html file requested
RewriteCond $1 !^(index\.html)?$
# And not already redirected to "file.php" (Prevent recursion)
RewriteCond $1 !file\.php$
RewriteRule ^(.*)$ http://www.example.com/file.php [R=302,L] # 302 Redirect to this page
You also need to know that the [OR] operator only operates between the current RewriteCond and the following RewriteCond, and that RewriteConds apply only to the single RewriteRule which follows them. This makes it impossible to implement your logic with a single rule.
And finally, getting back to the IP address range, be aware that there is no numeric range compare in mod_rewrite; Mod_rewrite can only do string compares -- That is, you are comparing the characters that express numbers, and not the numbers themselves.
Oh, and the "not file.php" RewriteCond may be redundant in the second rule, depending on whether it is in fact your "index file."
Replace all broken pipe "¦" characters above with solid pipe characters before use; Posting on this forum modifies the pipe characters.
Jim
Your advice has helped move me in the right direction and allowed me to accomplish my task at hand.
While it works perfectly, I still don't understand this part:
RewriteCond $1 /
I thought the $1 was a variable, something used in the RewriteRule part. Is this different?
How would I read that expression out-loud?
Maybe, "If the following condition request variable contains a slash, then this rule is in agreement with the rewrite"?
Thanks again.
If it's not clear, be aware that the RewriteRule pattern is always evaluated first. Only if it matches are any of the RewriteConds evaluated. If they too match, then the rewrite or redirect specified by the rule is invoked. Thus RewriteRule back-references are available to both RewriteConds and to the RewriteRule itself, and RewriteCond back-references are available to subsequent RewriteConds and to the RewriteRule (as %1 through %9).
See the Ruleset Processing section and the descriptions of back-references in the mod_rewrite documentation if this isn't clear.
With a "(.*)" pattern back-referenced as $1 in a .htaccess context, RewriteCond patterns are identical to what would be used if you tested the %{REQUEST_URI} variable, except that the leading slash will be present in %{REQUEST_URI}, but not in the URL-path as seen by RewriteRule. So, using $1 in this ruleset actually simplified it, because it made testing for "not in root" easier than it would have been if we used
RewriteCond %{REQUEST_URI} ^/[^/]+/
Jim