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