7

I have public and private projects on my webserver. I put everything what is public into the webserver root, and I have a private folder there which I can only reach from local network (set by .htaccess in there).

I want to simply put every private projects in the private folder and handle the requests automatically, but want the URLs look like they are served from webroot.
For example if there is private/project1 I want to use the URL http://example.com/project1 to serve that folder and don't want to change the URL.

This simple rewrite:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ private/$1           

works, but when I have a private/project2 with another .htaccess:

Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /project2/

<Files .*>
       Order Deny,Allow
       Deny From All
</Files>

# Allow asset folders through
RewriteRule ^(assets/.+) - [L]

# Protect files from being viewed
RewriteRule ^(uploads.+) - [F,L]


RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ index.php/$1 [L]

</IfModule>
Options -Indexes

then the static content will appear, but the links are broken. What should I modify to work ?

Also if I have a private/project3 and browse to http://example.com/project3/ there is no problem, but when I browse to http://example.com/project3 (without the trailing /) the URL will be visible as http://example.com/private/project3/ in the browser. Why ? How can I avoid that ?

kissgyorgy
  • 2,947
  • 2
  • 32
  • 54
  • 1
    Just change your HTTP DocumentRoot to the sub-directory. – Geoffrey Aug 09 '12 at 08:47
  • this is close. but how can I serve the public projects then ? (which are above `private` folder ? A simple `Alias /publicproject1 /home/www/publicproject1` works for some, but I have a Passenger application (redmine) which doesn't seem to work with Alias – kissgyorgy Aug 10 '12 at 05:20

3 Answers3

5

All you need in your case is mod_alias.

Then serve your private project like:

Alias /project3 /apache/htdocs/private/project3

And with .htaccess you will control access rights.

If you want to control it without restarting server, you can try to achieve this with following config, that can be placed in .htaccess file:

RewriteRule ^/(project1)$ /private/$1/index.html
RewriteRule ^/(project1/)(.*)$ /private/$1$2

index.html - any index file for your project. This way public part of URL's will be completly accessible, beside path's you are using for the private projects. You also can add RewriteCond to check IP and enable rewriting only for your local network.

Nagh
  • 1,757
  • 1
  • 14
  • 19
  • I have a ton of projects under private, and constantly adding new. How can I avoid writing a new alias to the apache.conf and restarting the server every time I add a new directory ? – kissgyorgy Aug 12 '12 at 00:34
2

Actually, looking over your question it looks like this is an issue with mod_dir interferring with the path pipeline. Specifically, DirectorySlash which is by default turned on, will 301 redirect the browser when it thinks the browser is requesting a directory and is missing the trailing slash. You can try turning DirectorySlash Off but there's a security warning associated with it:

Turning off the trailing slash redirect may result in an information disclosure. Consider a situation where mod_autoindex is active (Options +Indexes) and DirectoryIndex is set to a valid resource (say, index.html) and there's no other special handler defined for that URL. In this case a request with a trailing slash would show the index.html file. But a request without trailing slash would list the directory contents.

That may or may not be applicable to your setup. You can also try modifying your rewrite rule to account for a trailing slash:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/$ private/$1/     

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ private/$1/     

But I've had mixed results trying to get mod_rewrite and mod_dir to always play nicely with each other.

Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • "Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace." but I feel your solution is really close. any more idea ? – kissgyorgy Aug 12 '12 at 01:09
  • @Walkman weird that it would say that if the requested resource is supposed to be there. But I guess you can try adding a `RewriteCond %{REQUEST_URI} !^/private/` right before each of the `RewriteRule`'s. – Jon Lin Aug 12 '12 at 01:23
2

Wouldn't virtual domains be enough?

You could use a domain for private projects and another for public projects.

http://httpd.apache.org/docs/2.2/vhosts/examples.html

Edson Medina
  • 9,862
  • 3
  • 40
  • 51
  • 1
    MAN ! This feals so right. I already have another Virtualhost, why did not come this to my mind ? I just made `dev.example.com`, it is another DocumentRoot so no need to mix RewriteRules. Thanks so much ! A dream come true :D I was struggling with this for months... – kissgyorgy Aug 12 '12 at 12:57