summaryrefslogtreecommitdiff
path: root/modules/proxy/proxy_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/proxy/proxy_util.c')
-rw-r--r--modules/proxy/proxy_util.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index 763073c1..0d2c8563 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -54,24 +54,6 @@ typedef struct {
const char *proxy_auth; /* Proxy authorization */
} forward_info;
-/* Keep synced with mod_proxy.h! */
-static struct wstat {
- unsigned int bit;
- char flag;
- const char *name;
-} wstat_tbl[] = {
- {PROXY_WORKER_INITIALIZED, PROXY_WORKER_INITIALIZED_FLAG, "Init "},
- {PROXY_WORKER_IGNORE_ERRORS, PROXY_WORKER_IGNORE_ERRORS_FLAG, "Ign "},
- {PROXY_WORKER_DRAIN, PROXY_WORKER_DRAIN_FLAG, "Drn "},
- {PROXY_WORKER_IN_SHUTDOWN, PROXY_WORKER_IN_SHUTDOWN_FLAG, "Shut "},
- {PROXY_WORKER_DISABLED, PROXY_WORKER_DISABLED_FLAG, "Dis "},
- {PROXY_WORKER_STOPPED, PROXY_WORKER_STOPPED_FLAG, "Stop "},
- {PROXY_WORKER_IN_ERROR, PROXY_WORKER_IN_ERROR_FLAG, "Err "},
- {PROXY_WORKER_HOT_STANDBY, PROXY_WORKER_HOT_STANDBY_FLAG, "Stby "},
- {PROXY_WORKER_FREE, PROXY_WORKER_FREE_FLAG, "Free "},
- {0x0, '\0', NULL}
-};
-
/* Global balancer counter */
int PROXY_DECLARE_DATA proxy_lb_workers = 0;
static int lb_workers_limit = 0;
@@ -1375,7 +1357,7 @@ static apr_status_t connection_cleanup(void *theconn)
* If the connection pool is NULL the worker
* cleanup has been run. Just return.
*/
- if (!worker->cp) {
+ if (!worker->cp->pool) {
return APR_SUCCESS;
}
@@ -1498,10 +1480,11 @@ static apr_status_t connection_constructor(void **resource, void *params,
static apr_status_t connection_destructor(void *resource, void *params,
apr_pool_t *pool)
{
- proxy_conn_rec *conn = (proxy_conn_rec *)resource;
+ proxy_worker *worker = params;
/* Destroy the pool only if not called from reslist_destroy */
- if (conn->worker->cp->pool) {
+ if (worker->cp->pool) {
+ proxy_conn_rec *conn = resource;
apr_pool_destroy(conn->pool);
}
@@ -1698,6 +1681,7 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
memset(wshared, 0, sizeof(proxy_worker_shared));
+ wshared->port = (uri.port ? uri.port : ap_proxy_port_of_scheme(uri.scheme));
if (uri.port && uri.port == ap_proxy_port_of_scheme(uri.scheme)) {
uri.port = 0;
}
@@ -1712,11 +1696,13 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
if (PROXY_STRNCPY(wshared->hostname, uri.hostname) != APR_SUCCESS) {
return apr_psprintf(p, "worker hostname (%s) too long", uri.hostname);
}
- wshared->port = uri.port;
wshared->flush_packets = flush_off;
wshared->flush_wait = PROXY_FLUSH_WAIT;
wshared->is_address_reusable = 1;
wshared->lbfactor = 1;
+ wshared->passes = 1;
+ wshared->fails = 1;
+ wshared->interval = apr_time_from_sec(HCHECK_WATHCHDOG_DEFAULT_INTERVAL);
wshared->smax = -1;
wshared->hash.def = ap_proxy_hashfunc(wshared->name, PROXY_HASHFUNC_DEFAULT);
wshared->hash.fnv = ap_proxy_hashfunc(wshared->name, PROXY_HASHFUNC_FNV);
@@ -1730,6 +1716,9 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
else {
*wshared->uds_path = '\0';
}
+ if (!balancer) {
+ wshared->status |= PROXY_WORKER_IGNORE_ERRORS;
+ }
(*worker)->hash = wshared->hash;
(*worker)->context = NULL;
@@ -1896,7 +1885,14 @@ static int ap_proxy_retry_worker(const char *proxy_function, proxy_worker *worke
server_rec *s)
{
if (worker->s->status & PROXY_WORKER_IN_ERROR) {
- if (apr_time_now() > worker->s->error_time + worker->s->retry) {
+ if (PROXY_WORKER_IS(worker, PROXY_WORKER_STOPPED)) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(3305)
+ "%s: Won't retry worker (%s): stopped",
+ proxy_function, worker->s->hostname);
+ return DECLINED;
+ }
+ if ((worker->s->status & PROXY_WORKER_IGNORE_ERRORS)
+ || apr_time_now() > worker->s->error_time + worker->s->retry) {
++worker->s->retries;
worker->s->status &= ~PROXY_WORKER_IN_ERROR;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00932)
@@ -2430,7 +2426,7 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
#endif
#if USE_ALTERNATE_IS_CONNECTED && defined(APR_MSG_PEEK)
-static int is_socket_connected(apr_socket_t *socket)
+PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *socket)
{
apr_pollfd_t pfds[1];
apr_status_t status;
@@ -2468,7 +2464,7 @@ static int is_socket_connected(apr_socket_t *socket)
}
#else
-static int is_socket_connected(apr_socket_t *sock)
+PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *sock)
{
apr_size_t buffer_len = 1;
@@ -2590,12 +2586,12 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
}
-#if APR_HAVE_SYS_UN_H
/* TODO: In APR 2.x: Extend apr_sockaddr_t to possibly be a path !!! */
PROXY_DECLARE(apr_status_t) ap_proxy_connect_uds(apr_socket_t *sock,
const char *uds_path,
apr_pool_t *p)
{
+#if APR_HAVE_SYS_UN_H
apr_status_t rv;
apr_os_sock_t rawsock;
apr_interval_time_t t;
@@ -2637,8 +2633,10 @@ PROXY_DECLARE(apr_status_t) ap_proxy_connect_uds(apr_socket_t *sock,
}
return APR_SUCCESS;
-}
+#else
+ return APR_ENOTIMPL;
#endif
+}
PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
proxy_conn_rec *conn,
@@ -2657,7 +2655,7 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
(proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
if (conn->sock) {
- if (!(connected = is_socket_connected(conn->sock))) {
+ if (!(connected = ap_proxy_is_socket_connected(conn->sock))) {
/* This clears conn->scpool (and associated data), so backup and
* restore any ssl_hostname for this connection set earlier by
* ap_proxy_determine_connection().
@@ -3073,7 +3071,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_set_wstatus(char c, int set, proxy_worker *
{
unsigned int *status = &w->s->status;
char flag = toupper(c);
- struct wstat *pwt = wstat_tbl;
+ proxy_wstat_t *pwt = proxy_wstat_tbl;
while (pwt->bit) {
if (flag == pwt->flag) {
if (set)
@@ -3091,12 +3089,15 @@ PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w)
{
char *ret = "";
unsigned int status = w->s->status;
- struct wstat *pwt = wstat_tbl;
+ proxy_wstat_t *pwt = proxy_wstat_tbl;
while (pwt->bit) {
if (status & pwt->bit)
ret = apr_pstrcat(p, ret, pwt->name, NULL);
pwt++;
}
+ if (!*ret) {
+ ret = "??? ";
+ }
if (PROXY_WORKER_IS_USABLE(w))
ret = apr_pstrcat(p, ret, "Ok ", NULL);
return ret;
@@ -3498,7 +3499,9 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
}
proxy_run_fixups(r);
- ap_proxy_clear_connection(r, r->headers_in);
+ if (ap_proxy_clear_connection(r, r->headers_in) < 0) {
+ return HTTP_BAD_REQUEST;
+ }
/* send request headers */
headers_in_array = apr_table_elts(r->headers_in);
@@ -3624,6 +3627,8 @@ static proxy_schemes_t pschemes[] =
{"fcgi", 8000},
{"ajp", AJP13_DEF_PORT},
{"scgi", SCGI_DEF_PORT},
+ {"h2c", DEFAULT_HTTP_PORT},
+ {"h2", DEFAULT_HTTPS_PORT},
{ NULL, 0xFFFF } /* unknown port */
};
@@ -3767,6 +3772,17 @@ PROXY_DECLARE(apr_status_t) ap_proxy_transfer_between_connections(
return rv;
}
+PROXY_DECLARE (const char *) ap_proxy_show_hcmethod(hcmethod_t method)
+{
+ proxy_hcmethods_t *m = proxy_hcmethods;
+ for (; m->name; m++) {
+ if (m->method == method) {
+ return m->name;
+ }
+ }
+ return "???";
+}
+
void proxy_util_register_hooks(apr_pool_t *p)
{
APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker);