1

Ok. So, I've taken a look at eerily similar questions such as this one and this one, but, while they've definitely helped, I'm still running into one last issue.

Suppose we have the following URLs:
http://playground.dev/projects/project1 http://playground.dev/projects/project1/work http://playground.dev/projects/project1/work/1.txt

And suppose we have the following directory structure:

/var/www
- projects/
-- project1/
--- public_html/
---- index.html
---- work/
----- 1.txt

My goal is to write a generic .htaccess file that will live within the "root" of each project (project1, project2, etc.), and will map the above URLs to their appropriate files and directories.

Now, I've pretty much figured it out:

RewriteEngine On

RewriteRule ^public_html - [L]
RewriteRule ^(.*)$ public_html/$1

This gets me what I want. The above-mentioned URLs all map like they're supposed to, and most outliers/erroneous input is properly dealt a 4xx; however, there's one glitch: URLs like the following are accepted by Apache.

http://playground.dev/projects/project1/work/1.txt/fgdgfgfdgfdgd

No, fgdgfgfdgfdgd does not exist, nor is "1.txt" a directory, yet not only does Apache allow this abomination to go on without so much as a 404, but somehow manages to pass through to the "1.txt" file as if the URL I had entered was http://playground.dev/projects/project1/work/1.txt.

This does not happen when I remove the .htaccess file and try the same thing on the full path. The apache docs are shedding little light, and Google is sputtering. Maybe I'm tired and missing something... but just what is going on here?

Let me be a bit more specific:

The URL is composed like so: http://playground.dev/projects/{projectname}{path} where {projectname} and {path} are not only both variable (although projectname is only ever a single directory), but {path} may or may not exist, may or may not be 3 directories deep, or may even be 300 directories deep.

Community
  • 1
  • 1
Xunnamius
  • 478
  • 1
  • 8
  • 16
  • 1
    Are `projects` and `project1` fixed strings? When you say `http://playground.dev/projects/project1/work/1.txt/fgdgfgfdgfdgd` "...are accepted by Apache.", do you mean it is also redirected like this: `http://playground.dev/public_html/projects/project1/work/1.txt/fgdgfgfdgfdgd`? – Felipe Alameda A Mar 16 '13 at 07:51
  • `projects` is fixed, `project1` is not. And yes, the (internal) redirect keeps the URL at `http://playground.dev/public_html/projects/project1/work/1.txt/fgdgfgfdgfdgd` while displaying `http://playground.dev/public_html/projects/project1/work/1.txt` – Xunnamius Mar 16 '13 at 07:53

1 Answers1

2

MODIFIED:

To do a global redirect as long as the file or directory exists, you may try this:

Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !public_html  [NC]
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*)$ /public_html/$1  [L,NC]

For permanent and visible redirection, replace [L,NC] with [R=301,L,NC]

Community
  • 1
  • 1
Felipe Alameda A
  • 11,791
  • 3
  • 29
  • 37
  • Sorry if I wasn't specific enough. The URL is composed like so: `http://playground.dev/projects/{projectname}{path}` where {projectname} and {path} are not only both variable, but {path} may or may not exist, may or may not be 3 directories deep, or even may or may not be 300 directories deep. Similar (in theory) to redirecting all requests from the root of a site to some subdirectory. – Xunnamius Mar 16 '13 at 08:19
  • @Xunnamius That's the problem. If the number of sub-directories is undefined, there is no way to know when some of them are not supposed to be redirected and they will be included in the substitution URL if there are enough back references to do it, though. There has to be a way to identify the valid sub-directories or files for the redirection to work as expected. – Felipe Alameda A Mar 16 '13 at 08:26
  • I did just that in my original .htaccess as detailed above: it goes "if the per-directory path of the URL (stripped of prefix by Apache) already starts with `public_html`, then we're done here," and it's working... except in that very last edge case. – Xunnamius Mar 16 '13 at 08:28
  • Further, even if Apache does reinterpret the .htaccess at every directory level and clips the "per-directory prefix" (see [the docs](http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule)), then I should get a 404 with a crazy URL like `http://playground.dev/projects/project1/work/public_html/1.txt/public_html/fgdgfgfdgfdgd`, right? Or maybe I'm understanding this wrong :) – Xunnamius Mar 16 '13 at 08:37
  • I understand what you need. I modified my answer, maybe it will work as expected. – Felipe Alameda A Mar 16 '13 at 08:40
  • I tried something like this after looking at a few other SO questions. Just popped your code into my .htaccess file and... Nope. When I navigate to `http://playground.dev/projects/project1` I get the pretty directory listing instead of the index.html. Dang. – Xunnamius Mar 16 '13 at 08:47
  • Try adding a trailing slash to the test URL. – Felipe Alameda A Mar 16 '13 at 08:49
  • Chrome inserts it for me automatically (it's there) – Xunnamius Mar 16 '13 at 08:51
  • Sorry I could not be of any help. Can't think of anything else to achieve what you need. I will delete this answer in a few minutes to allow for somebody else to try to answer your question. It is now pretty clear. – Felipe Alameda A Mar 16 '13 at 08:54
  • No apology necessary, thank YOU for taking the time to try :) Might want to save the answer (and comments) though, so other answerers can hit the ground running (if I'm so lucky!) – Xunnamius Mar 16 '13 at 08:56
  • Okay. I will leave it. Good luck. – Felipe Alameda A Mar 16 '13 at 08:57