Yes, mod_rewrite is patched so that it calls fully_qualify_url() on the non-UDS part of the URL only.
Either mod_rewrite has to split the URL (and needs mod_proxy's helpers), or it does not fully qualify on the "unix:" scheme and let mod_proxy fully qualitfy later (which then needs mod_rewrite's helper). I choose the mod_proxy helpers with optional functions to hide the internals. Maybe we could also require fully qualified URLs for RewriteRule(s) with UDS, and avoid the helpers (mod_rewrite would still need to fully qualify the "unix:" scheme)... On Tue, Feb 25, 2014 at 7:26 PM, Jim Jagielski <j...@jagunet.com> wrote: > 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> > >