Monday, November 23, 2009

godaddy.com linux hosting and converting url to lowercase...

So I had an interesting experience today with my website nkcorner.com. I noticed that when running my website on my Windows system the URL is case insensitive. On GoDaddy's server the URL is case sensitive since it runs on Linux.


I started digging around for how to fix this. GoDaddy doesn't load the mod_spelling module or create a RewriteMap for tolower (as far as I know). This means that I can't use the CheckSpelling On fix or the RewriteMap tolower function.


Before I continue - Please correct me if I'm wrong because what I'm about to show is a really awkward workaround...


So I had to write 26 lines of letter by letter conversion. This is what it looks like in my .htaccess file:




RewriteCond %{REQUEST_URI} !([A-Z]+)
RewriteRule .* - [S=27]
RewriteRule ^(.*)A(.*)$ http://%{HTTP_HOST}/$1a$2 [R=301,L]
RewriteRule ^(.*)B(.*)$ http://%{HTTP_HOST}/$1b$2 [R=301,L]
RewriteRule ^(.*)C(.*)$ http://%{HTTP_HOST}/$1c$2 [R=301,L]
RewriteRule ^(.*)D(.*)$ http://%{HTTP_HOST}/$1d$2 [R=301,L]
RewriteRule ^(.*)E(.*)$ http://%{HTTP_HOST}/$1e$2 [R=301,L]
RewriteRule ^(.*)F(.*)$ http://%{HTTP_HOST}/$1f$2 [R=301,L]
RewriteRule ^(.*)G(.*)$ http://%{HTTP_HOST}/$1g$2 [R=301,L]
RewriteRule ^(.*)H(.*)$ http://%{HTTP_HOST}/$1h$2 [R=301,L]
RewriteRule ^(.*)I(.*)$ http://%{HTTP_HOST}/$1i$2 [R=301,L]
RewriteRule ^(.*)J(.*)$ http://%{HTTP_HOST}/$1j$2 [R=301,L]
RewriteRule ^(.*)K(.*)$ http://%{HTTP_HOST}/$1k$2 [R=301,L]
RewriteRule ^(.*)L(.*)$ http://%{HTTP_HOST}/$1l$2 [R=301,L]
RewriteRule ^(.*)M(.*)$ http://%{HTTP_HOST}/$1m$2 [R=301,L]
RewriteRule ^(.*)N(.*)$ http://%{HTTP_HOST}/$1n$2 [R=301,L]
RewriteRule ^(.*)O(.*)$ http://%{HTTP_HOST}/$1o$2 [R=301,L]
RewriteRule ^(.*)P(.*)$ http://%{HTTP_HOST}/$1p$2 [R=301,L]
RewriteRule ^(.*)Q(.*)$ http://%{HTTP_HOST}/$1q$2 [R=301,L]
RewriteRule ^(.*)R(.*)$ http://%{HTTP_HOST}/$1r$2 [R=301,L]
RewriteRule ^(.*)S(.*)$ http://%{HTTP_HOST}/$1s$2 [R=301,L]
RewriteRule ^(.*)T(.*)$ http://%{HTTP_HOST}/$1t$2 [R=301,L]
RewriteRule ^(.*)U(.*)$ http://%{HTTP_HOST}/$1u$2 [R=301,L]
RewriteRule ^(.*)V(.*)$ http://%{HTTP_HOST}/$1v$2 [R=301,L]
RewriteRule ^(.*)W(.*)$ http://%{HTTP_HOST}/$1w$2 [R=301,L]
RewriteRule ^(.*)X(.*)$ http://%{HTTP_HOST}/$1x$2 [R=301,L]
RewriteRule ^(.*)Y(.*)$ http://%{HTTP_HOST}/$1y$2 [R=301,L]
RewriteRule ^(.*)Z(.*)$ http://%{HTTP_HOST}/$1z$2 [R=301,L]
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]


I wish I could get this to work without the redirects, but so far I haven't found any way to get mod_rewrite to not re-append the sub-directories. Ie if you try this with a path like http://nkcorner.com/RacingLive/RacingLive.php, it will keep putting the %PATHINFO (RacingLive.php) onto the modified URL which is retarded. If you figure it out let me know.




The first 2 lines say that if there are no capital letters, skip the next 27 rules. This is the only way to group or perform if else like code with rewrites. This is because you can't group multiple RewriteRule lines to a single RewriteCond line.


The last line rewrites uppercase to lowercase on windows. I noticed that since Windows is case insensitive it detects the uppercase on the RewriteCond line, but converts it to lowercase for the RewriteRule line. This means that if I want to change the URL I have to manually rewrite it with the last line. I do this for all URLs that had uppercase letters after they pass the letter by letter replacements. (Letter by letter replacements don't occur on Windows, only on Linux...)


Perhaps someone knows an easier way to do this? Perhaps a single line for replacing A-Z with a-z without the mod_spelling or tolower functions?


Anyhow this is my solution and I hope it helps someone else with the same problem.


PS, I see someone else thought of this before me:
http://www.webmasterworld.com/forum92/5308.htm.
Give credit where credit is due.


Note: Beware using this option as the stats folder provided and updated by godaddy.com uses mostly uppercase files, and this will stop working with this solution. I haven't yet thought of how to fix this but I'll probably start using .htaccess per folder and per file as a solution.