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