You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by mi...@apache.org on 2021/08/22 09:51:33 UTC
svn commit: r1892522 - in /httpd/httpd/branches/2.4.x: STATUS
include/ap_mmn.h modules/proxy/mod_proxy.h modules/proxy/mod_proxy_balancer.c
Author: minfrin
Date: Sun Aug 22 09:51:33 2021
New Revision: 1892522
URL: http://svn.apache.org/viewvc?rev=1892522&view=rev
Log:
Backport:
*) back port the add of balancer_manage in mod_proxy_balancer.
trunk patch: http://svn.apache.org/r1859235
http://svn.apache.org/r1887176
http://svn.apache.org/r1887359
http://svn.apache.org/r1887144
Backport version for 2.4.x of patch:
https://people.apache.org/~jfclere/patches/patch.210810.txt
+1: jfclere, jim, minfrin
Modified:
httpd/httpd/branches/2.4.x/STATUS
httpd/httpd/branches/2.4.x/include/ap_mmn.h
httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.h
httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_balancer.c
Modified: httpd/httpd/branches/2.4.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/STATUS?rev=1892522&r1=1892521&r2=1892522&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/STATUS (original)
+++ httpd/httpd/branches/2.4.x/STATUS Sun Aug 22 09:51:33 2021
@@ -142,20 +142,6 @@ RELEASE SHOWSTOPPERS:
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- *) back port the add of balancer_manage in mod_proxy_balancer.
- trunk patch: http://svn.apache.org/r1859235
- http://svn.apache.org/r1887176
- http://svn.apache.org/r1887359
- http://svn.apache.org/r1887144
- Backport version for 2.4.x of patch:
- https://people.apache.org/~jfclere/patches/patch.210810.txt
- +1: jfclere, jim, minfrin
- jfclere: The previous proposal was removing the Referer check.
- jorton: r1859235 has an "ok2change" param in the newly added
- balancer_process_balancer_worker() but this is missing in the
- backport patch, maybe include r1887144 for completeness?
- jfclere: Fixed: Added in the patch.210810.txt
-
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
[ New proposals should be added at the end of the list ]
Modified: httpd/httpd/branches/2.4.x/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/include/ap_mmn.h?rev=1892522&r1=1892521&r2=1892522&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/include/ap_mmn.h (original)
+++ httpd/httpd/branches/2.4.x/include/ap_mmn.h Sun Aug 22 09:51:33 2021
@@ -574,6 +574,7 @@
* mod_dav.h.
* 20120211.112 (2.4.49-dev) Add deliver_report and gather_reports hooks.
* 20120211.113 (2.4.49-dev) Add method_precondition hook.
+ * 20120211.114 (2.4.49-dev) Add optional balancer_manage function.
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -581,7 +582,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20120211
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 113 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 114 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
Modified: httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.h?rev=1892522&r1=1892521&r2=1892522&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy.h Sun Aug 22 09:51:33 2021
@@ -1169,6 +1169,16 @@ PROXY_DECLARE(apr_status_t) ap_proxy_syn
server_rec *s,
proxy_server_conf *conf);
+/**
+ * Configure and create workers (and balancer) in mod_balancer.
+ * @param r request
+ * @param params table with the parameters like b=mycluster etc.
+ * @return 404 when the worker/balancer doesn't exist,
+ * 400 if something is invalid
+ * 200 for success.
+ */
+APR_DECLARE_OPTIONAL_FN(apr_status_t, balancer_manage,
+ (request_rec *, apr_table_t *params));
/**
* Find the matched alias for this request and setup for proxy handler
Modified: httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_balancer.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_balancer.c?rev=1892522&r1=1892521&r2=1892522&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_balancer.c (original)
+++ httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_balancer.c Sun Aug 22 09:51:33 2021
@@ -1120,119 +1120,20 @@ static int safe_referer(request_rec *r,
return strcasecmp(uri.hostname, ap_get_server_name(r)) == 0;
}
-/* Manages the loadfactors and member status
- * The balancer, worker and nonce are obtained from
- * the request args (?b=...&w=...&nonce=....).
- * All other params are pulled from any POST
- * data that exists.
- * TODO:
- * /.../<whatever>/balancer/worker/nonce
+/*
+ * Process the paramters and add or update the worker of the
+ * balancer. Must only be called if the nonce has been validated to
+ * match, to avoid XSS attacks.
*/
-static int balancer_handler(request_rec *r)
+static int balancer_process_balancer_worker(request_rec *r, proxy_server_conf *conf,
+ proxy_balancer *bsel,
+ proxy_worker *wsel,
+ apr_table_t *params)
+
{
- void *sconf;
- proxy_server_conf *conf;
- proxy_balancer *balancer, *bsel = NULL;
- proxy_worker *worker, *wsel = NULL;
- proxy_worker **workers = NULL;
- apr_table_t *params;
- int i, n;
- int ok2change = 1;
- const char *name, *ref;
- const char *action;
apr_status_t rv;
-
- /* is this for us? */
- if (strcmp(r->handler, "balancer-manager")) {
- return DECLINED;
- }
-
- r->allowed = 0
- | (AP_METHOD_BIT << M_GET)
- | (AP_METHOD_BIT << M_POST);
- if ((r->method_number != M_GET) && (r->method_number != M_POST)) {
- return DECLINED;
- }
-
- sconf = r->server->module_config;
- conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
- params = apr_table_make(r->pool, 10);
-
- balancer = (proxy_balancer *)conf->balancers->elts;
- for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
-#if APR_HAS_THREADS
- if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01189)
- "%s: Lock failed for balancer_handler",
- balancer->s->name);
- }
-#endif
- ap_proxy_sync_balancer(balancer, r->server, conf);
-#if APR_HAS_THREADS
- if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01190)
- "%s: Unlock failed for balancer_handler",
- balancer->s->name);
- }
-#endif
- }
-
- if (r->args && (r->method_number == M_GET)) {
- const char *allowed[] = { "w", "b", "nonce", "xml", NULL };
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01191) "parsing r->args");
-
- push2table(r->args, params, allowed, r->pool);
- }
- if (r->method_number == M_POST) {
- apr_bucket_brigade *ib;
- apr_size_t len = 1024;
- char *buf = apr_pcalloc(r->pool, len+1);
-
- ib = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
- rv = ap_get_brigade(r->input_filters, ib, AP_MODE_READBYTES,
- APR_BLOCK_READ, len);
- if (rv != APR_SUCCESS) {
- return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
- }
- apr_brigade_flatten(ib, buf, &len);
- buf[len] = '\0';
- push2table(buf, params, NULL, r->pool);
- }
-
- /* Ignore parameters if this looks like XSRF */
- ref = apr_table_get(r->headers_in, "Referer");
- if (apr_table_elts(params)
- && (!ref || !safe_referer(r, ref))) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10187)
- "ignoring params in balancer-manager cross-site access");
- apr_table_clear(params);
- }
-
- if ((name = apr_table_get(params, "b")))
- bsel = ap_proxy_get_balancer(r->pool, conf,
- apr_pstrcat(r->pool, BALANCER_PREFIX, name, NULL), 0);
-
- if ((name = apr_table_get(params, "w"))) {
- wsel = ap_proxy_get_worker(r->pool, bsel, conf, name);
- }
-
-
- /* Check that the supplied nonce matches this server's nonce;
- * otherwise ignore all parameters, to prevent a CSRF attack. */
- if (!bsel ||
- (*bsel->s->nonce &&
- (
- (name = apr_table_get(params, "nonce")) == NULL ||
- strcmp(bsel->s->nonce, name) != 0
- )
- )
- ) {
- apr_table_clear(params);
- ok2change = 0;
- }
-
/* First set the params */
- if (wsel && ok2change) {
+ if (wsel) {
const char *val;
int was_usable = PROXY_WORKER_IS_USABLE(wsel);
@@ -1341,7 +1242,7 @@ static int balancer_handler(request_rec
}
- if (bsel && ok2change) {
+ if (bsel) {
const char *val;
int ival;
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01193)
@@ -1488,11 +1389,62 @@ static int balancer_handler(request_rec
}
}
+ return APR_SUCCESS;
+}
+
+/*
+ * Process a request for balancer or worker management from another module
+ */
+static apr_status_t balancer_manage(request_rec *r, apr_table_t *params)
+{
+ void *sconf;
+ proxy_server_conf *conf;
+ proxy_balancer *bsel = NULL;
+ proxy_worker *wsel = NULL;
+ const char *name;
+ sconf = r->server->module_config;
+ conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
+
+ /* Process the parameters */
+ if ((name = apr_table_get(params, "b"))) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "balancer_manage "
+ "balancer: %s", name);
+ bsel = ap_proxy_get_balancer(r->pool, conf,
+ apr_pstrcat(r->pool, BALANCER_PREFIX, name, NULL), 0);
+ }
+
+ if ((name = apr_table_get(params, "w"))) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "balancer_manage "
+ "worker: %s", name);
+ wsel = ap_proxy_get_worker(r->pool, bsel, conf, name);
+ }
+ if (bsel) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "balancer_manage "
+ "balancer: %s", bsel->s->name);
+ return(balancer_process_balancer_worker(r, conf, bsel, wsel, params));
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "balancer_manage failed: "
+ "No balancer!");
+ return HTTP_BAD_REQUEST;
+}
+/*
+ * builds the page and links to configure via HTLM or XML.
+ */
+static void balancer_display_page(request_rec *r, proxy_server_conf *conf,
+ proxy_balancer *bsel,
+ proxy_worker *wsel,
+ int usexml)
+{
+ const char *action;
+ proxy_balancer *balancer;
+ proxy_worker *worker;
+ proxy_worker **workers;
+ int i, n;
action = ap_construct_url(r->pool, r->uri, r);
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01204) "genning page");
- if (apr_table_get(params, "xml")) {
+ if (usexml) {
char date[APR_RFC822_DATE_LEN];
ap_set_content_type(r, "text/xml");
ap_rputs("<?xml version='1.0' encoding='UTF-8' ?>\n", r);
@@ -1938,6 +1890,123 @@ static int balancer_handler(request_rec
ap_rputs("</body></html>\n", r);
ap_rflush(r);
}
+}
+
+/* Manages the loadfactors and member status
+ * The balancer, worker and nonce are obtained from
+ * the request args (?b=...&w=...&nonce=....).
+ * All other params are pulled from any POST
+ * data that exists.
+ * TODO:
+ * /.../<whatever>/balancer/worker/nonce
+ */
+static int balancer_handler(request_rec *r)
+{
+ void *sconf;
+ proxy_server_conf *conf;
+ proxy_balancer *balancer, *bsel = NULL;
+ proxy_worker *wsel = NULL;
+ apr_table_t *params;
+ int i;
+ const char *name, *ref;
+ apr_status_t rv;
+
+ /* is this for us? */
+ if (strcmp(r->handler, "balancer-manager")) {
+ return DECLINED;
+ }
+
+ r->allowed = 0
+ | (AP_METHOD_BIT << M_GET)
+ | (AP_METHOD_BIT << M_POST);
+ if ((r->method_number != M_GET) && (r->method_number != M_POST)) {
+ return DECLINED;
+ }
+
+ sconf = r->server->module_config;
+ conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
+ params = apr_table_make(r->pool, 10);
+
+ balancer = (proxy_balancer *)conf->balancers->elts;
+ for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
+#if APR_HAS_THREADS
+ if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01189)
+ "%s: Lock failed for balancer_handler",
+ balancer->s->name);
+ }
+#endif
+ ap_proxy_sync_balancer(balancer, r->server, conf);
+#if APR_HAS_THREADS
+ if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01190)
+ "%s: Unlock failed for balancer_handler",
+ balancer->s->name);
+ }
+#endif
+ }
+
+ if (r->args && (r->method_number == M_GET)) {
+ const char *allowed[] = { "w", "b", "nonce", "xml", NULL };
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01191) "parsing r->args");
+
+ push2table(r->args, params, allowed, r->pool);
+ }
+ if (r->method_number == M_POST) {
+ apr_bucket_brigade *ib;
+ apr_size_t len = 1024;
+ char *buf = apr_pcalloc(r->pool, len+1);
+
+ ib = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
+ rv = ap_get_brigade(r->input_filters, ib, AP_MODE_READBYTES,
+ APR_BLOCK_READ, len);
+ if (rv != APR_SUCCESS) {
+ return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
+ }
+ apr_brigade_flatten(ib, buf, &len);
+ buf[len] = '\0';
+ push2table(buf, params, NULL, r->pool);
+ }
+
+ /* Ignore parameters if this looks like XSRF */
+ ref = apr_table_get(r->headers_in, "Referer");
+ if (apr_table_elts(params)
+ && (!ref || !safe_referer(r, ref))) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10187)
+ "ignoring params in balancer-manager cross-site access %s: %s", ref, ap_get_server_name(r));
+ apr_table_clear(params);
+ }
+
+ /* Process the parameters */
+ if ((name = apr_table_get(params, "b")))
+ bsel = ap_proxy_get_balancer(r->pool, conf,
+ apr_pstrcat(r->pool, BALANCER_PREFIX, name, NULL), 0);
+
+ if ((name = apr_table_get(params, "w"))) {
+ wsel = ap_proxy_get_worker(r->pool, bsel, conf, name);
+ }
+
+
+ /* Check that the supplied nonce matches this server's nonce;
+ * otherwise ignore all parameters, to prevent a CSRF
+ * attack. */
+ if (bsel
+ && (*bsel->s->nonce
+ && ((name = apr_table_get(params, "nonce")) != NULL
+ && strcmp(bsel->s->nonce, name) == 0))) {
+ /* Process the parameters and add the worker to the balancer */
+ rv = balancer_process_balancer_worker(r, conf, bsel, wsel, params);
+ if (rv != APR_SUCCESS) {
+ return HTTP_BAD_REQUEST;
+ }
+ }
+
+ /* display the HTML or XML page */
+ if (apr_table_get(params, "xml")) {
+ balancer_display_page(r, conf, bsel, wsel, 1);
+ } else {
+ balancer_display_page(r, conf, bsel, wsel, 0);
+ }
return DONE;
}
@@ -1986,6 +2055,7 @@ static void ap_proxy_balancer_register_h
static const char *const aszPred[] = { "mpm_winnt.c", "mod_slotmem_shm.c", NULL};
static const char *const aszPred2[] = { "mod_proxy.c", NULL};
/* manager handler */
+ APR_REGISTER_OPTIONAL_FN(balancer_manage);
ap_hook_post_config(balancer_post_config, aszPred2, NULL, APR_HOOK_MIDDLE);
ap_hook_pre_config(balancer_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(balancer_handler, NULL, NULL, APR_HOOK_FIRST);