Forum Moderators: phranque
I've just started monkeying with .htaccess and mod_rewrite. It is very, very powerful, but I'm having trouble understanding how to do this. I'm fairly ok with regular expressions, but for some reason the rules I have written don't work. I'm getting lots of 403 Forbidden errors, or else the subdomains point back to the main site.
Let me first describe what I am trying to do. I have example.net as my main site. I have some access to the DNS records, so I have www and ftp pointing to the main site. I also added in two names that I want to use for subdomains. Thus:
(www.) example.net points to /www/example.net/webapps/ROOT
examplekh.example.net should point to /www/example.net/webapps/ROOT/HTML/Examplekh (for now, later on this will point to just /.../examplekh)
golddragon.example.net should point to /www/example.net/webapps/ROOT/HTML/GoldDragon (for now, later on this will point to just /.../golddragon)
Now, I read the forum charter, I read the references, and created this in .htaccess as I can't touch httpd.conf:
RewriteEngine On
Options +FollowSymLinks
RewriteBase /
RewriteCond %{HTTP_HOST} ^examplekh\.example\.net$
RewriteCond %{REQUEST_URI} !^examplekh/$
RewriteRule ^/(.*)$ HTML/Examplekh/$1 [L]
RewriteCond %{HTTP_HOST} ^golddragon\.example\.net$
RewriteCond %{REQUEST_URI} !^golddragon/$
RewriteRule ^/(.*)$ /HTML/GoldDragon/$1 [L]
[edited by: jdMorgan at 8:48 pm (utc) on Sep. 29, 2004]
[edit reason] Removed specifics per TOS [/edit]
Welcome to WebmasterWorld!
It appears that the main problem is that you end-anchored your REQUEST_URI patterns, thus requiring an exact match. In addition, you should use the [NC] (no-case) flag if you really want to use mixed-case subdirectory names. Finally, the URL "seen" by RewriteRule in .htaccess context does not start with a slash, so a leading slash should not be used in the pattern:
RewriteEngine On
Options +FollowSymLinks
RewriteBase /
RewriteCond %{HTTP_HOST} ^examplekh\.example\.net
RewriteCond %{REQUEST_URI} !^examplekh/ [NC]
RewriteRule ^(.*)$ /HTML/Examplekh/$1 [L]
#
RewriteCond %{HTTP_HOST} ^golddragon\.example\.net
RewriteCond %{REQUEST_URI} !^golddragon/ [NC]
RewriteRule ^(.*)$ /HTML/GoldDragon/$1 [L]
You might want to think about how likely it is that you will add additional subdomains in the future. The method above requires a new rule-set for each new subdomain, so this may become burdensome or inefficient. If it is likely that you will add numerous subdomains in the future, check out msg #6 in this thread on rewriting arbitrary subdomains to subdirectories [webmasterworld.com].
Jim
Now, then, I took your advice. I reviewed that message #6. I even went and reread a few references on regular expressions.
I couldn't understand why I would want arbitrary domain mapping, until I realized that I would also have to have a DNS entry anyway, which means that until a.example.com is mapped in DNS, the request won't even GET to Apache.
That is all fine. I therefore changed my .htaccess to match that in the article. For example purposes, this is the setup:
www.example.net is the main domain
a.example.net -> www.example.net/a
b.example.net -> www.example.net/b
In my /www/example.net/webapps/ROOT I created an a directory, a b directory, and index.html files in both of them, to indicate that I indeed am serving properly. DNS entries for a.example.net and b.example.net are in place.
Neither the script in message 6, nor my slightly modified version below, which ONLY adds the RewriteEngine and Options tag, works. a and b both end up either pointing to example.net's root dir, or else I get Internal Server errors for anything other than a known page. Trying [a.example.net...] causes an error; [a.example.net...] works properly.
I have spent several hours trying to verify exactly what this rewrite is doing, and thus far can't find any flaws. Can you suggest anything here?
***
RewriteEngine On
Options +FollowSymLinks
# Skip rewrite if no hostname or if subdomain is www
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST}!^www\. [NC]
# Extract (required) subdomain (%1), and first path
# element (%3), discard port number if present (%2)
RewriteCond %{HTTP_HOST}<>%{REQUEST_URI} ^([^.]+)\.example\.net(:80)?<>/([^/]*) [NC]
# Rewrite only when subdomain not equal to first path
# element (prevents mod_rewrite recursion)
RewriteCond %1<>%3!^(.*)<>\1$ [NC]
# Rewrite to /subdomain/path
RewriteRule ^(.*) /%1/$1 [L]
I even tried this script which I found from one of your other postings.
From [webmasterworld.com...]
# Redirect 'a' subdomain to subdirectory /a/
RewriteCond %{HTTP_HOST} ^a\.example\.net
rewriterule (.*) /a/$1 [L]
This doesn't work either. a.example.net (see above) doesn't properly load example.net/a/index.html; it loads example.net/index.html
I'm starting to convince myself this is a configuration error somewhere... though it is getting way out of my league now. Any help you can shed on this us appreciated.
A few things that can stop mod_rewrite from working are:
UseCanonicalName on
Options +MultiViews
no AllowOverride FileInfo
no AllowOverride Options
and of course that assumes that mod_rewrite is loaded on your server in the first place.
Try a very simple rewrite, like rewriting a nonexistent filename to your home page. Then request the nonexistent page with your browser, and you should get the contents of your homepage. That will answer the question of whether mod_rewrite is working:
RewriteRule ^silly\.html$ /path_to_homepage.html [L]
Before I ever posted I tried the simple example. foo.html existed, bar.html existed, foo was rewritten to bar and I never saw foo.html again. :)
As for your list, I have started walking through it. I know that these are defined in httpd.conf:
UseCanonicalName On - in the main httpd.conf, which calls a whole bunch of other .conf files, one for each site.
And the directory is defined as:
DocumentRoot /www/example.net/webapps/ROOT
<Directory /www/example.net/webapps/ROOT>
Allow from All
AllowOverride All
Order allow,deny
Options Indexes IncludesNOEXEC
</Directory>
Thus far it seems like the AllowOverride is ok, the Options is ok, but UseCanonicalName is the issue?
I'll see about adding UseCanonicalName Off in .htaccess