Forum Moderators: phranque
[httpd.apache.org...]
And then, this is what you need:
[httpd.apache.org...]
thank you for response and links...made me realize I have less of a clue than I thought..:) Onward....................
See the example case-conversion code in the RewriteMap section of the Apache mod_rewrite documentation; It makes use of the operating system's "tolower" function, and is quite efficient compared to lowercasing characters one-at-a-time, as required in .htaccess.
Jim
So if you typed in or linked to [widgets.com...] it would redirect it to [widgets.com...] When the code was added it seemed to work like it was supposed to but for some reason the index page could not be loaded if you went directly to widgets.com
From the code, TEST.HTM and test.htm are the same but their urls are difference. This is a reason why they're in the loop and the page can't be loaded if the code was added to redirect TEST.THM to test.htm.
Is there anyone know how to redirect TEST.HTM ot Test.htm to test.htm using 301 without going into a loop?
# Solution using a RewriteMap and a RewriteRule in httpd.conf, conf.d, etc.
#
RewriteMap LowerCaseIt int:tolower
RewriteRule ^/([^A-Z]*[A-Z].*)$ http://www.example.com/${LowerCaseIt:$1} [R=301,L]
# Solution using a RewriteMap defined in httpd.conf, conf.d, etc. (as
# shown in the example above), and a RewriteRule located in .htaccess
#
RewriteRule ^([^A-Z]*[A-Z].*)$ http://www.example.com/${LowerCaseIt:$1} [R=301,L]
# .htaccess-only solution
#
# If no uppercase characters in current URL-path, skip next 28 rules
RewriteRule ![A-Z] - [S=28]
#
# Else replace one instance of each uppercase letter present
RewriteRule ^([^A]*)A(.*)$ $1a$2
RewriteRule ^([^B]*)B(.*)$ $1b$2
RewriteRule ^([^C]*)C(.*)$ $1c$2
RewriteRule ^([^D]*)D(.*)$ $1d$2
RewriteRule ^([^E]*)E(.*)$ $1e$2
RewriteRule ^([^F]*)F(.*)$ $1f$2
RewriteRule ^([^G]*)G(.*)$ $1g$2
RewriteRule ^([^H]*)H(.*)$ $1h$2
RewriteRule ^([^I]*)I(.*)$ $1i$2
RewriteRule ^([^J]*)J(.*)$ $1j$2
RewriteRule ^([^K]*)K(.*)$ $1k$2
RewriteRule ^([^L]*)L(.*)$ $1l$2
RewriteRule ^([^M]*)M(.*)$ $1m$2
RewriteRule ^([^N]*)N(.*)$ $1n$2
RewriteRule ^([^O]*)O(.*)$ $1o$2
RewriteRule ^([^P]*)P(.*)$ $1p$2
RewriteRule ^([^Q]*)Q(.*)$ $1q$2
RewriteRule ^([^R]*)R(.*)$ $1r$2
RewriteRule ^([^S]*)S(.*)$ $1s$2
RewriteRule ^([^T]*)T(.*)$ $1t$2
RewriteRule ^([^U]*)U(.*)$ $1u$2
RewriteRule ^([^V]*)V(.*)$ $1v$2
RewriteRule ^([^W]*)W(.*)$ $1w$2
RewriteRule ^([^X]*)X(.*)$ $1x$2
RewriteRule ^([^Y]*)Y(.*)$ $1y$2
RewriteRule ^([^Z]*)Z(.*)$ $1z$2
#
# Set the redirect-required flag since at least one
# uppercase letter must have been replaced to get here
RewriteRule . - [E=Redirect:Yes]
#
# If any uppercase letters remain in the URL-path,
# then restart the mod_rewrite code from the top
RewriteRule [A-Z] - [N]
#
# (Skip from [S=28] flag above lands here)
# If the redirect-required flag has been set, invoke an external
# 301 redirect to notify the client that the URL has been changed
RewriteCond %{ENV:Redirect} ^Yes$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
If you must use the .htaccess-only solution, be aware that if a URL contains multiple instances of any given uppercase character, the code will restart mod_rewrite processing to replace subsequent instances of that character. So to minimize execution time, place the code as close as you practically can to the top of your existing mod_rewrite code without interfering with its function, and place the mod_rewrite code as close to the top of your .htaccess file as you can without interfering with its structure.
If you have one file or directory (or a few files or directories) that must be named with uppercase letters, you won't want this code to redirect that URL (or those URLs). You can add a RewriteRule above this code to skip it if that URL is requested. For example, add
RewriteRule ^my-required-uppercase-URL\.html$ - [S=30]
I just typed this code. It is untested and comes with no warranty, so please test it thoroughly and then use it at your own risk.
Jim
[edited by: jdMorgan at 1:14 am (utc) on Oct. 19, 2006]
So, after some tinkering, I found a work-around that functions on Apache 1.3. It is very much a kludge, but it seems to work.
# Uppercase-to-lowercase URL redirect - .htaccess-only solution
#
# Modified with work-around for Apache 1.3 mod_rewrite path bug
# (See http://archive.apache.org/gnats/7879)
#
# If no uppercase characters in current URL-path, skip next 28 rules
RewriteRule ![A-Z] - [S=28]
#
# Else replace first instance of each uppercase letter present
RewriteRule ^([^A]*)A([^<]*) $1a$2<
RewriteRule ^([^B]*)B([^<]*) $1b$2<
RewriteRule ^([^C]*)C([^<]*) $1c$2<
RewriteRule ^([^D]*)D([^<]*) $1d$2<
RewriteRule ^([^E]*)E([^<]*) $1e$2<
RewriteRule ^([^F]*)F([^<]*) $1f$2<
RewriteRule ^([^G]*)G([^<]*) $1g$2<
RewriteRule ^([^H]*)H([^<]*) $1h$2<
RewriteRule ^([^I]*)I([^<]*) $1i$2<
RewriteRule ^([^J]*)J([^<]*) $1j$2<
RewriteRule ^([^K]*)K([^<]*) $1k$2<
RewriteRule ^([^L]*)L([^<]*) $1l$2<
RewriteRule ^([^M]*)M([^<]*) $1m$2<
RewriteRule ^([^N]*)N([^<]*) $1n$2<
RewriteRule ^([^O]*)O([^<]*) $1o$2<
RewriteRule ^([^P]*)P([^<]*) $1p$2<
RewriteRule ^([^Q]*)Q([^<]*) $1q$2<
RewriteRule ^([^R]*)R([^<]*) $1r$2<
RewriteRule ^([^S]*)S([^<]*) $1s$2<
RewriteRule ^([^T]*)T([^<]*) $1t$2<
RewriteRule ^([^U]*)U([^<]*) $1u$2<
RewriteRule ^([^V]*)V([^<]*) $1v$2<
RewriteRule ^([^W]*)W([^<]*) $1w$2<
RewriteRule ^([^X]*)X([^<]*) $1x$2<
RewriteRule ^([^Y]*)Y([^<]*) $1y$2<
RewriteRule ^([^Z]*)Z([^<]*) $1z$2<
#
# Set the redirect-required flag since at least one
# uppercase letter must have been replaced to get here
RewriteRule . - [E=Redirect:Yes]
#
# If any uppercase letters remain in the URL-path,
# then restart the mod_rewrite code from the top
RewriteRule [A-Z][^<]*< - [N]
#
# (Skips from the [S=28] flag above land here)
# If the redirect-required flag has been set, invoke an external
# 301 redirect to notify the client that the URL has been changed
RewriteCond %{ENV:Redirect} ^Yes$
RewriteRule ^([^<]+) http://www.example.com/$1 [R=301,L]
It's unlikely, but if your URLs (not including any query strings) include a "<" character, then you must use a different demarcation character, taking care that the character you choose is not a special regular-expressions token. This leaves only a few choices, so I'd recommend using "~" (tilde), ";", ">", or "<" as shown.
Jim