Forum Moderators: phranque
Say I have the following existing subdomains: folder1.mydomain.com, folder2.mydomain.com and folder3.mydomain.com which translate to mydomain.com/folder1, mydomain.com/folder2 and mydomain.com/folder3. I also have 2 folders at mydomain.com/folder4 and mydomain.com/folder5, no corresponding subdomains.
How can I
1. redirect mydomain.com and www.mydomain.com (and -- this is a good-to-have but less important -- all non-existing subdomains say blah.mydomain.com) to folder1.mydomain.com?
2. make it such that for mydomain.com and www.mydomain.com, the URL in the location bar does not change to folder1.mydomain.com?
3. make it such that I can still access folders 4 and 5 at mydomain.com/folder4 and mydomain.com/folder5 (ie these don't get redirected as well to folder1.mydomain.com)?
I have tried:
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com$ [NC]
RewriteRule .* [folder1.mydomain.com...] [L]
but for one thing the URL in the location bar gets changed to folder1.mydomain.com and for another mydomain.com/folder4 gets redirected to folder1.mydomain.com as well.
Please help, thanks!
Welcome to WebmasterWorld [webmasterworld.com]!
While we usually try to avoid taking on "projects" for individuals here on WebmasterWorld, and prefer to deal with concepts, it just so happens that your problem can be used to illustrate a concept in mod_rewrite - that of matching a pattern and then stopping the rewrite engine to provide an exclusion mechanism. In the following code, this construct is used to avoid rewriting URLs containing /folder4 or /folder5.
From what you posted, it was not clear what you wanted to do with folder2, and folder3 as requests. They were mentioned at the top, but were not mentioned again as requested URLs. I assume you want to map those subdomains to same-named subdirectories, and that is what the following code does.
The following code does what I think you want it to do. If it doesn't work, then make sure you understand it in terms of the included comments before making any modifications.
# If mydomain.com/folder4 or mydomain.com/folder5 is requested, stop rewriting and
# serve the requested file. (These folders have no corresponding subdomains.)
RewriteCond %{HTTP_HOST} ^mydomain\.com [NC]
RewriteCond %{REQUEST_URI} ^/(folder4¦folder5) [NC]
RewriteRule - [L]
#
# Take care of requests for "www.mydomain" and directly-entered requests for "folder1.mydomain.com"
# by externally (visibly) redirecting to mydomain.com, and stop rewriting. The browser will then
# issue a new request for mydomain.com, and all these rules will be processed again as a result.
RewriteCond %{HTTP_HOST} ^(www¦folder1)\.mydomain\.com [NC]
RewriteRule .* http://mydomain.com/$1 [R=301,L]
#
# Internally redirect folder2-3.mydomain.com to mydomain.com/folder2-3, and stop rewriting.
# Note that folder1.mydomain.com is taken care of by Rule #2 above and the last Rule below.
RewriteCond %{HTTP_HOST} ^folder2\.mydomain\.com [NC]
RewriteCond %{REQUEST_URI} !^/folder2 [NC]
RewriteRule .* /folder2/.* [L]
RewriteCond %{HTTP_HOST} ^folder3\.mydomain\.com [NC]
RewriteCond %{REQUEST_URI} !^/folder3 [NC]
RewriteRule .* /folder3/.* [L]
#
# For all other subdomains, internally redirect to subdirectory folder1 and stop rewriting.
# (This will internally redirect "mydomain.com" and all undefined subdomains.)
RewriteCond %{REQUEST_URI} !^/folder1 [NC]
RewriteRule .* /folder1/$1 [L]
This code comes with no warranties, expressed or implied. Use at your own risk. Availability of support may be limited. Please see the reference material cited below. :)
The code above is designed for use in a .htaccess context. For use in httpd.conf, changes to the treatment of leading slashes in pathnames will be required.
Rule order and the use of the [L] flag are critical.
External redirects terminate the current HTTP request and return a new URL with a 301-Moved Permanently response code to the browser. The browser will then issue a new HTTP request with the specified new URL, and your rewrite rules will be processed again for this new request. This external redirect is visible in the browser address bar.
Internal redirects are not visible to the user; they can be viewed as serving content from an alternate local filepath only. They do not cause a new HTTP request and do not cause the rewrite rules to be reprocessed.
RewriteRule - [L] does nothing except to stop rewriting. This has the effect of saying "leave these URLs alone." The requested content will be served.
You didn't really say what you wanted to do with subdomain names folder2, and folder3, so I assumed you just wanted to map those subdomain names to corresponding subdirectory names. Note that folder1 is handled in two steps; If it is requested as folder1.mydomain.com, then folder1 is stripped off and an external redirect is done in Rule #2 to mydomain.com. When this new request comes back from the browser, then the last rule is invoked, internally redirecting mydomain.com and all undefined subdomains to mydomain.com/folder1.
The RewriteCond %{REQUEST_URI} lines for the last three rules may not be needed. I included them to stop some strange looping problems that can happen in some server setups, especially with scripts that also do redirection. You can try commenting them out to see if anything goes wrong. If not, you can delete them or just leave them commented out in case you need them later.
In the code above, the broken vertical pipe "¦" characters must be replaced with solid vertical pipe characters from your keyboard; posting on WebmasterWorld changes solid vertical pipes to broken vertical pipes, and mod_rewrite requires the solid ones.
This Introduction to mod_rewrite [webmasterworld.com] thread contains good information, and links to the Apache mod_rewrite documentation and a Regular-Expressions tutorial that may help to clarify the code above.
HTH,
Jim
Regarding your code, actually the redirecting of the subdomains to their respective folders is taken care of by my host -- I didn't have to do anything. My problem was just the forwarding of mydomain.com and www.mydomain.com internally to folder1.mydomain.com, but NOT forwarding www.mydomain.com/folder4 for example.
Now I've modified my problem somewhat -- I'm trying to get:
1. (www.)mydomain.com/folders_with_corresponding_subdomains redirected to folders_with_corresponding_subdomains.mydomain.com
-- this one not a problem, I have:
# Rule A
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com [NC]
RewriteCond %{REQUEST_URI} ^/(folder1¦folder2¦folderN) [NC]
RewriteRule .* [%1.mydomain.com...] [R=301,L]
which seems to be working fine.
2. (www.)mydomain.com/folders_without_corresponding_subdomains to be served as requested
-- which is not a problem until we come to #3 and #4 as follows:
3. www.mydomain.com and mainfolder.mydomain.com and (www.)mydomain.com/mainfolder to be externally redirected to mydomain.com
4. mydomain.com to be internally redirected to mydomain.com/mainfolder
For #2-4, I have:
# Rule B
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com [NC]
RewriteCond %{REQUEST_URI}!^/mainfolder [NC]
RewriteRule .* - [L]
# Rule C
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com [NC]
RewriteCond %{REQUEST_URI} ^/mainfolder [NC]
RewriteRule .* [mydomain.com...] [R=301,L]
# Rule D
RewriteCond %{HTTP_HOST} ^(www¦mainfolder)\.mydomain\.com [NC]
RewriteRule .* [mydomain.com...] [R=301,L]
# Rule E
RewriteCond %{HTTP_HOST} ^mydomain\.com [NC]
RewriteRule .* /mainfolder/$1 [L]
But Rule E doesn't get processed 'cos of Rule B. I'm thinking the solution may simply lie in modifying the condition to Rule B, to also exclude an "empty" REQUEST_URI (so that mydomain.com and www.mydomain.com *doesn't* get served as requested but instead gets taken care of by Rule E, thus internally redirected to mainfolder). But I'm not sure of the syntax to check for the "empty" REQUEST_URI... Have tried RewriteCond %{REQUEST_URI}!^/$ [NC] but it doesn't seem to work. If anyone can help me out with the syntax here (or point out any errors I may have overlooked), I'd be most grateful. I'm also thinking that once I have the right syntax, it may be possible to combine Rules C and D.
Looking forward to learning more from everyone here.