Thx... I haven't looked over it yet, but I do see that mod_rewrite is patched... why can't we set that note var and do all the required magic in mod_proxy? Does mod_rewrite itself really need to know about "unix:..."??
Why are they optional functions? On Feb 25, 2014, at 12:18 PM, Yann Ylavic <ylavic....@gmail.com> wrote: > On Tue, Feb 25, 2014 at 4:21 PM, Jim Jagielski <j...@jagunet.com> wrote: > > Of course, this doesn't mean that Yann should wait for > > me... you seem to have a good grasp. > > The following (attached) patch does the job, but I'm not it is "elegant". > It introduces the new optional ap_proxy_worker_real_url() and > proxy_worker_full_url() functions that can be used by both mod_rewrite and > mod_proxy to split/unsplit the URL wherever it needs to. > > I propose it here but you probably have a better idea... > > Index: modules/mappers/mod_rewrite.c > =================================================================== > --- modules/mappers/mod_rewrite.c (revision 1570613) > +++ modules/mappers/mod_rewrite.c (working copy) > @@ -97,6 +97,7 @@ > #include "util_mutex.h" > > #include "mod_ssl.h" > +#include "mod_proxy.h" > > #include "mod_rewrite.h" > #include "ap_expr.h" > @@ -109,6 +110,11 @@ static ap_dbd_t *(*dbd_acquire)(request_rec*) = NU > static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL; > static const char* really_last_key = "rewrite_really_last"; > > +static char *(*proxy_worker_real_url)(apr_pool_t *p, char *url, > + char **split) = NULL; > +static char *(*proxy_worker_full_url)(apr_pool_t *p, char *url, > + char *split) = NULL; > + > /* > * in order to improve performance on running production systems, you > * may strip all rewritelog code entirely from mod_rewrite by using the > @@ -4145,6 +4151,13 @@ static int apply_rewrite_rule(rewriterule_entry *p > * ourself). > */ > if (p->flags & RULEFLAG_PROXY) { > + char *real = NULL, *split = NULL; > + > + if (proxy_worker_real_url && > + (real = proxy_worker_real_url(r->pool, r->filename, > &split))) { > + r->filename = real; > + } > + > /* For rules evaluated in server context, the mod_proxy fixup > * hook can be relied upon to escape the URI as and when > * necessary, since it occurs later. If in directory context, > @@ -4164,6 +4177,9 @@ static int apply_rewrite_rule(rewriterule_entry *p > rewritelog((r, 2, ctx->perdir, "forcing proxy-throughput with %s", > r->filename)); > > + if (proxy_worker_full_url && real) { > + r->filename = proxy_worker_full_url(r->pool, r->filename, split); > + } > r->filename = apr_pstrcat(r->pool, "proxy:", r->filename, NULL); > apr_table_setn(r->notes, "rewrite-proxy", "1"); > return 1; > @@ -4384,6 +4400,8 @@ static int pre_config(apr_pool_t *pconf, > } > dbd_acquire = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire); > dbd_prepare = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare); > + proxy_worker_real_url = > APR_RETRIEVE_OPTIONAL_FN(ap_proxy_worker_real_url); > + proxy_worker_full_url = > APR_RETRIEVE_OPTIONAL_FN(ap_proxy_worker_full_url); > return OK; > } > > Index: modules/proxy/mod_proxy.h > =================================================================== > --- modules/proxy/mod_proxy.h (revision 1570613) > +++ modules/proxy/mod_proxy.h (working copy) > @@ -595,13 +595,34 @@ typedef __declspec(dllimport) const char * > > > /* Connection pool API */ > + > /** > + * Return an UDS un-aware URL from the given @a url. > + * @param p memory pool used for the returned URL > + * @param url the URL to split > + * @param split output for the UDS part of the URL (if not NULL) > + * @return the non-UDS part of the URL (if applicable), > + * or the given @a url otherwise > + */ > +APR_DECLARE_OPTIONAL_FN(char *, ap_proxy_worker_real_url, > + (apr_pool_t *p, char *url, char **split)); > + > +/** > + * Return an UDS aware URL from the given @a url and @a split. > + * @param p memory pool used for the returned URL > + * @param url the non-UDS part of the URL > + * @param split the UDS part of the URL (or NULL) > + * @return the full URL > + */ > +APR_DECLARE_OPTIONAL_FN(char *, ap_proxy_worker_full_url, > + (apr_pool_t *p, char *url, char *split)); > + > +/** > * 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); > > Index: modules/proxy/proxy_util.c > =================================================================== > --- modules/proxy/proxy_util.c (revision 1570613) > +++ modules/proxy/proxy_util.c (working copy) > @@ -1507,6 +1507,52 @@ PROXY_DECLARE(char *) ap_proxy_worker_name(apr_poo > return apr_pstrcat(p, "unix:", worker->s->uds_path, "|", > worker->s->name, NULL); > } > > +static char *ap_proxy_worker_real_url(apr_pool_t *p, char *url, char **split) > +{ > + char *ptr; > + /* > + * We could be passed a URL that contains the UDS path... > + * If any, save it in *split, and strip it. > + */ > + if (split) { > + *split = NULL; > + } > + 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 (split) { > + *split = apr_pstrmemdup(p, url, ptr - url); > + } > + if (c[1] == '\0') { > + return apr_pstrcat(p, ret, "//localhost", NULL); > + } > + else { > + return ret; > + } > + } > + return url; > +} > + > +static char *ap_proxy_worker_full_url(apr_pool_t *p, char *url, char *split) > +{ > + if (split) { > + return apr_pstrcat(p, split, "|", url, NULL); > + } > + else { > + return url; > + } > +} > + > PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p, > proxy_balancer *balancer, > proxy_server_conf *conf, > @@ -1905,8 +1951,13 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_work > > access_status = proxy_run_pre_request(worker, balancer, r, conf, url); > if (access_status == DECLINED && *balancer == NULL) { > - *worker = ap_proxy_get_worker(r->pool, NULL, conf, *url); > + char *real_url = *url, *uds_url = NULL; > + if (apr_table_get(r->notes, "rewrite-proxy")) { > + real_url = ap_proxy_worker_real_url(r->pool, *url, &uds_url); > + } > + *worker = ap_proxy_get_worker(r->pool, NULL, conf, real_url); > if (*worker) { > + *url = real_url; > ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, > "%s: found worker %s for %s", > (*worker)->s->scheme, (*worker)->s->name, *url); > @@ -1931,8 +1982,6 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_work > } > else if (r->proxyreq == PROXYREQ_REVERSE) { > if (conf->reverse) { > - char *ptr; > - char *ptr2; > ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, > "*: found reverse proxy worker for %s", *url); > *balancer = NULL; > @@ -1952,27 +2001,20 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_work > * NOTE: Here we use a quick note lookup, but we could also > * check to see if r->filename starts with 'proxy:' > */ > - if (apr_table_get(r->notes, "rewrite-proxy") && > - (ptr2 = ap_strcasestr(r->filename, "unix:")) && > - (ptr = ap_strchr(ptr2, '|'))) { > + if (uds_url) { > + apr_status_t rv; > apr_uri_t urisock; > - apr_status_t rv; > - *ptr = '\0'; > - rv = apr_uri_parse(r->pool, ptr2, &urisock); > + rv = apr_uri_parse(r->pool, uds_url, &urisock); > if (rv == APR_SUCCESS) { > - char *rurl = ptr+1; > char *sockpath = ap_runtime_dir_relative(r->pool, > urisock.path); > apr_table_setn(r->notes, "uds_path", sockpath); > - *url = apr_pstrdup(r->pool, rurl); /* so we get the > scheme for the uds */ > + *url = real_url; /* so we get the scheme for the uds > */ > /* r->filename starts w/ "proxy:", so add after that > */ > - memmove(r->filename+6, rurl, strlen(rurl)+1); > + r->filename = apr_pstrcat(r->pool, "proxy:", > real_url, NULL); > ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, > "*: rewrite of url due to UDS(%s): %s > (%s)", > sockpath, *url, r->filename); > } > - else { > - *ptr = '|'; > - } > } > } > } > @@ -3481,4 +3523,6 @@ void proxy_util_register_hooks(apr_pool_t *p) > { > APR_REGISTER_OPTIONAL_FN(ap_proxy_retry_worker); > APR_REGISTER_OPTIONAL_FN(ap_proxy_clear_connection); > + APR_REGISTER_OPTIONAL_FN(ap_proxy_worker_real_url); > + APR_REGISTER_OPTIONAL_FN(ap_proxy_worker_full_url); > } > Index: modules/proxy/mod_proxy.c > =================================================================== > --- modules/proxy/mod_proxy.c (revision 1570613) > +++ modules/proxy/mod_proxy.c (working copy) > @@ -32,6 +32,9 @@ APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup, > conn_rec *, request_rec *, char *)); > #endif > > +static char *(*proxy_worker_real_url)(apr_pool_t *p, char *url, > + char **split) = NULL; > + > #ifndef MAX > #define MAX(x,y) ((x) >= (y) ? (x) : (y)) > #endif > @@ -1444,36 +1447,6 @@ 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) > { > @@ -1565,7 +1538,8 @@ static const char * > } > > new->fake = apr_pstrdup(cmd->pool, f); > - new->real = apr_pstrdup(cmd->pool, de_socketfy(cmd->pool, r)); > + new->real = apr_pstrdup(cmd->pool, > + proxy_worker_real_url(cmd->temp_pool, r, NULL)); > new->flags = flags; > if (use_regex) { > new->regex = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); > @@ -1614,7 +1588,7 @@ static const char * > new->balancer = balancer; > } > else { > - proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, > conf, de_socketfy(cmd->pool, r)); > + proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, > conf, new->real); > int reuse = 0; > if (!worker) { > const char *err = ap_proxy_define_worker(cmd->pool, &worker, > NULL, conf, r, 0); > @@ -1626,14 +1600,15 @@ 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'", > - ap_proxy_worker_name(cmd->pool, worker), new->real); > + ap_proxy_worker_name(cmd->temp_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, > ap_proxy_worker_name(cmd->pool, worker)); > + elts[i].key, elts[i].val, > ap_proxy_worker_name(cmd->temp_pool, > + > worker)); > } else { > const char *err = set_worker_param(cmd->pool, worker, > elts[i].key, > elts[i].val); > @@ -2093,7 +2068,9 @@ static const char *add_member(cmd_parms *cmd, void > } > > /* Try to find existing worker */ > - worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, > de_socketfy(cmd->temp_pool, name)); > + worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, > + proxy_worker_real_url(cmd->temp_pool, > + name, NULL)); > if (!worker) { > ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01147) > "Defining worker '%s' for balancer '%s'", > @@ -2179,7 +2156,9 @@ static const char * > } > } > else { > - worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, > de_socketfy(cmd->temp_pool, name)); > + worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, > + proxy_worker_real_url(cmd->temp_pool, > + name, NULL)); > if (!worker) { > if (in_proxy_section) { > err = ap_proxy_define_worker(cmd->pool, &worker, NULL, > @@ -2319,7 +2298,9 @@ static const char *proxysection(cmd_parms *cmd, vo > } > else { > worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf, > - de_socketfy(cmd->temp_pool, > (char*)conf->p)); > + > proxy_worker_real_url(cmd->temp_pool, > + > (char*)conf->p, > + NULL)); > if (!worker) { > err = ap_proxy_define_worker(cmd->pool, &worker, NULL, > sconf, conf->p, 0); > @@ -2712,6 +2693,8 @@ static void register_hooks(apr_pool_t *p) > > /* register optional functions within proxy_util.c */ > proxy_util_register_hooks(p); > + > + proxy_worker_real_url = > APR_RETRIEVE_OPTIONAL_FN(ap_proxy_worker_real_url); > } > > AP_DECLARE_MODULE(proxy) = > [EOS] > <httpd-trunk-uds2.patch>