Return-Path: X-Original-To: apmail-httpd-cvs-archive@www.apache.org Delivered-To: apmail-httpd-cvs-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 66A6D17544 for ; Thu, 19 Mar 2015 11:29:56 +0000 (UTC) Received: (qmail 61218 invoked by uid 500); 19 Mar 2015 11:29:56 -0000 Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 61149 invoked by uid 500); 19 Mar 2015 11:29:56 -0000 Mailing-List: contact cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 61140 invoked by uid 99); 19 Mar 2015 11:29:56 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 19 Mar 2015 11:29:56 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id CEFBAAC0041 for ; Thu, 19 Mar 2015 11:29:55 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1667707 - in /httpd/httpd/trunk/modules/proxy: mod_proxy.c mod_proxy.h Date: Thu, 19 Mar 2015 11:29:55 -0000 To: cvs@httpd.apache.org From: jkaluza@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20150319112955.CEFBAAC0041@hades.apache.org> Author: jkaluza Date: Thu Mar 19 11:29:55 2015 New Revision: 1667707 URL: http://svn.apache.org/r1667707 Log: * 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. Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.c httpd/httpd/trunk/modules/proxy/mod_proxy.h Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy.c?rev=1667707&r1=1667706&r2=1667707&view=diff ============================================================================== --- httpd/httpd/trunk/modules/proxy/mod_proxy.c (original) +++ httpd/httpd/trunk/modules/proxy/mod_proxy.c Thu Mar 19 11:29:55 2015 @@ -315,6 +315,7 @@ static const char *set_balancer_param(pr } 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 @@ -327,6 +328,7 @@ static const char *set_balancer_param(pr 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. @@ -357,6 +359,7 @@ static const char *set_balancer_param(pr if (provider) { balancer->lbmethod = provider; if (PROXY_STRNCPY(balancer->s->lbpname, val) == APR_SUCCESS) { + balancer->lbmethod_set = 1; return NULL; } else { @@ -376,6 +379,7 @@ static const char *set_balancer_param(pr balancer->s->scolonsep = 0; else return "scolonpathdelim must be On|Off"; + balancer->s->scolonsep_set = 1; } else if (!strcasecmp(key, "failonstatus")) { char *val_split; @@ -406,6 +410,7 @@ static const char *set_balancer_param(pr balancer->failontimeout = 0; else return "failontimeout must be On|Off"; + balancer->failontimeout_set = 1; } else if (!strcasecmp(key, "nonce")) { if (!strcasecmp(val, "None")) { @@ -416,12 +421,14 @@ static const char *set_balancer_param(pr 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")) @@ -430,6 +437,7 @@ static const char *set_balancer_param(pr balancer->s->forcerecovery = 0; else return "forcerecovery must be On|Off"; + balancer->s->forcerecovery_set = 1; } else { return "unknown Balancer parameter"; @@ -1279,6 +1287,99 @@ static void * create_proxy_config(apr_po 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)); @@ -1303,7 +1404,7 @@ static void * merge_proxy_config(apr_poo 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; Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.h URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy.h?rev=1667707&r1=1667706&r2=1667707&view=diff ============================================================================== --- httpd/httpd/trunk/modules/proxy/mod_proxy.h (original) +++ httpd/httpd/trunk/modules/proxy/mod_proxy.h Thu Mar 19 11:29:55 2015 @@ -443,6 +443,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))) @@ -463,6 +468,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; }; struct proxy_balancer_method {