From 9fac5c4376bdaa206ba877d74d71e77af8c90849 Mon Sep 17 00:00:00 2001 From: Mladen Turk Date: Mon, 11 Apr 2005 08:45:15 +0000 Subject: [PATCH] Add failover to mod proxy. If the service is unavailable, check another worker in case this is balancer request. In case the error in unrecoverable, fail with returned status code. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@160848 13f79535-47bb-0310-9956-ffa450edef68 --- modules/proxy/mod_proxy.c | 45 +++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index dce3bf3394..f3ad42be2f 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -515,7 +515,7 @@ static int proxy_needsdomain(request_rec *r, const char *url, const char *domain static int proxy_handler(request_rec *r) { - char *url, *scheme, *p; + char *uri, *scheme, *p; const char *p2; void *sconf = r->server->module_config; proxy_server_conf *conf = (proxy_server_conf *) @@ -573,8 +573,8 @@ static int proxy_handler(request_rec *r) apr_table_set(r->headers_in, "Max-Forwards", apr_psprintf(r->pool, "%ld", (maxfwd > 0) ? maxfwd : 0)); - url = r->filename + 6; - p = strchr(url, ':'); + uri = r->filename + 6; + p = strchr(uri, ':'); if (p == NULL) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "proxy_handler no URL in %s", r->filename); @@ -583,12 +583,12 @@ static int proxy_handler(request_rec *r) /* If the host doesn't have a domain name, add one and redirect. */ if (conf->domain != NULL) { - rc = proxy_needsdomain(r, url, conf->domain); + rc = proxy_needsdomain(r, uri, conf->domain); if (ap_is_HTTP_REDIRECT(rc)) return HTTP_MOVED_PERMANENTLY; } - scheme = apr_pstrndup(r->pool, url, p - url); + scheme = apr_pstrndup(r->pool, uri, p - uri); /* Check URI's destination host against NoProxy hosts */ /* Bypass ProxyRemote server lookup if configured as NoProxy */ for (direct_connect = i = 0; i < conf->dirconn->nelts && @@ -602,7 +602,7 @@ static int proxy_handler(request_rec *r) #endif do { - + char *url = uri; /* Try to obtain the most suitable worker */ access_status = ap_proxy_pre_request(&worker, &balancer, r, conf, &url); if (access_status != OK) @@ -648,10 +648,37 @@ static int proxy_handler(request_rec *r) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Running scheme %s handler (attempt %d)", scheme, attempts); - if ((access_status = proxy_run_scheme_handler(r, worker, conf, - url, NULL, 0)) == OK) + access_status = proxy_run_scheme_handler(r, worker, conf, + url, NULL, 0); + if (access_status == OK) + break; + else if (access_status == HTTP_INTERNAL_SERVER_ERROR) { + /* Unrecoverable server error. + * We can not failover to another worker. + * Mark the worker as unusable if member of load balancer + */ + if (balancer) + worker->s->status |= PROXY_WORKER_IN_ERROR; break; - + } + else if (access_status == HTTP_SERVICE_UNAVAILABLE) { + /* Recoverable server error. + * We can failover to another worker + * Mark the worker as unusable if member of load balancer + */ + if (balancer) { + worker->s->status |= PROXY_WORKER_IN_ERROR; + } + } + else { + /* Unrecoverable error. + * Return the origin status code to the client. + */ + break; + } + /* Try again if the worker is unusable and the service is + * unavailable. + */ } while (!PROXY_WORKER_IS_USABLE(worker) && max_attempts > attempts++); -- 2.50.1