Commit f1fd2478 authored by Yann Ylavic's avatar Yann Ylavic
Browse files

Merge r1667707, r1824332 from trunk:

* mod_proxy: Allow setting options to globally defined balancer from
  ProxyPass used in VirtualHost. Balancers are now merged using the new
  merge_balancers method which merges the balancers options.


mod_proxy: follow up to r1667707: MMN minor bump.


Submitted by: jkaluza, ylavic
Reviewed by: icing, jim, ylavic


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1824333 13f79535-47bb-0310-9956-ffa450edef68
parent 1cff2ec5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.4.30

  *) mod_proxy: Allow setting options to globally defined balancer from
     ProxyPass used in VirtualHost. Balancers are now merged using the new
     merge_balancers method which merges the balancers options.  [Jan Kaluza]

  *) logresolve: Fix incorrect behavior or segfault if -c flag is used
     Fixes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=823259
     [Stefan Fritsch]
+3 −1
Original line number Diff line number Diff line
@@ -505,6 +505,8 @@
 *                          and optional ssl_engine_set() to mod_ssl.h.
 * 20120211.72 (2.4.30-dev) Add NOT_IN_DIR_CONTEXT replacing NOT_IN_DIR_LOC_FILE
 *                          semantics
 * 20120211.73 (2.4.30-dev) Add failontimeout_set, growth_set and lbmethod_set
 *                          to proxy_balancer struct
 */

#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -512,7 +514,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20120211
#endif
#define MODULE_MAGIC_NUMBER_MINOR 72                  /* 0...n */
#define MODULE_MAGIC_NUMBER_MINOR 73                  /* 0...n */

