diff options
Diffstat (limited to 'modules/proxy/proxy_util.c')
-rw-r--r-- | modules/proxy/proxy_util.c | 78 |
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); |