There have been a few times when people get caught up when
using ProxyPassReverse with balancers that contain a path...
After all, the normal convention is everywhere you see a
ProxyPass there should be a corresponding ProxyPassReverse
that follows the same format. However in cases where
ProxyPass contains a path, PPR doesn't work correctly...

This fixes that but is also safe for the vast majority of
existing sites. I plan to commit unless there are objections:

Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c  (revision 757753)
+++ modules/proxy/proxy_util.c  (working copy)
@@ -1080,11 +1080,9 @@
       * or may not be the right one... basically, we need
       * to find which member actually handled this request.
       *
-         * TODO: Recover the path from real and use that
-         *       for more exact matching
       */
      if ((strncasecmp(real, "balancer:", 9) == 0) &&
-            (balancer = ap_proxy_get_balancer(r->pool, sconf, real))) {
+ (balancer = ap_proxy_get_balancerwpath(r->pool, sconf, real))) {
          int n;
          proxy_worker *worker;
          worker = (proxy_worker *)balancer->workers->elts;
@@ -1245,9 +1243,10 @@
  return ret;
}

-PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
- proxy_server_conf *conf,
-                                                      const char *url)
+static proxy_balancer *proxy_find_balancer(apr_pool_t *p,
+                                           proxy_server_conf *conf,
+                                           const char *url,
+                                           int usepath)
{
  proxy_balancer *balancer;
  char *c, *uri = apr_pstrdup(p, url);
@@ -1257,8 +1256,13 @@
  if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') {
     return NULL;
  }
-    /* remove path from uri */
-    if ((c = strchr(c + 3, '/'))) {
+    /*
+     * remove path from uri if desired. For compatibility, if
+     * we want to use the path, but there is no real path, just
+     * a trailing '/', strip it and continue
+     */
+    c = strchr(c + 3, '/');
+    if ( (usepath && c && !*(c+1)) || (!usepath && c)) {
      *c = '\0';
  }
  balancer = (proxy_balancer *)conf->balancers->elts;
@@ -1271,6 +1275,21 @@
  return NULL;
}

+PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
+ proxy_server_conf *conf,
+                                                      const char *url)
+{
+    return proxy_find_balancer(p, conf, url, 0);
+}
+
+PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancerwpath(apr_pool_t *p, + proxy_server_conf *conf, + const char *url)
+{
+    return proxy_find_balancer(p, conf, url, 1);
+}
+
+
PROXY_DECLARE(const char *) ap_proxy_add_balancer(proxy_balancer **balancer,
                                                apr_pool_t *p,
proxy_server_conf *conf,
Index: modules/proxy/mod_proxy.h
===================================================================
--- modules/proxy/mod_proxy.h   (revision 757753)
+++ modules/proxy/mod_proxy.h   (working copy)
@@ -583,6 +583,17 @@
proxy_server_conf *conf,
                                                    const char *url);
/**
+ * Get the balancer from proxy configuration without dropping the path
+ * associated with that balancer
+ * @param p     memory pool used for finding balancer
+ * @param conf  current proxy server configuration
+ * @param url url to find the worker from. Has to have balancer:// prefix
+ * @return      proxy_balancer or NULL if not found
+ */
+PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancerwpath(apr_pool_t *p, + proxy_server_conf *conf,
+                                                      const char *url);
+/**
* Add the balancer to proxy configuration
* @param balancer the new balancer
* @param p      memory pool to allocate balancer from

Reply via email to