mopsyd
mopsyd

Reputation: 1922

htaccess and multiple public folders

I am laying out a system that has multiple public folders, and need the .htaccess to allow access to all public folders, but only public folders.

The directory structure looks something like this:

apps
  -app1
    -public
  -app2
    -public
  -app3
    -public
public
system
  -public

The root public folder has shared script, image and css assets, which later on may get packaged into individual app folders as needed so they can be deployed as standalone apps, and contains the front controller. The system folder has script and css assets for system administration and debugging. The app folders have their own individual public folders, and when run directly do not need to fall back on the system assets.

I need my htaccess to expose all of these public folders, without having to put "public" in the url, ie:

somedomain.com/css/something.css should map to: somedomain.com/public/css/something.css

somedomain.com/system/css/something.css should map to: somedomain.com/system/public/something.css

somedomain.com/app1/css/something.css should map to: somedomain.com/apps/app1/public/css/something.css

In my existing .htaccess, I've tried a number of ways of mapping this with no luck. The base level public folder maps fine, but the problem arises when I have to rewrite to a public folder that is more than one level deep, aka system and apps.

I don't really see what is wrong with this, but here's what I have now:

# Change default directory page
DirectoryIndex index.php index.html

# Prevent directory listings
Options All -Indexes -Multiviews

<IfModule mod_rewrite.c>
    RewriteEngine On
    Options +FollowSymlinks

    #App folder block
    #Does not match system folder
    RewriteCond %{REQUEST_URI} !^/system
    #Does match an app folder
    RewriteCond %{REQUEST_URI} ^/apps/([a-zA-Z0-9\-\_]*)$
    #Does not match an app public folder
    RewriteCond %{REQUEST_URI} !^/apps/([a-zA-Z0-9\-\_]*)/public
    #Redirect to specified app public folder
    RewriteRule ((!?apps/)(!?public/).*)$ apps/$1/public/$2 [L,NC]

    #System folder block
    #Does match system folder
    RewriteCond %{REQUEST_URI} ^/system(/.*) [NC]
    #Does not match system public folder
    RewriteCond %{REQUEST_URI} !^/system/public [NC]
    #Redirect to system public folder
    RewriteRule . /system/public/$1 [L,NC]

    #Root public folder block
    #Does not match root public folder
    RewriteCond %{REQUEST_URI} !^/public/
    #Does not match system public folder
    RewriteCond %{REQUEST_URI} !^/system/public/
    #Does not match an app public folder
    RewriteCond %{REQUEST_URI} !^/apps/([a-zA-Z0-9\-\_]*)/public/
    #Redirect all remaining requests to front controller
    RewriteRule ^(.*)$ public/index.php?action=$1 [QSA,L]
</IfModule>

My access log returns the following when I try to load somedomain.com/system/css/something.css

127.0.0.1 - - [25/Mar/2017:23:04:13 -0600] "GET /system/css/something.css HTTP/1.1" 200 - "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7"

The page returns a status code of 200 OK, but no content loads and there is no valid route to any file being given, as per the access log.

If I reference the same file like so: somedomain.com/system/public/css/something.css then it loads fine, but I need the "public" not to be included in the url. Thus far this only works for the root level public folder.

This behavior was consistent when I commented out everything except the part pertaining to the system public folder, so it's not other rules interfering with the behavior.

NOTE: need a solution without the common

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

The reason for this is that there should never be any direct directory access, and actual public html files paths are always rewritten. This is handled differently in the individual app folders when they are loaded directly, and that already works, and cannot be changed for this purpose.

Upvotes: 2

Views: 336

Answers (1)

anubhava
anubhava

Reputation: 784988

Have it like this:

# Change default directory page
DirectoryIndex index.php index.html

# Prevent directory listings
Options All -Indexes -Multiviews
RewriteEngine On

# handle /app1, /app2, /app3
RewriteCond %{DOCUMENT_ROOT}/apps/$1/public/$2 -f
RewriteRule ^([\w-]+)/(css/.+)$ apps/$1/public/$2 [L,NC]

# handle /system/css/
RewriteRule ^(system)/css/(.+)$ $1/public/$1 [L,NC]

# handle /css
RewriteRule ^css/.+$ public/$0 [L,NC]

# your remaining rewrite rules, if any

Upvotes: 2

Related Questions