Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I run 8-10 EC2 based web servers, so my experience is many hours, but is limited to CentOS; specifically Amazon's distribution. I'm installing Apache using yum, so therefore getting Amazon's default compilation of Apache.

I want to implement canonical redirects from non-www (bare/root) domain to www.domain.com for SEO using mod_rewrite BUT MY .htaccess FILE IS CONSISTENTLY IGNORED.

My troubleshooting steps (outlined below) lead me to believe it's something specific to Amazon's build of Apache.

TEST CASE

  1. Launch a EC2 Instance, e.g. Amazon Linux AMI 2013.03.1
  2. SSH to the Server
  3. Run the commands:

    • $ sudo yum install httpd
    • $ sudo apachectl start
    • $ sudo vi /etc/httpd/conf/httpd.conf
    • $ sudo apachectl restart
    • $ sudo vi /var/www/html/.htaccess

In httpd.conf I changed the following, in the DOCROOT section / scope:

AllowOverride All

In .htaccess, added:

(EDIT, I added RewriteEngine On later)

RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^/(.*) http://www.domain.com/$1 [R=301,L]

Permissions on .htaccess are correct, AFAI can tell:

$ ls -al /var/www/html/.htaccess -rwxrwxr-x 1 git apache 142 Jun 18 22:58 /var/www/html/.htaccess

Other info:

$ httpd -v
Server version: Apache/2.2.24 (Unix)
Server built:   May 20 2013 21:12:45

$ httpd -M
Loaded Modules:
 core_module (static)
     ...
 rewrite_module (shared)
     ...
 version_module (shared)
Syntax OK

EXPECTED BEHAVIOR

$ curl -I domain.com
HTTP/1.1 301 Moved Permanently
Date: Wed, 19 Jun 2013 12:36:22 GMT
Server: Apache/2.2.24 (Amazon)
Location: http://www.domain.com/
Connection: close
Content-Type: text/html; charset=UTF-8

ACTUAL BEHAVIOR

$ curl -I domain.com
HTTP/1.1 200 OK
Date: Wed, 19 Jun 2013 12:34:10 GMT
Server: Apache/2.2.24 (Amazon)
Connection: close
Content-Type: text/html; charset=UTF-8

TROUBLESHOOTING STEPS

In .htaccess, added:

BLAH BLAH BLAH ERROR
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^/(.*) http://www.domain.com/$1 [R=301,L]

My server threw an error 500, so I knew the .htaccess file was processed.

As expected, it created an Error log entry: [Wed Jun 19 02:24:19 2013] [alert] [client XXX.XXX.XXX.XXX] /var/www/html/.htaccess: Invalid command 'BLAH BLAH BLAH ERROR', perhaps misspelled or defined by a module not included in the server configuration


Since I have root access on the server, I then tried moving my rewrite rule directly to the httpd.conf file. THIS WORKED. This tells us several important things are working.

$ curl -I domain.com
HTTP/1.1 301 Moved Permanently
Date: Wed, 19 Jun 2013 12:36:22 GMT
Server: Apache/2.2.24 (Amazon)
Location: http://www.domain.com/
Connection: close
Content-Type: text/html; charset=UTF-8

HOWEVER, it is bothering me that it didn't work in the .htaccess file. And I have other use cases where I need it to work in .htaccess (e.g. an EC2 instance with named virtual hosts).

Thank you in advance for your help.

share|improve this question
    
Are you sure it's hitting the proper server with every test? If you look at the expected versus actual, the server line is different. –  Nathan C Jun 19 '13 at 13:01
    
I second Nathan's suggestion - check any virtualhost settings to make sure that the .htaccess file is actually used for that domain. Also, as a general rule, if you can have the configuration in the httpd.conf file instead of the .htaccess file that will mean a small but measurable improvement in performance. –  Jenny D Jun 19 '13 at 13:54
    
Eagle eyes, all. As I mentioned, I have several servers. I had to go back in time to recreate this ticket, so I borrowed the output from several servers to do so. However, the PROCESS is consistant. –  tedneigerux Jun 19 '13 at 14:01

1 Answer 1

up vote 1 down vote accepted

You can put RewriteRules in the server config, or in .htaccess. There are however differences that mean that a rule that works in a server config will not necessarily work in .htaccess context or vice versa. RewriteRules in .htaccess files (and directory context) are matched against relative URLs, so your rule starting with / is never matched. Enable rewritelog and you'll see.

So for asume docroot is /var/www and you request http://myserver.com/foo/bar.html

A rewrite rule in your server config will be matched against /foo/bar.html

A rewrite rul in a context, or in a .htaccess file in /var/www/foo will be matched against just bar.html. So if it starts with a / it will not match ever.

It is important to be aware of this, and one of the reasons I generally consider rewriterules in .htaccess files a bad idea. I usually advise strongly against having rewriterules in .htaccess files if you can avoid it (and you have access to httpd.conf so you can). RewriteRules in .htaccess files often lead to hard to diagnose behavior, and are a huge performance hit.

See also the apache documentation: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule

"In Directory and htaccess context, the Pattern will initially be matched against the filesystem path, after removing the prefix that led the server to the current RewriteRule (e.g. "app1/index.html" or "index.html" depending on where the directives are defined)."

share|improve this answer
    
Thank you, KVB. I can't say I fully understood your answer (but that's my fault, not yours) but it gave me many new paths to investigate. –  tedneigerux Jun 27 '13 at 16:35
    
I reworded my answer a bit. Is it better now? –  Krist van Besien Jun 29 '13 at 7:17

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.