views:

122

answers:

3

I want to have my primary domain be hosted from a subdirectory (have completed this step somewhat), i.e. when someone types in www.example.com/news behind the scenes it will go to www.example.com/subdirectory/news but will still show up as www.example.com/news.

I have used the following bluehost code to accomplish this:

RewriteEngine on

RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/subdirectory/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /subdirectory/$1

RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ subdirectory/index.php [L]

This code works if I type in www.example.com/news/ (notice the trailing slash) but does NOT work if I just type in www.example.com/news (without the slash). Any ideas why?

Thank you.

A: 

Not really an answer to your question, but wouldn't it be easier to

  • Change your DocumentRoot to the public dir, or if you can't do that (e.g. on a shared host)...
  • Put the public files in your document root (public_html or whatever it's called) and the application files somewhere outside it (or if you cannot go above the document root, inside it but protected against web access with a Deny from all
Bart van Heukelom
Yeah, I think that second option is what I will have to do if I can't get this to work, thanks for the tip. I'll give it another day or two of trying things and implement that if defeated :)
Robert
+1  A: 

I think the problem is that after Apache rewrites /news to /subdirectory/news it then finds itself with a request matching a directory on the filesystem, which does NOT end in a trailing slash. So it issues a redirect to a new url including the trailing slash.

The thing is, we do actually want the traling slash to be added to preserve the canonical url (otherwise we end up with /news and /news/ leading to the same place - not good for relative links, SEO etc.), just not quite in the way apache is doing it. So we have to do it ourselves, by adding the following:

RewriteCond %{REQUEST_URI} ^/subdirectory/.*[^/]$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^subdirectory/(.*)$ /$1/ [L,R=301]

The conditions of this rule will match any requests that begin with 'subdirectory', DO match a directory on the fielsysem but do NOT end with a trainling slash. (e.g. '/subdirectory/news'). The rewriterule then issues a permanent redirect to the same path, but ending in a slash and with 'subdiretcory' stripped out (e.g. '/news/').

The client will then issue a request for '/news/', apache will rewrite this to /subdirectory/news/ and will not issue a redirect becuase it ends with a slash.

Quickly tested this out and it seems to do the trick.

andrewmabbott
A: 

andrewmabbott is right, and to fix it you need to use a ProxyPassReverse. This will rewrite all redirects to use the correct address.

The easiest way to do it would be something like:

ProxyPassReverse /subdirectory http://www.example.com/

However bluehost might have disabled mod_proxy, in which case this won't work.

Singletoned