Trying to do all of the following in the .htaccess
file in the most elegant way:
http(s)://subdomain.example.com(/or/any/other/folder/or_file.html)
-> https://example.com/results.php?q=subdomain
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.
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?