views:

76

answers:

3

I'm looking into setting up an application where there is a core and a project namespace, where core is the default fallback to the project customisation. to this end id like to be able to cascade various resources like css, javascript etc. for the purposes of the excersize, ive simplified this as

./.htaccess
./first/firstonly.txt
./first/both.txt
./second/secondonly.txt
./second/both.txt

expected behaviour would be a request would check for existence in first before looking in second, and finally throwing 404.

for baseurl/firstonly.txt would hit ./first/firstonly.txt (200),
whereas baseurl/secondonly.txt would try ./first/secondonly.txt (404) then ./second/secondonly.txt (200).
baseurl/both.txt would hit ./first/both.txt (200) and go no further.
baseurl/nonexistant.txt (404) would run through the cascades and return 404.

I'm fairly competant with mod_rewrite, so dont feel the need to talk basics here. What would be the most efficient (sane) way of implementing this? Speed concerns aside, as most of the time things will be found on the first hit.

A: 

Try these rules:

RewriteEngine on
RewriteRule ^(first|second)/ - [L]
RewriteCond %{DOCUMENT_ROOT}/first/$0 -f
RewriteRule ^[^/]+$ first/$0 [L]
RewriteCond %{DOCUMENT_ROOT}/second/$0 -f
RewriteRule ^[^/]+$ second/$0 [L]
Gumbo
Ah yes, well thats prettymuch a similar solution to what ive come up with myself, however it relies on the root of the project being in the document root, which doesnt always happen. It needs to be able to work happily relative to the .htaccess (which is the current sticking point)
devians
@devians: Try `RewriteCond first/$0 -F` instead.
Gumbo
doing rewritecond checks like that dont seem to work, it requires the full path
devians
@devians: Note the capital *F* in `-F`.
Gumbo
A: 

Some other potential solutions

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^first
RewriteCond %{REQUEST_URI} !^second
RewriteRule ^([^/]+\.?[^/])*$ first/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^second
RewriteRule ^first/([^/]+\.?[^/])*$ second/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^(first|second).*$
RewriteRule .* /404.html [L]

or

RewriteCond %{REQUEST_URI} 404.html
RewriteRule .* - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^first
RewriteCond %{REQUEST_URI} !^second
RewriteRule ^([^/]+\.?[^/])*$ first/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^second
RewriteRule ^first/([^/]+\.?[^/])*$ second/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^(first|second).*$
RewriteRule .* /404.html [L]

In my personal testing im noticing that the -f check is accurate only against a full pathname, which makes things tricky if you're not in the document root. Could this be addressed by rewriting to the file, and then doing the -f on the request_uri?

devians
A: 
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule ^Public/(.*)$ Application/Public/$1 [L]

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]

RewriteRule ^(css|scripts|images|assets|flash)/(.*)$ Public/$1/$2 [L]

This is the final working solution (outside the sandbox example above).

devians