Index: modules/proxy/mod_proxy_balancer.c =================================================================== --- modules/proxy/mod_proxy_balancer.c (revision 1559678) +++ modules/proxy/mod_proxy_balancer.c (working copy) @@ -118,7 +118,8 @@ static void init_balancer_members(apr_pool_t *p, s int worker_is_initialized; proxy_worker *worker = *workers; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01158) - "Looking at %s -> %s initialized?", balancer->s->name, worker->s->name); + "Looking at %s -> %s initialized?", balancer->s->name, + ap_proxy_worker_name(p, worker)); worker_is_initialized = PROXY_WORKER_IS_INITIALIZED(worker); if (!worker_is_initialized) { ap_proxy_initialize_worker(worker, s, p); @@ -638,10 +639,11 @@ static int proxy_balancer_post_request(proxy_worke int val = ((int *)balancer->errstatuses->elts)[i]; if (r->status == val) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01174) - "%s: Forcing worker (%s) into error state " + "%s: Forcing worker (%s) into error state " "due to status code %d matching 'failonstatus' " "balancer parameter", - balancer->s->name, worker->s->name, val); + balancer->s->name, ap_proxy_worker_name(r->pool, worker), + val); worker->s->status |= PROXY_WORKER_IN_ERROR; worker->s->error_time = apr_time_now(); break; @@ -654,7 +656,7 @@ static int proxy_balancer_post_request(proxy_worke ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02460) "%s: Forcing worker (%s) into error state " "due to timeout and 'failonstatus' parameter being set", - balancer->s->name, worker->s->name); + balancer->s->name, ap_proxy_worker_name(r->pool, worker)); worker->s->status |= PROXY_WORKER_IN_ERROR; worker->s->error_time = apr_time_now(); @@ -1282,7 +1284,7 @@ static int balancer_handler(request_rec *r) worker = *workers; /* Start proxy_worker */ ap_rputs(" \n", r); - ap_rvputs(r, " ", worker->s->name, + ap_rvputs(r, " ", ap_proxy_worker_name(r->pool, worker), "\n", NULL); ap_rvputs(r, " ", worker->s->scheme, "\n", NULL); @@ -1531,7 +1533,8 @@ static int balancer_handler(request_rec *r) ap_escape_uri(r->pool, worker->s->name), "&nonce=", balancer->s->nonce, "\">", NULL); - ap_rvputs(r, worker->s->name, "", NULL); + ap_rvputs(r, (*worker->s->uds_path ? "" : ""), ap_proxy_worker_name(r->pool, worker), + (*worker->s->uds_path ? "" : ""), "", NULL); ap_rvputs(r, "", ap_escape_html(r->pool, worker->s->route), NULL); ap_rvputs(r, "", @@ -1556,7 +1559,7 @@ static int balancer_handler(request_rec *r) ap_rputs("
\n", r); if (wsel && bsel) { ap_rputs("

Edit worker settings for ", r); - ap_rvputs(r, wsel->s->name, "

\n", NULL); + ap_rvputs(r, (*wsel->s->uds_path?"":""), ap_proxy_worker_name(r->pool, wsel), (*wsel->s->uds_path?"":""), "\n", NULL); ap_rputs("
pool, action), "\">\n", NULL); ap_rputs("
\n
Load factor: +#endif +#if (APR_MAJOR_VERSION < 2) +#include "apr_support.h" /* for apr_wait_for_io_or_timeout() */ +#endif + APLOG_USE_MODULE(proxy); /* @@ -86,14 +93,20 @@ PROXY_DECLARE(apr_status_t) ap_proxy_strncpy(char char *thenil; apr_size_t thelen; + /* special case handling */ + if (!dlen) { + /* XXX: APR_ENOSPACE would be better */ + return APR_EGENERAL; + } + if (!src) { + *dst = '\0'; + return APR_SUCCESS; + } thenil = apr_cpystrn(dst, src, dlen); thelen = thenil - dst; - /* Assume the typical case is smaller copying into bigger - so we have a fast return */ - if ((thelen < dlen-1) || ((strlen(src)) == thelen)) { + if (src[thelen] == '\0') { return APR_SUCCESS; } - /* XXX: APR_ENOSPACE would be better */ return APR_EGENERAL; } @@ -1218,11 +1231,11 @@ PROXY_DECLARE(apr_status_t) ap_proxy_share_balance } else { action = "re-using"; } + balancer->s = shm; + balancer->s->index = i; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02337) "%s shm[%d] (0x%pp) for %s", action, i, (void *)shm, balancer->s->name); - balancer->s = shm; - balancer->s->index = i; /* the below should always succeed */ lbmethod = ap_lookup_provider(PROXY_LBMETHOD, balancer->s->lbpname, "0"); if (lbmethod) { @@ -1356,7 +1369,7 @@ static apr_status_t connection_cleanup(void *theco ap_log_perror(APLOG_MARK, APLOG_ERR, 0, conn->pool, APLOGNO(00923) "Pooled connection 0x%pp for worker %s has been" " already returned to the connection pool.", conn, - worker->s->name); + ap_proxy_worker_name(conn->pool, worker)); return APR_SUCCESS; } @@ -1480,6 +1493,16 @@ static apr_status_t connection_destructor(void *re * WORKER related... */ +PROXY_DECLARE(char *) ap_proxy_worker_name(apr_pool_t *p, + proxy_worker *worker) +{ + if (!(*worker->s->uds_path) || !p) { + /* just in case */ + return worker->s->name; + } + return apr_pstrcat(p, "unix:", worker->s->uds_path, "|", worker->s->name, NULL); +} + PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p, proxy_balancer *balancer, proxy_server_conf *conf, @@ -1495,6 +1518,10 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker( char *url_copy; int i; + if (!url) { + return NULL; + } + c = ap_strchr_c(url, ':'); if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') { return NULL; @@ -1573,20 +1600,47 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_p int do_malloc) { int rv; - apr_uri_t uri; + apr_uri_t uri, urisock; proxy_worker_shared *wshared; - char *ptr; + char *ptr, *sockpath = NULL; + /* + * Look to see if we are using UDS: + * require format: unix:/path/foo/bar.sock|http://ignored/path2/ + * This results in talking http to the socket at /path/foo/bar.sock + */ + ptr = ap_strchr((char *)url, '|'); + if (ptr) { + *ptr = '\0'; + rv = apr_uri_parse(p, url, &urisock); + if (rv == APR_SUCCESS && !strcasecmp(urisock.scheme, "unix")) { + sockpath = ap_runtime_dir_relative(p, urisock.path);; + url = ptr+1; /* so we get the scheme for the uds */ + } + else { + *ptr = '|'; + } + } rv = apr_uri_parse(p, url, &uri); if (rv != APR_SUCCESS) { - return "Unable to parse URL"; + return apr_pstrcat(p, "Unable to parse URL: ", url, NULL); } - if (!uri.hostname || !uri.scheme) { - return "URL must be absolute!"; + if (!uri.scheme) { + return apr_pstrcat(p, "URL must be absolute!: ", url, NULL); } - - ap_str_tolower(uri.hostname); + /* allow for unix:/path|http: */ + if (!uri.hostname) { + if (sockpath) { + uri.hostname = "localhost"; + } + else { + return apr_pstrcat(p, "URL must be absolute!: ", url, NULL); + } + } + else { + ap_str_tolower(uri.hostname); + } ap_str_tolower(uri.scheme); /* * Workers can be associated w/ balancers or on their @@ -1642,7 +1696,16 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_p wshared->hash.def = ap_proxy_hashfunc(wshared->name, PROXY_HASHFUNC_DEFAULT); wshared->hash.fnv = ap_proxy_hashfunc(wshared->name, PROXY_HASHFUNC_FNV); wshared->was_malloced = (do_malloc != 0); + if (sockpath) { + if (PROXY_STRNCPY(wshared->uds_path, sockpath) != APR_SUCCESS) { + return apr_psprintf(p, "worker uds path (%s) too long", sockpath); + } + } + else { + *wshared->uds_path = '\0'; + } + (*worker)->hash = wshared->hash; (*worker)->context = NULL; (*worker)->cp = NULL; @@ -1670,12 +1733,18 @@ PROXY_DECLARE(apr_status_t) ap_proxy_share_worker( } else { action = "re-using"; } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02338) - "%s shm[%d] (0x%pp) for worker: %s", action, i, (void *)shm, - worker->s->name); - worker->s = shm; worker->s->index = i; + { + apr_pool_t *pool; + apr_pool_create(&pool, ap_server_conf->process->pool); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02338) + "%s shm[%d] (0x%pp) for worker: %s", action, i, (void *)shm, + ap_proxy_worker_name(pool, worker)); + if (pool) { + apr_pool_destroy(pool); + } + } return APR_SUCCESS; } @@ -1687,11 +1756,13 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_wo if (worker->s->status & PROXY_WORKER_INITIALIZED) { /* The worker is already initialized */ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00924) - "worker %s shared already initialized", worker->s->name); + "worker %s shared already initialized", + ap_proxy_worker_name(p, worker)); } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00925) - "initializing worker %s shared", worker->s->name); + "initializing worker %s shared", + ap_proxy_worker_name(p, worker)); /* Set default parameters */ if (!worker->s->retry_set) { worker->s->retry = apr_time_from_sec(PROXY_WORKER_DEFAULT_RETRY); @@ -1727,11 +1798,13 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_wo /* What if local is init'ed and shm isn't?? Even possible? */ if (worker->local_status & PROXY_WORKER_INITIALIZED) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00926) - "worker %s local already initialized", worker->s->name); + "worker %s local already initialized", + ap_proxy_worker_name(p, worker)); } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00927) - "initializing worker %s local", worker->s->name); + "initializing worker %s local", + ap_proxy_worker_name(p, worker)); apr_global_mutex_lock(proxy_mutex); /* Now init local worker data */ if (worker->tmutex == NULL) { @@ -2023,6 +2096,29 @@ PROXY_DECLARE(int) ap_proxy_acquire_connection(con (*conn)->close = 0; (*conn)->inreslist = 0; + if (*worker->s->uds_path) { + if ((*conn)->uds_path == NULL) { + /* use (*conn)->pool instead of worker->cp->pool to match lifetime */ + (*conn)->uds_path = apr_pstrdup((*conn)->pool, worker->s->uds_path); + } + if ((*conn)->uds_path) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02545) + "%s: has determined UDS as %s", + proxy_function, (*conn)->uds_path); + } + else { + /* should never happen */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02546) + "%s: cannot determine UDS (%s)", + proxy_function, worker->s->uds_path); + + } + } + else { + (*conn)->uds_path = NULL; + } + + return OK; } @@ -2094,7 +2190,7 @@ ap_proxy_determine_connection(apr_pool_t *p, reque * spilling the cached addr from the worker. */ if (!conn->hostname || !worker->s->is_address_reusable || - worker->s->disablereuse) { + worker->s->disablereuse || *worker->s->uds_path) { if (proxyname) { conn->hostname = apr_pstrdup(conn->pool, proxyname); conn->port = proxyport; @@ -2132,7 +2228,8 @@ ap_proxy_determine_connection(apr_pool_t *p, reque conn->port = uri->port; } socket_cleanup(conn); - if (!worker->s->is_address_reusable || worker->s->disablereuse) { + if (!(*worker->s->uds_path) && + (!worker->s->is_address_reusable || worker->s->disablereuse)) { /* * Only do a lookup if we should not reuse the backend address. * Otherwise we will look it up once for the worker. @@ -2143,7 +2240,7 @@ ap_proxy_determine_connection(apr_pool_t *p, reque conn->pool); } } - if (worker->s->is_address_reusable && !worker->s->disablereuse) { + if (!(*worker->s->uds_path) && worker->s->is_address_reusable && !worker->s->disablereuse) { /* * Looking up the backend address for the worker only makes sense if * we can reuse the address. @@ -2372,6 +2469,52 @@ static apr_status_t send_http_connect(proxy_conn_r } +#if APR_HAVE_SYS_UN_H +/* lifted from mod_proxy_fdpass.c; tweaked addrlen in connect() call */ +static apr_status_t socket_connect_un(apr_socket_t *sock, + struct sockaddr_un *sa) +{ + apr_status_t rv; + apr_os_sock_t rawsock; + apr_interval_time_t t; + + rv = apr_os_sock_get(&rawsock, sock); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_timeout_get(sock, &t); + if (rv != APR_SUCCESS) { + return rv; + } + + do { + const socklen_t addrlen = APR_OFFSETOF(struct sockaddr_un, sun_path) + + strlen(sa->sun_path) + 1; + rv = connect(rawsock, (struct sockaddr*)sa, addrlen); + } while (rv == -1 && errno == EINTR); + + if ((rv == -1) && (errno == EINPROGRESS || errno == EALREADY) + && (t > 0)) { +#if APR_MAJOR_VERSION < 2 + rv = apr_wait_for_io_or_timeout(NULL, sock, 0); +#else + rv = apr_socket_wait(sock, APR_WAIT_WRITE); +#endif + + if (rv != APR_SUCCESS) { + return rv; + } + } + + if (rv == -1 && errno != EISCONN) { + return errno; + } + + return APR_SUCCESS; +} +#endif + PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, proxy_conn_rec *conn, proxy_worker *worker, @@ -2396,93 +2539,131 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const proxy_function); } } - while (backend_addr && !connected) { - if ((rv = apr_socket_create(&newsock, backend_addr->family, - SOCK_STREAM, APR_PROTO_TCP, - conn->scpool)) != APR_SUCCESS) { - loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; - ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00952) - "%s: error creating fam %d socket for target %s", - proxy_function, - backend_addr->family, - worker->s->hostname); - /* - * this could be an IPv6 address from the DNS but the - * local machine won't give us an IPv6 socket; hopefully the - * DNS returned an additional address to try - */ - backend_addr = backend_addr->next; - continue; - } - conn->connection = NULL; + while ((backend_addr || conn->uds_path) && !connected) { +#if APR_HAVE_SYS_UN_H + if (conn->uds_path) + { + struct sockaddr_un sa; - if (worker->s->recv_buffer_size > 0 && - (rv = apr_socket_opt_set(newsock, APR_SO_RCVBUF, - worker->s->recv_buffer_size))) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00953) - "apr_socket_opt_set(SO_RCVBUF): Failed to set " - "ProxyReceiveBufferSize, using default"); - } + rv = apr_socket_create(&newsock, AF_UNIX, SOCK_STREAM, 0, + conn->scpool); + if (rv != APR_SUCCESS) { + loglevel = APLOG_ERR; + ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(02453) + "%s: error creating Unix domain socket for " + "target %s", + proxy_function, + worker->s->hostname); + break; + } + conn->connection = NULL; - rv = apr_socket_opt_set(newsock, APR_TCP_NODELAY, 1); - if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00954) - "apr_socket_opt_set(APR_TCP_NODELAY): " - "Failed to set"); - } + sa.sun_family = AF_UNIX; + apr_cpystrn(sa.sun_path, conn->uds_path, sizeof(sa.sun_path)); - /* Set a timeout for connecting to the backend on the socket */ - if (worker->s->conn_timeout_set) { - apr_socket_timeout_set(newsock, worker->s->conn_timeout); + rv = socket_connect_un(newsock, &sa); + if (rv != APR_SUCCESS) { + apr_socket_close(newsock); + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(02454) + "%s: attempt to connect to Unix domain socket " + "%s (%s) failed", + proxy_function, + conn->uds_path, + worker->s->hostname); + break; + } } - else if (worker->s->timeout_set) { - apr_socket_timeout_set(newsock, worker->s->timeout); - } - else if (conf->timeout_set) { - apr_socket_timeout_set(newsock, conf->timeout); - } - else { - apr_socket_timeout_set(newsock, s->timeout); - } - /* Set a keepalive option */ - if (worker->s->keepalive) { - if ((rv = apr_socket_opt_set(newsock, - APR_SO_KEEPALIVE, 1)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00955) - "apr_socket_opt_set(SO_KEEPALIVE): Failed to set" - " Keepalive"); + else +#endif + { + if ((rv = apr_socket_create(&newsock, backend_addr->family, + SOCK_STREAM, APR_PROTO_TCP, + conn->scpool)) != APR_SUCCESS) { + loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; + ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00952) + "%s: error creating fam %d socket for " + "target %s", + proxy_function, + backend_addr->family, + worker->s->hostname); + /* + * this could be an IPv6 address from the DNS but the + * local machine won't give us an IPv6 socket; hopefully the + * DNS returned an additional address to try + */ + backend_addr = backend_addr->next; + continue; } - } - ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s, - "%s: fam %d socket created to connect to %s", - proxy_function, backend_addr->family, worker->s->hostname); + conn->connection = NULL; - if (conf->source_address_set) { - local_addr = apr_pmemdup(conn->pool, conf->source_address, - sizeof(apr_sockaddr_t)); - local_addr->pool = conn->pool; - rv = apr_socket_bind(newsock, local_addr); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00956) - "%s: failed to bind socket to local address", - proxy_function); + if (worker->s->recv_buffer_size > 0 && + (rv = apr_socket_opt_set(newsock, APR_SO_RCVBUF, + worker->s->recv_buffer_size))) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00953) + "apr_socket_opt_set(SO_RCVBUF): Failed to set " + "ProxyReceiveBufferSize, using default"); } - } - /* make the connection out of the socket */ - rv = apr_socket_connect(newsock, backend_addr); + rv = apr_socket_opt_set(newsock, APR_TCP_NODELAY, 1); + if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00954) + "apr_socket_opt_set(APR_TCP_NODELAY): " + "Failed to set"); + } - /* if an error occurred, loop round and try again */ - if (rv != APR_SUCCESS) { - apr_socket_close(newsock); - loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; - ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00957) - "%s: attempt to connect to %pI (%s) failed", - proxy_function, - backend_addr, - worker->s->hostname); - backend_addr = backend_addr->next; - continue; + /* Set a timeout for connecting to the backend on the socket */ + if (worker->s->conn_timeout_set) { + apr_socket_timeout_set(newsock, worker->s->conn_timeout); + } + else if (worker->s->timeout_set) { + apr_socket_timeout_set(newsock, worker->s->timeout); + } + else if (conf->timeout_set) { + apr_socket_timeout_set(newsock, conf->timeout); + } + else { + apr_socket_timeout_set(newsock, s->timeout); + } + /* Set a keepalive option */ + if (worker->s->keepalive) { + if ((rv = apr_socket_opt_set(newsock, + APR_SO_KEEPALIVE, 1)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00955) + "apr_socket_opt_set(SO_KEEPALIVE): Failed to set" + " Keepalive"); + } + } + ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s, + "%s: fam %d socket created to connect to %s", + proxy_function, backend_addr->family, worker->s->hostname); + + if (conf->source_address_set) { + local_addr = apr_pmemdup(conn->pool, conf->source_address, + sizeof(apr_sockaddr_t)); + local_addr->pool = conn->pool; + rv = apr_socket_bind(newsock, local_addr); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00956) + "%s: failed to bind socket to local address", + proxy_function); + } + } + + /* make the connection out of the socket */ + rv = apr_socket_connect(newsock, backend_addr); + + /* if an error occurred, loop round and try again */ + if (rv != APR_SUCCESS) { + apr_socket_close(newsock); + loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; + ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00957) + "%s: attempt to connect to %pI (%s) failed", + proxy_function, + backend_addr, + worker->s->hostname); + backend_addr = backend_addr->next; + continue; + } } /* Set a timeout on the socket */ @@ -2498,7 +2679,7 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const conn->sock = newsock; - if (conn->forward) { + if (!conn->uds_path && conn->forward) { forward_info *forward = (forward_info *)conn->forward; /* * For HTTP CONNECT we need to prepend CONNECT request before @@ -2779,7 +2960,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer found = 1; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02402) "re-grabbing shm[%d] (0x%pp) for worker: %s", i, (void *)shm, - worker->s->name); + ap_proxy_worker_name(conf->pool, worker)); break; } } Index: modules/proxy/mod_proxy.c =================================================================== --- modules/proxy/mod_proxy.c (revision 1559678) +++ modules/proxy/mod_proxy.c (working copy) @@ -1370,7 +1370,6 @@ static void *merge_proxy_dir_config(apr_pool_t *p, return new; } - static const char * add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex) { @@ -1445,6 +1444,36 @@ static const char * return add_proxy(cmd, dummy, f1, r1, 1); } +static char *de_socketfy(apr_pool_t *p, char *url) +{ + char *ptr; + /* + * We could be passed a URL during the config stage that contains + * the UDS path... ignore it + */ + if (!strncasecmp(url, "unix:", 5) && + ((ptr = ap_strchr(url, '|')) != NULL)) { + /* move past the 'unix:...|' UDS path info */ + char *ret, *c; + + ret = ptr + 1; + /* special case: "unix:....|scheme:" is OK, expand + * to "unix:....|scheme://localhost" + * */ + c = ap_strchr(ret, ':'); + if (c == NULL) { + return NULL; + } + if (c[1] == '\0') { + return apr_pstrcat(p, ret, "//localhost", NULL); + } + else { + return ret; + } + } + return url; +} + static const char * add_pass(cmd_parms *cmd, void *dummy, const char *arg, int is_regex) { @@ -1536,7 +1565,7 @@ static const char * } new->fake = apr_pstrdup(cmd->pool, f); - new->real = apr_pstrdup(cmd->pool, r); + new->real = apr_pstrdup(cmd->pool, de_socketfy(cmd->pool, r)); new->flags = flags; if (use_regex) { new->regex = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); @@ -1572,7 +1601,7 @@ static const char * new->balancer = balancer; } else { - proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, r); + proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, de_socketfy(cmd->pool, r)); int reuse = 0; if (!worker) { const char *err = ap_proxy_define_worker(cmd->pool, &worker, NULL, conf, r, 0); @@ -1584,14 +1613,14 @@ static const char * reuse = 1; ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01145) "Sharing worker '%s' instead of creating new worker '%s'", - worker->s->name, new->real); + ap_proxy_worker_name(cmd->pool, worker), new->real); } for (i = 0; i < arr->nelts; i++) { if (reuse) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(01146) "Ignoring parameter '%s=%s' for worker '%s' because of worker sharing", - elts[i].key, elts[i].val, worker->s->name); + elts[i].key, elts[i].val, ap_proxy_worker_name(cmd->pool, worker)); } else { const char *err = set_worker_param(cmd->pool, worker, elts[i].key, elts[i].val); @@ -2048,7 +2077,7 @@ static const char *add_member(cmd_parms *cmd, void } /* Try to find existing worker */ - worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, name); + worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, de_socketfy(cmd->temp_pool, name)); if (!worker) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01147) "Defining worker '%s' for balancer '%s'", @@ -2057,13 +2086,13 @@ static const char *add_member(cmd_parms *cmd, void return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01148) "Defined worker '%s' for balancer '%s'", - worker->s->name, balancer->s->name); + ap_proxy_worker_name(cmd->pool, worker), balancer->s->name); PROXY_COPY_CONF_PARAMS(worker, conf); } else { reuse = 1; ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01149) "Sharing worker '%s' instead of creating new worker '%s'", - worker->s->name, name); + ap_proxy_worker_name(cmd->pool, worker), name); } arr = apr_table_elts(params); @@ -2072,7 +2101,7 @@ static const char *add_member(cmd_parms *cmd, void if (reuse) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(01150) "Ignoring parameter '%s=%s' for worker '%s' because of worker sharing", - elts[i].key, elts[i].val, worker->s->name); + elts[i].key, elts[i].val, ap_proxy_worker_name(cmd->pool, worker)); } else { err = set_worker_param(cmd->pool, worker, elts[i].key, elts[i].val); @@ -2134,7 +2163,7 @@ static const char * } } else { - worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, name); + worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, de_socketfy(cmd->temp_pool, name)); if (!worker) { if (in_proxy_section) { err = ap_proxy_define_worker(cmd->pool, &worker, NULL, @@ -2274,7 +2303,7 @@ static const char *proxysection(cmd_parms *cmd, vo } else { worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf, - conf->p); + de_socketfy(cmd->temp_pool, (char*)conf->p)); if (!worker) { err = ap_proxy_define_worker(cmd->pool, &worker, NULL, sconf, conf->p, 0); Index: modules/proxy/mod_proxy.h =================================================================== --- modules/proxy/mod_proxy.h (revision 1559678) +++ modules/proxy/mod_proxy.h (working copy) @@ -253,6 +253,7 @@ typedef struct { unsigned int need_flush:1; /* Flag to decide whether we need to flush the * filter chain or not */ unsigned int inreslist:1; /* connection in apr_reslist? */ + const char *uds_path; /* Unix domain socket path */ } proxy_conn_rec; typedef struct { @@ -345,6 +346,7 @@ typedef struct { char route[PROXY_WORKER_MAX_ROUTE_SIZE]; /* balancing route */ char redirect[PROXY_WORKER_MAX_ROUTE_SIZE]; /* temporary balancing redirection route */ char flusher[PROXY_WORKER_MAX_SCHEME_SIZE]; /* flush provider used by mod_proxy_fdpass */ + char uds_path[PROXY_WORKER_MAX_NAME_SIZE]; /* path to worker's unix domain socket if applicable */ int lbset; /* load balancer cluster set */ int retries; /* number of retries on this worker */ int lbstatus; /* Current lbstatus */ @@ -590,6 +592,16 @@ typedef __declspec(dllimport) const char * /* Connection pool API */ /** + * Return the user-land, UDS aware worker name + * @param p memory pool used for displaying worker name + * @param worker the worker + * @return name + */ + +PROXY_DECLARE(char *) ap_proxy_worker_name(apr_pool_t *p, + proxy_worker *worker); + +/** * Get the worker from proxy configuration * @param p memory pool used for finding worker * @param balancer the balancer that the worker belongs to