View Full Version : Primary domain in subfolder partially broken
astfgl
04-12-2008, 07:23 PM
I've followed the KB article(1) which shows how to put the primary domain in a subdirectory, and I've run into several problems.
The first bug I've found is that a URL for a directory with no trailing slash triggers a 301 redirect. Please correct me if I'm wrong, but my .htaccess has no 301 redirect, so it must be done in the global server apache configuration. The problem is that the redirect is done incorrectly, and the URL has the subdirectory added on when sent back to the browser:
GET http://www.rustic-engines.com/Media --> 301 Moved Permanently
GET http://www.rustic-engines.com/re/Media/ --> 200 OK
From then on, all URLs have the subdirectory visible.
The second problem is that the apache index modules have an incorrect absolute path for their "Parent Directory" link and if it's clicked on, the subdirectory is visible from then on.
The indexer problem can be worked around, but I can't find any way of fixing the trailing slash problem. I've submitted a ticket to bluehost, but they closed it saying that they don't support the KB article and I probably edited it wrong anyway.
Can anyone think up another .htacces rule to fix this?
# Bluehost.com
# .htaccess main domain to subfolder redirect
# Copy and paste the following code into the .htaccess file
# in the public_html folder of your hosting account
# make the changes to the file according to the instructions.
# Do not change this line.
RewriteEngine on
# Change yourdomain.com to be your main domain.
RewriteCond %{HTTP_HOST} ^(www\.)?rustic-engines\.com$
# Change 'subfolder' to be the folder you will use for your main domain.
RewriteCond %{REQUEST_URI} !^/re/
# Don't change this line.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Change 'subfolder' to be the folder you will use for your main domain.
RewriteRule ^(.*)$ /re/$1
# Change yourdomain.com to be your main domain again.
# Change 'subfolder' to be the folder you will use for your main domain
# followed by / then the main file for your site, index.php, index.html, etc.
RewriteCond %{HTTP_HOST} ^(www\.)?rustic-engines\.com$
RewriteRule ^(/)?$ re/index.php [L]
(1) http://helpdesk.bluehost.com/kb/index.php?x=&mod_id=2&id=394
astfgl
04-12-2008, 08:15 PM
OK more information. I tried disabling mod_dir with an "Options -Indexes" in my htaccess, as one of it's tasks is to add trailing slashes. The module is disabled, as I no longer get a directory listing, but the 301 redirect is still happening.
Bluehost much have a per-virtual-server or global redirect in their configuration. Is it possible to get them to remove it for my server?
charlesp
04-12-2008, 10:51 PM
The only way to find out is to ask them.:D
astfgl
04-13-2008, 02:37 PM
I opened another ticket, and the new level 1 person suggested it was a problem with my htaccess file and he's have a look at it. He then changed the subdirectory name(which I'd already tried), said it was fixed and closed the ticket.
It's not fixed, it's exactly the same. So, I'm off to open ticket three.
Does anyone know how to escalate to level two?
Early Out
04-13-2008, 03:10 PM
Don't submit tickets. Use Live Chat.
astfgl
04-14-2008, 05:58 PM
Jamie from support worked on this problem for a while, then called in others to help. They finally admitted defeat, but confirmed that there's no extra apache configuration which is causing the problem.
With that information, I started hacking my way through the .htaccess file myself and re-wrote most of it, plus added a couple of helper scripts. mod_dir is the main problem, and has to be mostly disabled and it's functionality replaced with ErrorDocuments.
Here's the .htaccess. Replace domain.name and subdirectory as appropriate. Note that the backslashes in the RewriteCond lines escape the period to match a period rather than it being interpreted as a wildcard.
/.htaccess
# Turn off mod_dir generated directory listings.
Options -Indexes
# Turn off mod_dir generated trailing slash redirects.
DirectorySlash Off
# Default index files. NOTE: Does not work for /. See below.
DirectoryIndex index.html index.php
# Custom errors to hide primary domain subdirectory.
ErrorDocument 403 /403.php
ErrorDocument 404 /404.php
#Turn on the rewrite engine.
RewriteEngine On
# Redirect from domain.name to www.domain.name first.
RewriteCond %{HTTP_HOST} ^domain\.name$ [NC]
RewriteRule ^(.*)$ http://www.domain.name/$1 [R=301,L]
# If the URL is for primary domain, move to it's subdirectory.
RewriteCond %{HTTP_HOST} ^www\.domain\.name$
RewriteCond %{REQUEST_URI} !^/www\.domain\.name/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /subdirectory/$1
# Add a trailing slash onto directories so the DirectoryIndex search works.
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME} !/$
RewriteRule ^(.*)$ $1/ [L]
# ...except for /. This one we have to hard code to a specific file.
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^ index.html
#End.
This file has:
* Disabled most of mod_dir, except for index files
* Set up custom error pages
* Redirected(301) domain.name to www.domain.name
* Moved to the subdirectory
* Added a trailing slash to directories
* Forced the index file in the root directory
Any built in error responses will now show the subdirectory as well. The ErrorDocument lines allow a short script to fix up that path:
/404.php
<?php
header("Status: 404 Not Found");
?>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL <?php echo str_replace('/subdirectory', '', $_SERVER["REDIRECT_URL"]); ?> was not found on this server.</p>
<p>Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.</p>
<hr>
<address>Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8g DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 Server at www.rustic-engines.com Port 80</address>
</body></html>
Since it's disabled the directory indexing, any URL pointing to a directory without an index file will generate a 403 Forbidden reponse. We can decide to show or not show a directory listing by having two different custom 403 pages. The default 403 page in the root .htaccess is the same as the custom 404 page, but with the 403 text:
/403.php
<?php
header("Status: 403 Forbidden");
?>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access <?php echo str_replace('/subdirectory', '', $_SERVER["REDIRECT_URL"]); ?> on this server.</p>
<p>Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.</p>
<hr>
<address>Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8g DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 Server at www.rustic-engines.com Port 80</address>
</body></html>
For those directories where a listing is wanted, a .htaccess file is created with a different custom error page. Note that it will still respond to a Forbidden file request with the correct page, but directory listings are generated. Dot-files are not included in the listing, and the hiding of other files is left as an exercise to the reader.
.htaccess
ErrorDocument 403 /403-dir.php
/403-dir.php
<?php
if (is_dir($_SERVER["DOCUMENT_ROOT"].$_SERVER["REDIRECT_URL"])) {
$basedir = rtrim(str_replace('/subdirectory', '', $_SERVER["REDIRECT_URL"]), '/');
header("Status: 200 OK");
echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">";
echo "<html>\n <head>\n <title>";
echo "Index of $basedir";
echo " </head>\n <body>\n";
echo "<h1>Index of $basedir</h1>\n<ul>";
$dh = opendir($_SERVER["DOCUMENT_ROOT"].$_SERVER["REDIRECT_URL"]);
while (($file = readdir($dh)) !== false) {
if ($file == '..') {
$pdir = implode('/', explode('/', $basedir, -1));
echo "<li><a href=\"$pdir/\"> Parent Directory</a></li>\n";
continue;
}
if (strncmp($file, '.', 1) == 0) {
continue;
}
echo "<li><a href=\"$basedir/$file\"> $file</a></li>\n";
}
closedir($dh);
echo "</ul>\n</body></html>\n";
exit;
}
header("Status: 403 Forbidden");
?>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access <?php echo str_replace('/subdirectory', '', $_SERVER["REDIRECT_URL"]); ?> on this server.</p>
<p>Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.</p>
<hr>
<address>Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8g DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 Server at www.rustic-engines.com Port 80</address>
</body></html>
It's probably not compatible with other URL rewriting systems used in many web applications, but I'm not using any on this domain.
If anyone finds an bugs in this system, please let me know the fixes.
Cheers, astfgl.
cnymike
05-02-2008, 10:33 PM
I've spent most of the evening battling tech support over this issue of mapping my account domain to a subdirectory of my public_html
Why this is so difficult to accomplish I do not know. I have accounts at other hosts, pair.com for instance, where this is quickly done without the use of .htaccess games. I simply map the domain to a subdirectory in my Account Control Center... done deal.
In any case the BlueHost knowledgebase article solution regarding this topic did not work for me. Support offered this solution...an .htaccess in public_html that says
DirectoryIndex "myDomain", and an .htaccess file in the subdirectory public_html/myDomain that says "DirectoryIndex index.php"
This does not seem like a reliable solution to me. Any comments?
Powered by vBulletin® Version 4.1.10 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.