/**
 * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
+102 −1
Original line number Diff line number Diff line
@@ -365,6 +365,7 @@ static const char *set_balancer_param(proxy_server_conf *conf,
        }
        else
            balancer->s->sticky_separator = *val;
        balancer->s->sticky_separator_set = 1;
    }
    else if (!strcasecmp(key, "nofailover")) {
        /* If set to 'on' the session will break
@@ -377,6 +378,7 @@ static const char *set_balancer_param(proxy_server_conf *conf,
            balancer->s->sticky_force = 0;
        else
            return "failover must be On|Off";
        balancer->s->sticky_force_set = 1;
    }
    else if (!strcasecmp(key, "timeout")) {
        /* Balancer timeout in seconds.
@@ -407,6 +409,7 @@ static const char *set_balancer_param(proxy_server_conf *conf,
        if (provider) {
            balancer->lbmethod = provider;
            if (PROXY_STRNCPY(balancer->s->lbpname, val) == APR_SUCCESS) {
                balancer->lbmethod_set = 1;
                return NULL;
            }
            else {
@@ -426,6 +429,7 @@ static const char *set_balancer_param(proxy_server_conf *conf,
            balancer->s->scolonsep = 0;
        else
            return "scolonpathdelim must be On|Off";
        balancer->s->scolonsep_set = 1;
    }
    else if (!strcasecmp(key, "failonstatus")) {
        char *val_split;
@@ -456,6 +460,7 @@ static const char *set_balancer_param(proxy_server_conf *conf,
            balancer->failontimeout = 0;
        else
            return "failontimeout must be On|Off";
        balancer->failontimeout_set = 1;
    }
    else if (!strcasecmp(key, "nonce")) {
        if (!strcasecmp(val, "None")) {
@@ -466,12 +471,14 @@ static const char *set_balancer_param(proxy_server_conf *conf,
                return "Provided nonce is too large";
            }
        }
        balancer->s->nonce_set = 1;
    }
    else if (!strcasecmp(key, "growth")) {
        ival = atoi(val);
        if (ival < 1 || ival > 100)   /* arbitrary limit here */
            return "growth must be between 1 and 100";
        balancer->growth = ival;
        balancer->growth_set = 1;
    }
    else if (!strcasecmp(key, "forcerecovery")) {
        if (!strcasecmp(val, "on"))
@@ -480,6 +487,7 @@ static const char *set_balancer_param(proxy_server_conf *conf,
            balancer->s->forcerecovery = 0;
        else
            return "forcerecovery must be On|Off";
        balancer->s->forcerecovery_set = 1;
    }
    else {
        return "unknown Balancer parameter";
@@ -1360,6 +1368,99 @@ static void * create_proxy_config(apr_pool_t *p, server_rec *s)
    return ps;
}

static apr_array_header_t *merge_balancers(apr_pool_t *p,
                                           apr_array_header_t *base,
                                           apr_array_header_t *overrides)
{
    proxy_balancer *b1;
    proxy_balancer *b2;
    proxy_balancer tmp;
    int x, y, found;
    apr_array_header_t *tocopy = apr_array_make(p, 1, sizeof(proxy_balancer));

    /* Check if the balancer is defined in both override and base configs:
     * a) If it is, Create copy of base balancer and change the configuration
     *    which can be changed by ProxyPass.
     * b) Otherwise, copy the balancer to tocopy array and merge it later.
     */
    b1 = (proxy_balancer *) base->elts;
    for (y = 0; y < base->nelts; y++) {
        b2 = (proxy_balancer *) overrides->elts;
        for (x = 0, found = 0; x < overrides->nelts; x++) {
            if (b1->hash.def == b2->hash.def && b1->hash.fnv == b2->hash.fnv) {
                tmp = *b2;
                *b2 = *b1;
                b2->s = tmp.s;

                /* For shared memory entries, b2->s belongs to override
                 * balancer, so if some entry is not set there, we have to
                 * update it according to the base balancer. */
                if (*b2->s->sticky == 0 && *b1->s->sticky) {
                    PROXY_STRNCPY(b2->s->sticky_path, b1->s->sticky_path);
                    PROXY_STRNCPY(b2->s->sticky, b1->s->sticky);
                }
                if (!b2->s->sticky_separator_set
                    && b1->s->sticky_separator_set) {
                    b2->s->sticky_separator_set = b1->s->sticky_separator_set;
                    b2->s->sticky_separator = b1->s->sticky_separator;
                }
                if (!b2->s->timeout && b1->s->timeout) {
                    b2->s->timeout = b1->s->timeout;
                }
                if (!b2->s->max_attempts_set && b1->s->max_attempts_set) {
                    b2->s->max_attempts_set = b1->s->max_attempts_set;
                    b2->s->max_attempts = b1->s->max_attempts;
                }
                if (!b2->s->nonce_set && b1->s->nonce_set) {
                    b2->s->nonce_set = b1->s->nonce_set;
                    PROXY_STRNCPY(b2->s->nonce, b1->s->nonce);
                }
                if (!b2->s->sticky_force_set && b1->s->sticky_force_set) {
                    b2->s->sticky_force_set = b1->s->sticky_force_set;
                    b2->s->sticky_force = b1->s->sticky_force;
                }
                if (!b2->s->scolonsep_set && b1->s->scolonsep_set) {
                    b2->s->scolonsep_set = b1->s->scolonsep_set;
                    b2->s->scolonsep = b1->s->scolonsep;
                }
                if (!b2->s->forcerecovery_set && b1->s->forcerecovery_set) {
                    b2->s->forcerecovery_set = b1->s->forcerecovery_set;
                    b2->s->forcerecovery = b1->s->forcerecovery;
                }

                /* For non-shared memory entries, b2 is copy of b1, so we have
                 * to use tmp copy of b1 to detect changes done in override. */
                if (tmp.lbmethod_set) {
                    b2->lbmethod_set = tmp.lbmethod_set;
                    b2->lbmethod = tmp.lbmethod;
                }
                if (tmp.growth_set) {
                    b2->growth_set = tmp.growth_set;
                    b2->growth = tmp.growth;
                }
                if (tmp.failontimeout_set) {
                    b2->failontimeout_set = tmp.failontimeout_set;
                    b2->failontimeout = tmp.failontimeout;
                }
                if (!apr_is_empty_array(tmp.errstatuses)) {
                    apr_array_cat(tmp.errstatuses, b2->errstatuses);
                    b2->errstatuses = tmp.errstatuses;
                }

                found = 1;
                break;
            }
            b2++;
        }
        if (!found) {
            *(proxy_balancer *)apr_array_push(tocopy) = *b1;
        }
        b1++;
    }

    return apr_array_append(p, tocopy, overrides);
}

static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv)
{
    proxy_server_conf *ps = apr_pcalloc(p, sizeof(proxy_server_conf));
@@ -1384,7 +1485,7 @@ static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv)
    ps->dirconn = apr_array_append(p, base->dirconn, overrides->dirconn);
    if (ps->inherit || ps->ppinherit) {
        ps->workers = apr_array_append(p, base->workers, overrides->workers);
        ps->balancers = apr_array_append(p, base->balancers, overrides->balancers);
        ps->balancers = merge_balancers(p, base->balancers, overrides->balancers);
    }
    else {
        ps->workers = overrides->workers;
+8 −0
Original line number Diff line number Diff line
@@ -494,6 +494,11 @@ typedef struct {
    unsigned int    inactive:1;
    unsigned int    forcerecovery:1;
    char      sticky_separator;                                /* separator for sessionid/route */
    unsigned int    forcerecovery_set:1;
    unsigned int    scolonsep_set:1;
    unsigned int    sticky_force_set:1; 
    unsigned int    nonce_set:1;
    unsigned int    sticky_separator_set:1;
} proxy_balancer_shared;

#define ALIGNED_PROXY_BALANCER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_balancer_shared)))
@@ -514,6 +519,9 @@ struct proxy_balancer {
    void            *context;    /* general purpose storage */
    proxy_balancer_shared *s;    /* Shared data */
    int failontimeout;           /* Whether to mark a member in Err if IO timeout occurs */
    unsigned int failontimeout_set:1;
    unsigned int growth_set:1;
    unsigned int lbmethod_set:1;
    ap_conf_vector_t *section_config; /* <Proxy>-section wherein defined */
};