Forum Moderators: phranque
RewriteEngine on
# no-www level b compliance
# RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
# RewriteRule ^(.*)$ http://%1/$1 [R=301,L]# Custom no-www from all domains (to comply with no-www.org)
RewriteCond %{HTTP_HOST} ^(www\.)+(.+)$ [NC]
RewriteRule ^(.*)$ http://%2/$1 [R=301,L]
# Catch-all script for user redirects
RewriteCond %{HTTP_HOST} ^(^.*)\.inforumal.com$
RewriteRule ^(.*)$ /home/impro/public_html/forums/user_redirect.php [L]
There are two ways to do this: You can make a rule that 'lists' each subdomain-subdirectory, but this can be a maintenance nightmare. Or alternatively (and I think, better), you can 'tag' your subdomain-subdirectories, and then detect that 'tag' and redirect any client request for URL-paths starting with that tag.
For example,
1) Rewrite <subdomain>.example.com/<path-to-resource> to /sd_<subdomain>/<path-to-resource> (The 'tag' is "sd_")
2) Redirect direct client requests for <anything>.example.com/sd_<subdomain>/<path-to-resource> to <subdomain>.example.com/<path-to-resource>
and of course, you'll also want to preserve any query strings appended to those URL-paths.
The trick is in the phrasing "direct client requests only" above. By detecting and redirecting *only* direct client requests for the subdomain-subdirectories, you prevent the two rules from interacting and causing an 'infinite' rewrite-redirect loop. You can use the variable %{THE_REQUEST} in a RewriteCond to implement this.
The variable %{THE_REQUEST} contains the entire client request line, as shown in your raw server access log file, for example:
GET /sd_subdomain/some-directory-path/some-page.php?query=foo HTTP/1.1
Jim
including query strings. It should be 'invalid' to get to subdomains content through the folder. I cannot get:
RewriteRule /subdomain http://subdomain.domain.com/ [R=301]
To work. Any ideas why this wouldn't work? I only want to do this for one particular subdomain.
I think this is what I understand:
jdMorgan's solution was either:
a) redirect the subdomain to a new URL and make sure the document root is the same for ANY subdomain subdomain.example.com/ to subdomain.example.com/subdomain
(this is how I understood it)
or
b) redirect when the server asks for the subdomain folder directly and make sure they get sent to the subdomain
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule ^(.*)$ http://subdomain.example.com/ [L,R=301]
It checks to see if the user is accessing the folder from the domain or the subdomain. It sends a moved permanently.
# Ensure that user is on subdomain
RewriteRule ^subdomain(/?)$ http://subdomain.example.com/ [L,R=301]
This forces people that try get to the domain.com/subdomain onto the subdomain
Outcome:
Which is just what I wanted. Thank you jdMorgan and g1. I may experiment with forcing error pages from the example.com/subdomain just to prevent them being used.
Hopefully this helps someone else.
Update: pasted wrong line
Just for reference, the following rules are an example one of the "standard" implementations for the case where all domains and subdomains are mapped to the same DocumentRoot ("home page") directory. That is, where the subdomains are not set up as "add-on domains" using a control panel, but rather are mapped (using DNS only) to the same directory as the "main domain" on a server having a unique IP address. This illustrates the solution I outlined previously:
# Externally redirect direct client requests for subdomain-subdirectory URLs
# to subdomain URLs without subdomain-subdirectory URL-path
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /sd_[^/]+/
RewriteRule ^sd_([^/]+)/(.*)$ http://$1.example.com/$2 [R=301,L]
#
# Externally redirect non-canonical domains and subdomains
# (extra or missing "www") to canonical domain and subdomains
RewriteCond www>%{HTTP_HOST} ^(www)>example\.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.([^.]+)\.example\.com [NC,OR]
RewriteCond %{HTTP_HOST} ^([^.]+)\.www\.example\.com [NC,OR]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com\. [NC,OR]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com\.?:[0-9]+ [NC]
RewriteRule ^(.*)$ http://%1.example.com/$1 [R=301,L]
#
# Internally rewrite all but "main domain" URL-requests to
# subdomain subdirectory filepaths unless previously done
RewriteCond $1 !^sd_
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com
RewriteRule ^(.*)$ /sd_%1/$1 [L]
Additionally, the code will redirect if the requested hostname is in FQDN format, if it has a port number appended to it, or if it contains an "extra" www either before or after the "real" subdomain name. Since these are the most common non-canonical requests, this fixes and prevents most duplicate-content problems related to the requested hostname.
Jim