apachemod-rewritemod-vhost-alias

Subdomain to subfolder in Apache


I am looking for Apache configuration that would allow for the following:

I would be grateful for any solution, especially if there was no mod_rewrite involved (using mod_vhost_alias).

Note: There are some obvious solutions using mod_vhost_alias, but they either work for domain.com or sub.domain.com, none of them seems to cover both cases.

Have a nice day!


Solution

  • Point *.domain.com to your document root (/%docRoot%/). You'll need to do this in a vhost config. In that same vhost, add this:

    RewriteEngine On
    RewriteCond %{REQUEST_URI} !^/domain.com/
    RewriteCond %{HTTP_HOST} ^([^\.]+)\.domain\.com$ [NC]
    RewriteRule ^/(.*)$ /domain.com/%1/$1 [L]
    

    If you want to avoid pointing www.domain.com to /%docRoot%/domain.com/www, then add a condition to exclude it:

    RewriteEngine On
    RewriteCond %{REQUEST_URI} !^/domain.com/
    RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
    RewriteCond %{HTTP_HOST} ^([^\.]+)\.domain\.com$ [NC]
    RewriteRule ^/(.*)$ /domain.com/%1/$1 [L]
    

    EDIT:

    I assume I will still have to do this for every hosted domain (as the examples you've posted all refer to "domain.com"). Am I right?

    Yes, the above will only do the routing for domain.com, if you want to do this for all arbitrary domain.com, you'll need to do something a bit more tricky:

    RewriteEngine On
    # here, %1 = subdomain name, and %2 = domain name
    RewriteCond %{HTTP_HOST} ^([^\.]+)\.(.+)$ [NC]
    # make sure the request doesn't already start with the domain name/subdomain name
    RewriteCond %{REQUEST_URI}:%2/%1 !^/([^/]+/[^/]+)[^:]*:\1
    # rewrite
    RewriteRule ^/(.*)$ /%2/%1/$1 [L]
    

    The tricky thing here is the %{REQUEST_URI}:%2/%1 !^/([^/]+/[^/]+)[^:]*:\1 match. It posits the condition: %{REQUEST_URI}:domain.com/sub and makes sure the %{REQUEST_URI} doesn't start with the domain.com/sub (back refrenced from previous match using %2/%1) using the \1 back reference.

    With this, you setup your vhost to accept every domain (default vhost) and any subdomain/domain will get routed. Examples:


    EDIT2:

    Yes, I would very much like to get domain.com routed to /%docRoot%/domain.com/

    Try these:

    RewriteCond %{HTTP_HOST} ^(.+?)\.([^\.]+\.[^\.]+)$ [NC]
    RewriteCond %{REQUEST_URI}:%2/%1 !^/([^/]+/[^/]+)[^:]*:\1
    RewriteRule ^/?(.*)$ /%2/%1/$1 [L]
    
    RewriteCond %{HTTP_HOST} ^([^\.]+\.[^\.]+)$ [NC]
    RewriteCond %{REQUEST_URI}:%1 !^/([^/]+)[^:]*:\1
    RewriteRule ^/?(.*)$ /%1/$1 [L]
    

    Basically the same thing, except a few of the regex needs to be tweaked to separate what a domain.com is like vs sub.domain.com. If you want to redirect www.domain.com to domain.com, that needs to happen before these rules.