Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic htaccess handling of subdomain, missing traffic & HTTPS

I'm still pretty new to .htaccess and RegEx and very frustrated with this but I'm probably over-complicating. Basically:

  • HTTP_HOST will be one of several domains, and should be preserved as-is including subdomains, except www. should always be removed
  • only domain1 and 'domain2' have SSL, so HTTPS should be forced, but any others should be forced to HTTP
  • if the first subfolder after the domain name is foo, then rewrite so that foo is a subdomain instead of a subfolder.
  • after that, if foo. is the subdomain:
    • retain any missing/forbidden folders/file in the visible URL (to be handled later)
    • the actual page for any of these is located at foo.*.com/index.php
  • missing/forbidden pages not on the foo subdomain should still be sent to \index.php in the root, which I'm currently doing with:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ /index.php [last,nocase]
    

My attempt:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www. [NC] 
RewriteRule ^(.*)$ $1 [L] 
RewriteCond %{HTTP_HOST} domain1\.ca [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L]
RewriteCond %{HTTP_HOST} !domain1\.ca [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L]
RewriteCond %{REQUEST_URI} ^/foo.* [NC]
RewriteRule ^ %{REQUEST_SCHEME}://foo\.%{HTTP_HOST}%{REQUEST_URI} [L]
RewriteRule "^/foo/(.+)" "%{REQUEST_SCHEME}://foo.%{HTTP_HOST}/$1" [L,NS,QSA,R=301]

Some examples:

incoming url:                               should become:
http://www.domain1.com/foo/blah          => https://foo.domain1.com/blah
https://example.com/foo/blah.html        => http://foo.example.com/blah.html
http://www.domain1.com/foo/index.php/foo => https://foo.domain1.com/foo
https://example.com/blah/blah.html       => http://example.com/blah/blah.html 

I hope this makes sense (I'm overwhelmed and overdue!) - Thanks!

like image 200
ashleedawg Avatar asked Sep 26 '19 22:09

ashleedawg


1 Answers

Those rules are a sequential translation based on your question

RewriteEngine On

# Remove www from domain, keep scheme (http or https)
RewriteCond %{HTTP_HOST}#%{HTTPS}s ^www\.([^#]+)#(?:off|on(s)) [NC]
RewriteRule ^ http%2://%1%{REQUEST_URI} [R=302,L]

# force https for {domain1,domain2}
RewriteCond %{HTTP_HOST} ^(?:domain1|domain2)\. [NC]
RewriteCond %{HTTPS} off [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

# force http for others
RewriteCond %{HTTP_HOST} !^(?:domain1|domain2)\. [NC]
RewriteCond %{HTTPS} on [NC]
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

# foo subfolder -> foo subdomain
RewriteCond %{HTTP_HOST} !^foo\. [NC]
RewriteCond %{REQUEST_URI}#%{HTTPS}s ^/foo/([^#]+)#(?:off|on(s)) [NC]
RewriteRule ^ http%2://foo.%{HTTP_HOST}/%1 [R=302,L]

# hide index.php for foo subdomain
RewriteCond %{HTTP_HOST} ^foo\. [NC]
RewriteRule ^index\.php(?:$|/(.*)) /$1 [R=302,L]

# (internal rewrite) foo subdomain -> foo's root index
RewriteCond %{HTTP_HOST} ^foo\. [NC]
RewriteCond %{REQUEST_URI} !^/foo/ [NC]
RewriteRule ^ /foo/index.php [L]

# default rule (root index)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ /index.php [L]

This is ugly, I agree. But this should work as you expect. It has been tested on a local server and all example tests you showed just passed.

Note: I intentionally used 302 redirects. When everything will be OK on your side, just switch back to 301.

like image 81
Justin Iurman Avatar answered Sep 28 '22 10:09

Justin Iurman