logo
Apache Lounge
Webmasters

 

About Forum Index Downloads Search Register Log in RSS X


Keep Server Online

If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.

or

Bitcoin

A donation makes a contribution towards the costs, the time and effort that's going in this site and building.

Thank You! Steffen

Your donations will help to keep this site alive and well, and continuing building binaries. Apache Lounge is not sponsored.
Post new topic   Forum Index -> Apache View previous topic :: View next topic
Reply to topic   Topic: DirectoryMatch expression detect subfolders
Author
dsk8311



Joined: 01 Feb 2022
Posts: 2

PostPosted: Tue 01 Feb '22 18:02    Post subject: DirectoryMatch expression detect subfolders Reply with quote

I currently have an .htaccess file in the site's DocumentRoot to control direct access to certain files.
Two other applications, each with its own .htaccess, are installed in subfolders (\app1 and \app2) but are impacted by the propagation of the parent's rules.

My goal is to move the root's .htaccess to the main Apache config with a condition to exclude them from applying to \app1 and \app2 subfolders.

I managed to detect the subfolders with a LocationMatch

Code:
<LocationMatch "^(?!/(?:app1|APP1|app2|APP2))/[^/]+">   
    Header set X-TEST-LOCATION "ROOT-APP"
</LocationMatch>


What would be the equivalent condition for a DirectoryMatch directive? I have a custom DEF_ROOT variable defined and this doesn't seem to work

Code:
<DirectoryMatch "(?!${DEF_ROOT}/main-app/(?:app1|APP1|app2|APP2))/[^/]+">
    Header set X-TEST-LOCATION "ROOT-APP"
</DirectoryMatch>


Apache 2.4.46 running on Windows.

Thanks!
Back to top
tangent
Moderator


Joined: 16 Aug 2020
Posts: 312
Location: UK

PostPosted: Wed 02 Feb '22 19:24    Post subject: Reply with quote

When working with complex regex constructs, I tend to use this site to check the logic - https://regex101.com. You need to escape forward slashes with this checker, so I tend to leave them in Apache configs.

Re your LocationMatch regex, I've simplified it with a case insensitive match, and character class set [12]. The boundary markers \b are needed to prevent the match picking up entries such as "app12" or "app212", and therefore don't believe you need the trailing slash, etc. after the negative lookahead assertion.
Code:
<LocationMatch "^(?i)(?!\/\bapp[12]\b)">
    Header set X-TEST-LOCATION "ROOT-APP"
</LocationMatch>

With the DirectoryMatch, believe your negative lookahead assertion is in the wrong place (too early). The following works for me using a local test instance of Apache (setting DEF_ROOT with a Define directive).
Code:
<DirectoryMatch "^(?i)${DEF_ROOT}\/main_app(?!\/\bapp[12]\b)">
    Header set X-TEST-DIRECTORY "ROOT-APP"
</DirectoryMatch>

Hope this helps.
Back to top
dsk8311



Joined: 01 Feb 2022
Posts: 2

PostPosted: Mon 07 Feb '22 9:46    Post subject: Reply with quote

Thank you, that seems to do the trick.
However it seems that I need to escape the path separator slashes in the DEF_ROOT variable as well, which is not always practical (eg. D:\/SrvHome\/HTTPD\/Root).

I figured I could try encapsulating the condition within a ~m#[...]# block (as described in the documentation: https://httpd.apache.org/docs/2.4/expr.html#other) but that doesn't seem to be working:

Code:

<DirectoryMatch "~m#^(?i)${DEF_ROOT}\/main_app(?!\/\bapp[12]\b)#">
    Header set X-TEST-DIRECTORY "ROOT-APP"
</DirectoryMatch>
Back to top
tangent
Moderator


Joined: 16 Aug 2020
Posts: 312
Location: UK

PostPosted: Mon 07 Feb '22 23:34    Post subject: Reply with quote

I think you have an extraneous tilde '~' at the start of your match, but that aside I don't think this construct will work here. It looks like DirectoryMatch requires a straight regex, and not the "m#regexp#" variant supported with expressions.

That said, in Apache the escape backslashes aren't actually needed in front of forward slashes, since Apache regex's are normally defined in a quoted string, rather than a Perl type match or substitute regex construct, which typically use a forward slash separator.

So your DirectoryMatch regex can actually be reduced to:
Code:
<DirectoryMatch "^(?i)${DEF_ROOT}/main_app(?!/\bapp[12]\b)">
    Header set X-TEST-DIRECTORY "ROOT-APP"
</DirectoryMatch>

Apache configurations require the use of forward slash as path separators, irrespective of whether the host platform is Windows or Unix. The top of the default httpd.conf file specifically says:
    # NOTE: Where filenames are specified, you must use forward slashes
    # instead of backslashes (e.g., "c:/apache" instead of "c:\apache").
So I don't really understand why you need to escape the forward slashes in your DEF_ROOT variable, even if it were possible to do so (I've had a think about it, and can't come up with an easy way to do this so far either).
Back to top
James Blond
Moderator


Joined: 19 Jan 2006
Posts: 7294
Location: Germany, Next to Hamburg

PostPosted: Tue 22 Feb '22 12:31    Post subject: Reply with quote

You can also use https://www.debuggex.com/ to debug your regex or https://regexper.com/#%5E%28%5C%3Fi%29%24%7BDEF_ROOT%7D%5C%2Fmain_app%28%3F!%5C%2F%5Cbapp%5B12%5D%5Cb%29
Back to top


Reply to topic   Topic: DirectoryMatch expression detect subfolders View previous topic :: View next topic
Post new topic   Forum Index -> Apache