Search code examples
apache.htaccessmod-rewrite

Apache mod_rewrite redirect subdomains on specific basis


I'm developing an application that is running on my domain. All works as expected, but I cannot seem to find any good answer to my problem relating subdomains.

This application allows for different clients to register themselves and get their own "environment" inside the application.

E.g. if client1 registers himself, his environment will be at https://main.application.com/v/client1

Now, as you can see, this is quite ugly. I want him to be able to go to https://client1.application.com/ and in the background it would show him https://main.application.com/v/client1. I've read this is possible with apache rewrite.

My case is a little bit more complex than a simple rewrite, I'm guessing. What I'm trying to achieve is this:

User goes to | Has to redirect to

client1.application.com | main.application.com/v/client1

client1.application.com/register | main.application.com/v/client1/register

client1.application.com/dashboard | main.application.com/dashboard

client1.application.com/... | main.application.com/...

As you can see, the only time I want to redirect with the /v/client1 appended to my domain, is when somebody is trying to register or trying to reach the login page for their environment. In all other scenarios, I just want to take what's behind the URL and append it to main.application.com (which is where the main app runs). I also don't want the users to notice the redirect, but that the URL in the address bar stays the same.

I've tried to come up with a bit of pseudocode that explains what I want to do:

If subdomain.application.com/ or subdomain.application.com/register
--> take subdomain and paste it like this: 
main.application.com/v/SUBDOMAIN/ or main.application.com/v/SUBDOMAIN/register
Else
--> Redirect to main.application.com/URL
    e.g. client1.application.com/dashboard --> main.application.com/dashboard

But I'm completely lost on how I should write it with a Rewrite.

Has anybody got experience in this matter that would be able to help me out with those rewrites here? I'm new to this and I cannot find documentation for my specific case.


Solution

  • Assuming that all requests to those host names ("sub domains") are handled by the same http host (by means of a ServerAlias or simply using the default fallback host) this should be pretty straight forward...

    1. do not rewrite any requests directly to example.com or www.example.com
    2. rewrite requests to other hosts that do not specify any path
    3. rewrite requests to other hosts that specify the /register path
    4. no treatment for other paths required if your http host uses the same file system layout (DOCUMENT_ROOT) for all these hosts ("sub domains")

    That leaves is with this:

    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
    RewriteCond %{HTTP_HOST} ^www\.example\.com$
    RewriteRule ^ - [END]
    
    RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$
    RewriteRule ^/?$ /v/%1 [END]
    
    RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$
    RewriteRule ^/?register/?$ /v/%1/register [END]
    

    In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.

    This implementation will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.

    And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).