The documentation says you can have multiple directives… It doesn’t indicate 
whether they’re and-ed or or-ed together.  (The fact that it calls them 
conditions leads me to believe they’re restrictive)  I also agree the code 
appears to be doing an And relation.

Personally it’s never occurred to me to try to use multiple URL directives.

I agree in your case Or is what you want.  I’m having a hard time thinking of a 
reason you might want to use Ands…  Maybe some sort of exclusionary rule using 
negative lookaheads.. but with regular expressions I would think you could do 
that on one line as well.

“Or” logic committed to stage_for_upstream/v2.7b

Joe

From: Conor McCarthy [mailto:[email protected]]
Sent: Tuesday, April 23, 2013 11:12 AM
To: [email protected]
Subject: Re: [Pound Mailing List] Defining multiple URL patterns in a Service


On 2013-01-30 18:58:24, Alan McGinlay wrote:
> On 2013-01-30 18:40, Andreas Hilboll wrote:

> > Hi,

> >

> > on my pound 2.6-2, I would like to define multiple URL patterns in a

> > service. The manpage says it's possible:

> >

> >    You may define multiple URL conditions per service.

> >

> > However, in a service like this, none of the three patterns seems to

> > kick in:

> >

> >   Service

> >     URL "^/services/ddEmissionService"

> >     URL "^/services/bbEmissionService2"

> >     URL "^/services/ccEmissionService3"

> >     BackEnd

>

> In order to redirect URL's to a specific backend I am using the

> following:

>

> Service

>    HeadRequire "^Host:\s*www.domain.com.*"

>    URL "/~.*"

>    BackEnd

>      Add... etc

>

> This will redirect any ~user directories (Apache UserDir's) to a

> specific backend.

>

> For me this works very well, perhaps you have specified the URL

> matching after another service that also matches (so it never reaches

> your URL match).

>

> /A

The documentation implies an "any" URL match logic, this does not match the
code, Pound-2.6/svc.c #412:

static int
match_service(const SERVICE *svc, const char *request, char **const headers)


{
    MATCHER *m;
    int     i, found;

    /* check for request */
    for(m = svc->url; m; m = m->next)
        if(regexec(&m->pat, request, 0, NULL, 0))
            return 0;

    /* check for required headers */


    /* ... */

    /* check for forbidden headers */
    /* ... */

    return 1;
}

regexec() returns 0 for a match, and non-zero (REG_NOMATCH) for no match.

The URL testing for-loop will "early out" as soon as a match fails, rejecting


that service as unsuitable: i.e. all URLs must match, just like HeadRequire and
HeadDeny (for these the man page is explicit).

I have patched my implementation as follows:

    int     i, found,check;


    /* check for request URL */
    check=0;
    for(m = svc->url; m; m = m->next) {
        check++;
        if(regexec(&m->pat, request, 0, NULL, 0)!=REG_NOMATCH) {
            return 1;


        }
    }
    if (check) return 0;  // URLs were specified, none matched

To play fair if combined with the HeadRequire/HeadDeny logic, the code needs
to be reworked slightly - moving the URL test loop to last should suffice, but


I have not tested this in production.

Since it works as expected with exactly one URL, you should be able to use:

  URL "^/services/(ddEmissionService|bbEmissionService2|ccEmissionService3)


or minor variations of it.

Regards,
 C.

Reply via email to