1

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.

3
  • 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, 2013 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, 2013 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. Jun 19, 2013 at 14:01

1 Answer 1

1

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)."

3
  • 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. Jun 27, 2013 at 16:35
  • I reworded my answer a bit. Is it better now? Jun 29, 2013 at 7:17
  • Jut void text.. @KristvanBesien May 3, 2016 at 11:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .