1

The Problem

I have a piece of code from another Q&A that is a generalized solution to forcing www in web addresses:

# Force www.
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [L,R=301]

My understanding of the logic:

If the HTTP_HOST is defined solely as "(no period string).(no period string)", ie. example.com, then capture the remainder and rebuild the URL with www affixed to the head of the HTTP_POST and captured string.

I have placed this code in a .htaccess file in my web document root. Within that folder are a number of subdirectories which each contain their own .htaccess file to handle redirects and clean urls that are automatically managed by a CMS. All of the entries in these subdirectories tend to follow the following pattern:

RewriteRule ^$ /reason/displayers/generate_page.php?site_id=11111&page_id=222222
RewriteRule ^page$ /subdirectory/page/ [R=permanent]
RewriteRule ^page/$ /reason/displayers/generate_page.php?site_id=111111&page_id=333333

The first problem I have is that the RewriteRule in the solution only triggers for the root page of the website and not any subdirectory or pages:

  • http(s)://example.com ->
    http(s)://www.example.com (Good)
  • http(s)://example.com/subdirectory/ ->
    http(s)://example.com/subdirectory/ (Bad)
  • http(s)://example.com/subdirectory/page/ ->
    http(s)://example.com/subdirectory/page/ (Bad)

Looking at another Q&A, a user suggested adding RewriteOptions inherit to the subdirectory .htaccess. Doing that with my initial RewriteRule in a single test directory results in the following:

  • http(s)://example.com/subdirectory/page/ ->
    http(s)://example.com//reason/displayers/generate_page.php/events/?site_id=111111&page_id=333333

The page content does appear, but the URL is certainly less than desirable. The OP of that Q&A left a comment noting that they needed to use %{REQUEST_URI} rather than attempting to capture and reuse it. Using that for the RewriteRule, I get:

  • http(s)://example.com/subdirectory/page/ ->
    http(s)://www.example.com/subdirectory/page/?site_id=111111&page_id=333333

Close, but I certainly don't want the parameters to appear there for the sake of SEO.


Questions

Is there any way to apply this kind of rule to all subdirectories and pages without needing to go in and add the RewriteOptions inherit line to each subdirectory .htaccess? Given these are created dynamically by the CMS each time a site is created, manually managing the inclusion of that line isn't ideal.

Assuming that, is there any solution to resolve the "bad" URLs I receive from my attempt to utilize RewriteOptions inherit given what the CMS is placing into the subdirectories automatically?


Alternative

This last one is likely outside of this site's scope, but given it's related, I included it in case the preceding isn't doable or if the following is preferable:

Would it be possible to handle this kind of redirect using VirtualHosts entries? As far as I can tell in my case, both "example.com" and "www.example.com" resolve to the same IP and document root. If they could be separated, www.example.com could remain as is while example.com is set to go somewhere else, allowing for a clear redirect to occur, perhaps?

<VirtualHost 111.11.11.111:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/html/
    ...
</VirtualHost>
Community
  • 1
  • 1
Nick Mischler
  • 175
  • 5
  • 20

1 Answers1

1

Yes indeed, to apply your rule to all the sub-directories insert this rule in <VirtualHost..> section:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
anubhava
  • 664,788
  • 59
  • 469
  • 547
  • So then, whatever is given in the VirtualHost is applied first, followed by the subdirectory .htaccess, then any higher directory .htaccess in order if told to via `RewriteOptions inherit`? – Nick Mischler Jan 11 '16 at 14:19
  • `RewriteOptions inherit` is only only needed to include parent directory's `.htaccess`. Rules in `VirtualHost` will be automatically applied across the site. – anubhava Jan 11 '16 at 14:47
  • Finally back to this issue. It took me awhile to figure it out (WHM/cPanel has a fairly complex include structure for virtualhosts). What you suggested, placing the rewrite rules in the virtualhost declaration, did work. Many thanks. Before I approve your answer, I have one more question to ask. Your rewrite rules check for the absence of www and append it, regardless of the value of HTTP_HOST, potentially breaking other defined subdomains. However if placed in the virtualhost for (www.)example.com, does that prevent any conflict given other subdomains would be defined elsewhere? – Nick Mischler Jan 12 '16 at 17:40
  • Yes that's correct, it will impact only `(www\.)example\.com` if placed in `VirtualHost` entry of the same. – anubhava Jan 12 '16 at 17:43
  • 1
    In my case, I went with the Rewrite at the start of my question which would trigger for any HTTP_HOST without a subdomain (assuming domain is string.string), but yes, it did work out. I ask that additional question in case another user comes along and questions the difference in the two rules and if one or either will work in the manner described. – Nick Mischler Jan 12 '16 at 19:36