Search code examples
wordpressapache.htaccessmod-rewritesubdirectory

.htaccess with two subfolders (bedrock in it self directory in the root)


In the webroot of my local server, I try to install Bedrock in it self directory :

|- htdocs
   |- bedrock
      |- web

With the .htaccess file I wrote, I can access the web directory and so launch my application :

RewriteEngine On
    
RewriteCond %{HTTPS} off 
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301]

RewriteCond %{HTTP_HOST} ^(www.)?example.local$
RewriteCond %{REQUEST_URI} !^/bedrock/web/
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /bedrock/web/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.local$
RewriteRule ^(/)?$ bedrock/web/index.php [L]

However I would like to avoid accessing to bedrock directory with the url : example.local/bedrock.

Can I do this with rewrite module from Apache or do I have to add a .htaccess with deny from all in the bedrock directory ?


Solution

  • You can block direct access to the /bedrock subdirectory, but still allow requests be internally rewritten to that directory, by adding the following before your existing rules:

    # Block "direct" access to the "/bedrock" subdirectory
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^bedrock($|/) - [F]
    

    The above will return a "403 Forbidden" if /bedrock or /bedrock/<anything> is requested directly by the client.

    By checking that the REDIRECT_STATUS environment variable is empty we can make sure the rule is only applied to direct requests (and not rewritten requests - later in the file).

    The REDIRECT_STATUS env is empty on the initial request, but set to 200 (as in 200 OK status) after the first successful rewrite.

    ...or do I have to add a .htaccess with deny from all in the bedrock directory ?

    That would block all requests, including your internal rewrites.


    Aside:

    RewriteCond %{HTTPS} off 
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
    
    RewriteCond %{HTTP_HOST} ^(www.)?example.local$
    RewriteCond %{REQUEST_URI} !^/bedrock/web/
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /bedrock/web/$1
    RewriteCond %{HTTP_HOST} ^(www.)?example.local$
    RewriteRule ^(/)?$ bedrock/web/index.php [L]
    

    You should include the L flag on the first 2 rules. You've only included the L flag on the last rule (where it isn't strictly required).

    You don't need the capturing group in the last rule. ^/?$ (or even ^$ in .htaccess) would suffice.