broken apache .htaccess (mod_rewrite)

Hey there, I'm running into an apache mod_rewrite configuration issue on one of our machines. Has anyone encountered / overcome anyone of these issues.

  • URL1 ( http://www.uppereast.com ) is not being redirected to URL2 ( http://www.nyclocalliving.com ). This definitely worked in my test environment where a localhost address was rewritten to URL2 ( RewriteRule ^http://upe.localhost$ http://www.nyclocalliving.com ).

  • I'm trying to get the all of the redirect rules working ( 2200 + ), but the 'http://www.nyclocalliving.com' site encounters a server error if I use more that 1000 or more rules.

A) .htaccess file - I've tried the simplest approach which worked in a local environment

 75 # Various rewrite rules.
 76 <IfModule mod_rewrite.c>
 77   RewriteEngine on
 78 
 79   # BEGIN new URL Mapping rules
 80 #RewriteRule ^http://www.uppereast.com/$ http://www.nyclocalliving.com
 ...
 2307 #RewriteRule ^http://www.uppereast.com/zipcodechange.html$ http://www.nyclocalliving.com/zip-code-change

fig. 1

B) /var/log/httpd/error_log file - there are these seg. fault errors when I enable the first rule ( line 80 ). no error logs otherwise.

 1893 [Fri Sep 25 17:53:46 2009] [notice] Digest: generating secret for digest authentication ...
 1894 [Fri Sep 25 17:53:46 2009] [notice] Digest: done
 1895 [Fri Sep 25 17:53:46 2009] [notice] Apache/2.2.3 (CentOS) configured -- resuming normal operations
 1896 [Fri Sep 25 17:53:47 2009] [notice] child pid 29774 exit signal Segmentation fault (11)
 1897 [Fri Sep 25 17:53:47 2009] [notice] child pid 29775 exit signal Segmentation fault (11)
 1898 [Fri Sep 25 17:53:47 2009] [notice] child pid 29776 exit signal Segmentation fault (11)
 1899 [Fri Sep 25 17:53:47 2009] [notice] child pid 29777 exit signal Segmentation fault (11)
 1900 [Fri Sep 25 17:53:47 2009] [notice] child pid 29778 exit signal Segmentation fault (11)
 1901 [Fri Sep 25 17:53:47 2009] [notice] child pid 29779 exit signal Segmentation fault (11)

fig. 2

C) Some more debug information from the shell; the mod_rewrite is turned on and this is the machine architecture

 1 # apachectl -t -D DUMP_MODULES | more         
 2 Loaded Modules:
 3  core_module (static)
 4  ...
 5  rewrite_module (shared)

 1 # uname -a
 2 Linux RegionalWeb 2.6.24-23-xen #1 SMP Mon Jan 26 03:09:12 UTC 2009 x86_64 x86_64 x86_64 GNU/Linux

fig. 3

I looked into some previous posts (.htaccess not working (mod_rewrite)), but didn't find a solution for this. I'm sure there's a small switch somewhere that I'm missing.

Thanks in advance Tim


Solution 1:

Let's start with your apache configuration. If you are getting segfaults when mod_rewrite rules begin, something is not meshing right. Are you running an RPM/DEB version of Apache? Or is this something you've compiled yourself?

I would troubleshoot this error first before looking into any issues with your syntax, especially since it worked on your localhost.

Solution 2:

I'm not sure why it would segfault, but, I think you want a rule like:

RewriteRule ^zipcodechange.html$ http://www.nyclocalliving.com/zip-code-change [R=301,L]
RewriteRule ^(.*)$ http://www.nyclocalliving.com/$1 [R=301,L]

The first rule will specifically write the page to the newly created page and do a 301 redirect. The second rule will take whatever url was requested, and redirect it to the other site with the page portion of the URL intact. Use [R=301,QSA,L] if you have arguments on the pages (i.e. pagename.html?something=else)

RewriteRule ^http://www.uppereast.com/$ http://www.nyclocalliving.com

The hostname/URL isn't available at that point. I don't know of any issues with / in the rules that would cause it to segfault, but, I think the two rules above do what you intend. As for the segfaults, that is a separate issue.

If the suggested rules work, I think something in the mod_rewrite parsing engine must be having issues with the //. If the above rules still cause the segfaults, you might want to make sure your apache modules and base version match. Perhaps you recompiled apache over top of the prepackaged apache and your compile options didn't put the modules in the same place.

As for the issue with 1000+ rules, Apache must read the .htaccess file for everything served in the current directory or below unless there is an .htaccess file in one of the subdirectories and it doesn't contain an Inherit statement. It is possible reading a 70k file each time it must serve a page/asset, something is overrunning a memory allocation. You could put these rules in your apache config as well.

Solution 3:

If you need to control your rules based on the servername/hostname, you can write rules like

# simple and not really useful
RewriteCond %{HTTP_HOST} ^domain\.com
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]

# more useful
RewriteCond %{HTTP_HOST} domainA\.com
RewriteRule ^(.*)$ http://www.domainB.com/$1 [R=301,L]

# or with a more specific match
RewriteCond %{HTTP_HOST} domainA\.com
RewriteRule ^zipcodechange.html$ http://www.domainB.com/zip-code-change [R=301,L]

Also make sure that your "catchall" rule is at the end of all the specific rules... the ,L option means Last Rule, meaning that the rest of the .htaccess is ignoreed (at least for rewite).