Bug 10932 - Allow Negative regex in LocationMatch
Summary: Allow Negative regex in LocationMatch
Status: RESOLVED WORKSFORME
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: Core (show other bugs)
Version: 2.0.39
Hardware: PC Linux
: P5 enhancement (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-07-18 02:23 UTC by Jerrad Pierce
Modified: 2007-06-08 06:46 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jerrad Pierce 2002-07-18 02:23:45 UTC
I've googled, and fiddled to no ends. I have what I believe to
be a simple goal. I wish to:

        <LocationMatch !"^/bar">
                ProxyPass http://somehost
        </LocationMatch>

        <Location /bar>
                handler
        </Location>

The specific regexp used doesn't matter. the instant I add !
which is supposed
to be the negation character /bar is passed to the handler
properly, but
anything else is not proxied but served from the local system
instead.

So to reiterate what is desired:
        everything but /bar goes to somehost
        /bar is handled locally
Comment 1 Joshua Slive 2002-07-18 15:11:11 UTC
I don't believe that the LocationMatch/DirectoryMatch/FilesMatch sections
allow negatives.  The "!" syntax is certainly not documented anywhere.

I guess we could consider this bug report a request for such ability.  I have
seen it requested elsewhere, and it shouldn't be that difficult to provide.

As far as your particular problem, it should be easy to get around using something
like
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/bar
RewriteRule / http://somehost/ [P]
Comment 2 Jerrad Pierce 2002-07-18 23:31:25 UTC
It's possible support for such does not exist,
I found examples of it out there on the web
though. However "regexp" is a nebulous term,
and I was unable to find anything specific in
the documentation concerning exactly what
regexp syntax was supported... (although
from looking at the source tree it seems pcre
is used, in which case it seems negation would
be extraordinarily easy)

The rewriterule while one means of a workaround,
does not emulate the desired behavior. I am
trying to proxypass from somehost such that
the content appears to come from this host.
(I'm actually proxying an apache 1.3 server
bound to 127.0.0.1).

I did think of workaround, which I have not
tests, that is more of a hack and hideous.

"/[^b][^a][^r]"
Comment 3 Joshua Slive 2002-07-19 17:30:06 UTC
The RewriteRule does work.  Please look at the docs for RewriteRule with 
specific reference to the "P" option which stands for Proxy.
Comment 4 Jerrad Pierce 2002-07-19 19:29:15 UTC
Heh, so does it. Sorry about that.
(Though it appears the last line needs to be
    RewriteRule /(.*) http://localhost/$1 [P]
)
Comment 5 André Malo 2003-03-03 16:05:07 UTC
Just for the records:

<LocationMatch "^/(?!bar)">

works, too (since httpd-2), because of the advantages of pcre. The syntax is
described and explained in perldoc perlre. (which is online at perldoc.com).
No need to duplicate that manual stuff within the apache docs.

Thanks for using Apache!
Comment 6 Morgan Doocy 2005-02-23 23:19:41 UTC
I'm surprised this isn't considered a useful enhancement. Negative matching is an integral part of 
regular expressions, and the fact that it's missing from the *Match directives is, to me, a serious 
oversight. It seems very backwards to me to suggest that, since it can be worked around using other 
features (without having identical functionality), this is not a useful feature to include.

I would like to petition the devs to reconsider adding this functionality. If there is some reason I have 
overlooked that it would be dangerous or impractical for this to be added, I am very open to feedback.

For reference, here are a few threads I found on Google, some of which express the same incredulity 
that this feature is not present, some of which are simply pleas for help on how to accomplish the same 
functionality. Note that in most, the negative assertion workaround is the recommended solution.

http://mathforum.org/epigone/modperl/lulsmoxkhi
http://www.mail-archive.com/tomcat-user@jakarta.apache.org/msg145973.html
http://www.apache-httpd.com/msg/5514.html
http://www.issociate.de/board/post/167026/Exclude_images_from_match.html
Comment 7 Morgan Doocy 2005-02-23 23:43:27 UTC
I found another resource containing a quote which sums up the lack of negative matching pretty well:

"This option was added for two reasons - firstly that the <LocationMatch> directive is not allowed in a 
.htaccess file, and secondly that the built in Apache regular expressions are not terribly powerful (for 
example they cannot do negative matches)."

Source: http://www.axkit.org/docs/guide.dkb?section=7
Comment 8 Leif W 2005-03-31 11:54:20 UTC
It would be spectacular to see a simple, no-nonsense negation.  From
what I understand after skimming the PCRE man page, this has to be
external to the regexp because of the nature of regexp matching.
Probably why it was never implemented, because it's extra work.  Maybe
other things needed more attention so this was put aside, then
forgotten about.

FYI for those searching for answers, the "^/(?!bar)" syntax is referred
to as a negative assertion.  It has some subtle syntax and can be a bit
confusing for the novice PCRE user even in a simple case, which may be
many of the admin running Apache.  I'm not too familiar with how nice it
plays with more complex regular expressions.

In the config file, it's difficult if not impossible to specify each
negative Match rule for every possible negative Match condition when the
negative results may change frequently and at random, yet the positive
Match are few and static.  These cases seem to be very common.  If a
regexp does not match the right answer, tell me it's the wrong answer.
I won't sit and try to pre-define every conceivable wrong answer in the
universe, when there are maybe 3-4 right answers that I care about.
That is computationally wasteful and redundant.

LocationMatch is part of the core.  What if I don't want to use
mod_rewrite for every tiny thing that isn't properly implemented in the
core?  I want to keep the server lean.  It's a shame to have to include
another module to do something that LocationMatch (from the view of a
sysadmin) should be able to handle within it's own syntax.  It's 95%
there already when the PCRE returns and finds that there was no match.
The PCRE function returns -1?  So if there's a "!" negation character,
check for "-1" return, and if so valued, perform the action specified.

I'd have to look into the code and research more to see if there were
any patches or to generate one.  I'm surprised that in all this time
there have been no patches.  Maybe it's uglier than I think in there.
Comment 9 Davi Arnaut 2007-06-08 06:46:41 UTC
Closing bug report due to inactivity and the issue is rather cosmetic.
If more information appears later, please re-open the bug.