Forum Moderators: phranque

Message Too Old, No Replies

Virtual SubDomain. mod rewrite code doesn't work.

.htaccess mod_rewrite

         

toeh

2:37 pm on May 26, 2008 (gmt 0)

10+ Year Member



Hello all,
I tried to use mod_rewrite to create virtual subdomain, but it doesn't work.
I would like to replace http://example.com/man with subdomain [man.example.com...]
Here is my .htaccess file code.

-----------------------------------------------------------------------------------
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.[^.]+\.example\.com$
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
RewriteRule ^www\.([^.]+)\.example\.com(.*) $1$2
-----------------------------------------------------------------------------------

When I go to [man.example.com,...] error appear

The requested URL could not be retrieved

--------------------------------------------------------------------------------

While trying to retrieve the URL: [man.example.com...]

The following error was encountered:

Unable to determine IP address from host name for man.example.com
The dnsserver returned:

Name Error: The domain name does not exist.
This means that:

The cache was not able to resolve the hostname presented in the URL.
Check if the address is correct.

Thank you for all help.
:)

[edited by: jdMorgan at 4:04 pm (utc) on May 26, 2008]
[edit reason] No URLs, please. Use example.com [/edit]

jdMorgan

4:40 pm on May 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There are two problems here. The first is that according to the error message you report, you have not defined your subdomain in your DNS zone file. So the DNS system cannot translate your subdomain name to the IP address of your server, making your subdomain unreachable. As a result, the code on your server does not matter; The subdomain requests never even reach your server.

The second problem is that your code does not match the description of your goal. Further, it seems to have been taken from an example intended for use in a server configuration file (e.g. httpd.conf) rather than for use in .htaccess. As such, it will require modification to prevent recursion in .htaccess.

So, you'll need to add an "A record" to your DNS zone file to point the "man" subdomain to your server's IP address. Or you can add a "wild-card" A record to point *all* subdomains to your server. Note that this will only work in two cases: Either your hosting account must assign your domain a unique IP address, or your host must provide some way for you to add subdomains or "add-on domains" to your account. In other words, either your server must be an IP-address-based server, or your host must provide you with a way to add domains or subdomains to the server's list of recognized domains/subdomains to be associated with your hosting account.

If you are on a name-based shared server, as opposed to an IP-address-based server, then you may not need to use mod_rewrite or .htaccess at all. Many "control panels" can be used to "create" an add-on domain or subdomain, and to point that add-on domain or subdomain to a subdirectory in your account space.

If you are on an IP-address-based server, then the following code may work better than what you started with:


RewriteEngine on
RewriteCond %{HTTP_HOST} ^man\.example\.com
RewriteCond $1 !^man/
RewriteRule (.*) /man/$1 [L]

The new second RewriteCond prevents recursion, i.e. it prevents an "infinite" rewriting loop.

That's the simple case, where you have only one subdomain. If you have more, you'll need to somehow 'tag' the subdirectories used to store files for subdomains, so that mod_rewrite can easily detect requests for them and prevent recursion. So, you might 'tag' the filepaths by prepending "sd_" to directories used to store subdomain files:


RewriteEngine on
#
RewriteCond %{HTTP_HOST} !^www\.example\.com
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com
RewriteCond $1 !^sd_
RewriteRule (.*) /sd_%1/$1 [L]

Having implemented either of those rules, you may want to add another one to prevent direct client access to the subdirectory. That is, to redirect requests for example.com/man to man.example.com, in order to prevent people "fishing around" in the filesystem, and to prevent duplicate-content problems in search engine results.

For the simple first rule above:


RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /man/
RewriteRule ^man/(.*)$ http://man.example.com/$1 [R=301,L]

or for the second one that supports multiple subdomains:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /sd_[^/]+/
RewriteRule ^sd([^/]+)/(.*)$ http://$1.example.com/$2 [R=301,L]

Here, we've used %{THE_REQUEST} to differentiate between the subdomain-subdirectory being requested directly by the client (browser or search engine robot) and requests due to the internal rewrite rule above. Without this test, we would again have a recursion or "looping" problem; We'd rewrite to the subdomain-subdirectory, and then redirect right back again!

Note that in all cases, "sd_" is an arbitrary string; You can use whatever you like as long as it is valid according to the HTTP specification, and as long as it is sufficiently-unique to avoid confusing it with any other filepath that might exist (now or later) on your server.

Jim