How to add/ignore a subfolder in htaccess file

.htaccessmod-rewriterewrite

I have build an app at http://url/sdf19/

I have a .htaccess placed in /sdf19/ containing RewriteRule for clean urls.

But I have built a PDF generating tool, which is in a subfolder /inc/tools.
I need to link to it direct to run before headers.

Despite a few hours of searching, trying snippets, generators, etc. I cannot get any request to http://url/sdf19/inc/tools to be allowed, without the existing RewriteRule set taking over

Here is my starting file

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

RewriteRule ^([a-z]+)\/?$ index.php?page=$1 [NC]
RewriteRule ^([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&id=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/?$ index.php?page=$1&action=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&action=$2&id=$3 [NC]

THINGS TRIED:

I've tried to add this on line 4;
RewriteCond %{REQUEST_URI} !^ inc/tools/ [NC]
This gave RewriteCond: bad argument line error

I've tried to add this to line 2;

RewriteCond %{REQUEST_URI} ^/inc/tools/(.*)$
RewriteRule ^.*$ - [L]

I've tried adding a .htaccess in /inc/tools with RewriteEngine OFF, didnt work.

I'e tried the .htaccess tester linked on the top post, but whislt my file (above) works IRL, it produces 'rule not met' for everything on there!

TL;DR

Desired result is that I can allow direct access to http://url/sdf19/inc/tools > everything I have tried so far i get redirected to base http://url/sdf19/

Best Answer

A bit of discussion about your current rules...

I've tried to add this on line 4; RewriteCond %{REQUEST_URI} !^ inc/tools/ [NC] This gave RewriteCond: bad argument line error

Because you have an erroneous space in the middle of the CondPattern !^ inc/tools/. However, that expression still won't give the correct result (see below).

I've tried to add this to line 2;

RewriteCond %{REQUEST_URI} ^/inc/tools/(.*)$
RewriteRule ^.*$ - [L]

You are close with this. However, the REQUEST_URI server variable contains the full URL-path, not the URL-path relative to where the .htaccess file is located. So, this would need to be of the form:

RewriteCond %{REQUEST_URI} ^/sdf19/inc/tools/
RewriteRule ^ - [L]

This would need to go near the top of your .htaccess file, immediately after the RewriteEngine On directive. The (.*)$ at the end of the CondPattern was superfluous, as was the RewriteRule pattern ^.*$. However, this can be written more efficiently as a single directive and testing with the RewriteRule pattern instead. You can then omit the /sdf19 subdirectory. For example:

RewriteRule ^inc/tools/ - [L]

I've tried adding a .htaccess in /inc/tools with RewriteEngine OFF, didn't work.

Well, that should have worked. (Unless perhaps you have mod_alias directives in the parent .htaccess file that are conflicting?) So, it's unclear, given what you've stated in the question why it didn't. Do you have other directives in your .htaccess file?

everything I have tried so far i get redirected to base http://url/sdf19/

That is also strange, because nothing you've shown so far would result in an external redirect. Do you have other directives in your .htaccess file? A mod_alias Redirect or RedirectMatch directive perhaps?

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

RewriteRule ^([a-z]+)\/?$ index.php?page=$1 [NC]
RewriteRule ^([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&id=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/?$ index.php?page=$1&action=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&action=$2&id=$3 [NC]

A potential problem with these directives is that RewriteCond directives only apply to the first RewriteRule that follows. So, the 2nd, 3rd and 4th RewriteRule directives above are being executed unconditionally and explains why requests to /sdf19/inc/tools are being caught by the third rule.

You would either need to include those same conditions before every RewriteRule (ie. the rule is only processed when the request does not map to a file and does not map to a directory). Or, negate their meaning and prevent further processing if a file or directory is requested - however, this can depend on whether you have more directives later in your file that still need to be processed under these conditions.

You are also missing L flags on these directives, so processing is (unnecessarily?) continuing through your file.

So, try the following instead:

# Prevent further processing if a file or directory is requested
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
 
# Route other URLs
RewriteRule ^([a-z]+)\/?$ index.php?page=$1 [NC,L]
RewriteRule ^([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&id=$2 [NC,L]
RewriteRule ^([a-z]+)\/([a-z]+)\/?$ index.php?page=$1&action=$2 [NC,L]
RewriteRule ^([a-z]+)\/([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&action=$2&id=$3 [NC,L]
Related Topic