16

I would like URLs like server.com/foo to be case-insensitive. But server.com/foo actually gets mod_rewrite'd to server.com/somedir/foo

(Assume that all the files in "somedir" are lower case.)

So the question is, how to accomplish a mod_rewrite like the following:

RewriteRule  ^([^/]+)/?$  somedir/convert_to_lowercase($1)

PS: Here's a handy mod_rewrite cheat sheet -- http://dreev.es/modrewrite -- though it fails to answer this particular question.

PPS: Thanks to Bee and Ignacio for all the help with this. Also, here's a related question: RewriteMap activation

Community
  • 1
  • 1
dreeves
  • 26,430
  • 45
  • 154
  • 229

3 Answers3

21

First, put the following line in the <VirtualHost> section of your .conf file. (For me that lives at /etc/httpd/vhosts.d/00foo.conf.)

RewriteMap lc int:tolower 

You can replace lc with any name you want. Then restart apache, which you can do with sudo service httpd restart.

Finally, add this in your .htaccess file:

RewriteRule ^/(.*)$ /${lc:$1} 
dreeves
  • 26,430
  • 45
  • 154
  • 229
  • Works here. Did you bounce httpd? – Ignacio Vazquez-Abrams May 27 '10 at 19:15
  • Probably not. What does that mean? – dreeves May 27 '10 at 19:19
  • Thanks for all the help, Ignacio. I updated this answer with explicit instructions about what to put where and about restarting apache. – dreeves May 28 '10 at 17:50
  • Be advised: This may not work as advertised. The first part is correct. Put the RewriteMap statement in the .conf file. However in the .htaccess file, you may need one more statement; "RewriteEngine On" This is what finally worked for me. `RewriteEngine On RewriteCond %{REQUEST_URI} [A-Z] RewriteRule . ${lc:%{REQUEST_URI}} [R=301,L]` – sea26.2 Apr 24 '14 at 18:02
  • "add this in your .htaccess file:" - although the directive as posted will only work in a _server_ or _virtualhost_ context. – MrWhite Mar 09 '21 at 12:25
14
RewriteMap tolower int:tolower
RewriteRule  ^([^/]+)/?$  somedir/${tolower:$1}
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 1
    Ah, thanks, it now matches what I found elsewhere on the web in the meantime, but it's still not working for me. I didn't understand your other comment about bouncing httpd. – dreeves May 27 '10 at 19:25
  • I tried adding the above to my .htaccess and restarting httpd, and it is bringing the whole domain down. The error log says: "Rewritemap not allowed here". Where specifically am I supposed to put the Rewritemap statement? The documentation I'm finding shows it as two consecutive lines, like above. (I just stuck it in .htaccess right above the specific RewriteRule). – Bee May 28 '10 at 03:03
  • 1
    @Bee: The docs say "server config, virtual host", which means right in the main config stream or within a `` directive. http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap – Ignacio Vazquez-Abrams May 28 '10 at 03:13
  • Sorry we're so dense about this stuff. I see from the link you provided (thanks!) that the RewriteMap line is not allowed in .htaccess. I tried putting in the section of /etc/httpd/vhosts.d/00server.conf but when I restart Apache it complains that RewriteMap is not allowed here. – dreeves May 28 '10 at 13:54
  • That's really odd. I have it working in a `` section just fine here, so I don't know what's going on. – Ignacio Vazquez-Abrams May 28 '10 at 16:09
  • Ah, sorry, it worked there after all! I'll update my answer with more explicit instructions about this. If you want to do the same then I can just delete my answer. – dreeves May 28 '10 at 17:45
3

I would make it a 301 redirect, NOT a URL rewrite, for SEO purposes:

RewriteMap tolower int:tolower
RewriteRule  ^([^/]+)/?$  somedir/${tolower:$1} [R=301,L]
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
  • 6
    A 301 without a cache expiry header is very bad practice because it gets cached *for ever* in browsers. You'll be living with its effects for years. Change `R=301,L` to `R=301,L,E=limitcache:1` and add a `Header always set Cache-Control "max-age=3600" env=limitcache` directive. That'll limit caching to 1h while still giving you the SEO advantages of a 301 redirect. – Richard Smith Dec 16 '15 at 09:58
  • 4
    A `301` redirect is, by definition, _permanent_, thus it can be cached indefinitely by default. If you expect the redirect not to be permanent, then use `302`. – fritzmg Jan 02 '20 at 12:27