Search code examples
apachemod-rewritehttp-redirectvhoststld

Apache / mod_rewrite: Change TLD, but keep subdomain, protocol and query-string


I thoroughly searched stackoverflow and found about 100 mod_rewrite-questions, but this was not covered...strange as it seems pretty common.

My problem: I have a web-application on a master-domain (mywebapp.com). Now I have additional country-specific TLDs (eg .ch) which I'd like to redirect on the .com-domain. Nothing special so far. But now to the other criteria:

Requirements

  • the protocol should be left unchanged
  • the query-string should be left unchanged
  • the subdomain-part should be left unchanged as the tenants are identified by those
  • only exchange the TLD!

Examples

So to put it all together some examples how it should be:

  • http:// demo.mywebapp.ch -> http:// demo.mywebapp.com
  • http:// other.mywebapp.ch/user/profile -> http:// other.mywebapp.com/user/profile
  • https:// third.mywebapp.ch/about -> https:// third.mywebapp.com/about

(spaces in urls are intentional to prevent stackoverflow from generating links)

and so on. I really only need to replace the TLD in protocol-generic manner. Of course it would be nice if the rule-set is SEO-conform (301).

Additional Information / details

The domains are currently set to point to the same webserver/IP which I have root-access upon. The server is managed by ISPConfig, but II can edit the vhosts manually as well.

Thanks already in advance!

cheers, Pascal


Solution

  • I think the following would do the trick:

    RewriteEngine on
    RewriteBase /
    
    RewriteCond %{HTTP_HOST} !.*\.com
    RewriteCond %{HTTPS} ^on
    RewriteCond %{HTTP_HOST} (?:([^.]+)\.)?mywebapp\..*
    RewriteRule ^.* https://%1mywebapp.com%{REQUEST_URI} [R=302,L] #removed double slash
    
    RewriteCond %{HTTP_HOST} !.*\.com
    RewriteCond %{HTTPS} !^on
    RewriteCond %{HTTP_HOST} (?:([^.]+)\.)?mywebapp\..*
    RewriteRule ^.* http://%1mywebapp.com%{REQUEST_URI} [R=302,L] #removed double slash
    

    Here's what it's saying:

    1. Create a RewriteRule only if %{HTTP_HOST} does not contain .com
    2. check protocol and only continue if is https
    3. Run a regex to check if subdomain exists and store subdomain if it does (referenced by $1)
    4. Manually force the .com, preceed it with subdomain, concatenate the %{REQUEST_URI} and then redirect (I left it as a 302 Temporary Redirect so you can play with it as needed. I would go to a 301 until you are 100% ready)

    Edit: I duplicated the rule set to handle the protocol issue. So apparently you can only get the last backreference. Meaning that when the protocol was https, it would overwrite the subdomain stored in %1 backreference. By having a ruleset for either protocol, you circumvent the issue. Likely not the prettiest way, but it should get the job done.