1

I'm trying to accomplish 2 tasks with mod_rewrite:

  1. If the URL, regardless of protocol, does not have the "www" subdomain, then add "www" to the URL.

  2. If the URI begins with /secure.php AND the protocol is NOT https, then switch the protocol to https.

So I tried:

# Redirect to www subdomain
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

# Force SSL for secure.php URIs
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/secure.php
RewriteRule ^(.*)$ https://www.mysite.com%{REQUEST_URI} [R=301,L]

But I get a redirect loop when accessing /secure.php URIs. I can't figure out what the problem is, this is how I see the sequence of events:

  1. http://mysite.com/secure.php is requested
  2. The host name does not contain "www", so it passes the first condition
  3. The URL is updated to http://www.mysite.com/secure.php, and the process loops back to the top.
  4. The host name does contain "www", so it fails the first condition and skips the rewrite.
  5. HTTPS is off, so it matches the next condition, AND
  6. The URI begins with "/secure.php", so it matches both required conditions
  7. The URL is updated to https://www.mysite.com/secure.php, and the process loops back to the top.
  8. The host name does contain "www", so it fails the first condition, and skips the rewrite.
  9. HTTPS is not off, so it fails the next condition and skips the rewrite.

Have I got that right? What am I doing wrong here?

I also have one other rule in .htaccess for removing index.php from ExpressionEngine URLs:

RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

So here's the entire .htaccess file:

RewriteEngine On
RewriteBase /

# Remove index.php from ExpressionEngine URIs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

# Redirect to www subdomain
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

# Force SSL for /secure.php URIs
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/secure.php
RewriteRule ^(.*)$ https://www.mysite.com%{REQUEST_URI} [R=301,L]
kmgdev
  • 2,607
  • 28
  • 41
  • Your sequence of events is pretty close to [the real process](http://httpd.apache.org/docs/2.2/rewrite/tech.html), but that's irrelevant in this case as your conclusion is correct, in my opinion. I can't see any reason for a loop either. Is that all or there are more rules somewhere? If that's all, where are the `RewriteEngine` and `RewriteBase` directives? Is `FollowSymlinks` enabled, i.e `Options +FollowSymlinks`? – Felipe Alameda A Feb 20 '13 at 22:26
  • I do have `RewriteEngine On` set, but not `RewriteBase`. `FollowSymlinks` is not enabled via the .htaccess file - not sure about the server itself. I do have one other rule in the file, which I've added to my question. – kmgdev Feb 21 '13 at 00:34
  • Where is the last rule-set you added to the question, before or after the other rules? Please put them in the original order including all directives. – Felipe Alameda A Feb 21 '13 at 03:05
  • I've added the full .htaccess file to my question (and added `RewriteBase`) - thanks! – kmgdev Feb 21 '13 at 15:31

1 Answers1

0

The server variables like HTTP_HOST or REQUEST_URI are available in a RewriteCond, but not in a RewriteRule. If you need these variables you must capture them in a RewriteCond

RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} (.+)
RewriteRule .* http://www.%1/$0 [R,L]

You don't need to check for secure.php in a RewriteCond, you can just specify it in the RewriteRule

RewriteCond %{HTTPS} off
RewriteRule ^/?(secure.php.*) https://www.mysite.com/$1 [R,L]

OT: Never test with 301 enabled, see this answer Tips for debugging .htaccess rewrite rules for details.

Community
  • 1
  • 1
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • Thanks for the help Olaf. I tried your code, but I'm still getting a redirect loop on the /secure.php URLs. – kmgdev Feb 21 '13 at 00:27
  • @kgrote I cannot see, how this might happen, unless you have other conflicting rules. If you have access to your apache configuration files, you can activate `RewriteLog` to see, where it is going wrong. – Olaf Dietsche Feb 21 '13 at 08:45