Search code examples
apache.htaccesshttp-redirectmod-rewritesubdomain

redirect all subdomains to main domain (SSL) with subdomain as query parameter using .htaccess


Trying to do all of the following in the .htaccess file in the most elegant way:

  • redirect all non-SSL to SSL
  • redirect www to non-www
  • redirect all other subdomains to main domain with query string parameter as the subdomain. Ignore any other info in the URL (302 redirect). For example: http(s)://subdomain.example.com(/or/any/other/folder/or_file.html) -> https://example.com/results.php?q=subdomain
  • redirect all main domain 404 to main domain with query string using only the first folder or filename as the parameter. for example: http(s)://example.com/does/not/exist/file.html -> https://example.com/results.php?q=does

Here is what I have so far and everything works except for the subdomain redirect and the SSL redirect doesn't always work with non-SSL URLs. Not sure about the order of things or if there is a way to combine some of these.

Options -Indexes
RewriteEngine On
# this rewrites all non-SSL www to main domain (SSL)
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

#redirect all 404 to query string
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/? /results.php?q=$1 [R=302,L,NC]

IMPORTANT: everything needs to be a redirect and not a rewrite.


Solution

  • and the SSL redirect doesn't always work with non-SSL URLs.

    Because you don't have a specific non-SSL (HTTP) to SSL (HTTPS) redirect, only a www to non-www redirect that also redirects to HTTPS.

    You can do it like this:

    Options -Indexes
    
    RewriteEngine On
    
    # Redirect all 404 (for www or main domain) to query string + main domain
    RewriteCond %{HTTP_HOST} ^(?:www\.)?(example\.com) [NC]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^/]+) https://%1/results.php?q=$1 [R=302,L]
    
    # Redirect www to main domain (+ HTTPS)
    RewriteCond %{HTTP_HOST} ^www\.(.+?)\.?$ [NC]
    RewriteRule (.*) https://%1/$1 [R=301,L]
    
    # Redirect subdomains to main domain and query string
    RewriteCond %{HTTP_HOST} ^([^.]+)\.(example\.com)
    RewriteRule ^ https://%2/results.php?q=%1 [R=302,L]
    
    # Redirect HTTP to HTTPS (remaining URLs) - must already be at main domain
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    

    I've arranged/constructed the rules in order to minimise the number of possible redirects. There is only ever at most 1 redirect.

    The redirect from HTTP to HTTPS (the last rule) in which we are testing against the HTTPS server variable assumes the SSL cert is installed on your application server and you have a relatively standard implementation.

    You could make the rules entirely generic and remove the reliance on example.com (to determine what is a subdomain etc) by assuming the domain is always of the form <domain>.<tld> for instance (or of a known subset of TLDs perhaps).

    Just an observation... seems a little odd that you would redirect both subdomains and the first path segment of non-existent files/directories to the same URL format?