Bug 56074 - ProxyPassMatch-Rules break by upgrade from 2.4.4 to 2.4.6
Summary: ProxyPassMatch-Rules break by upgrade from 2.4.4 to 2.4.6
Status: RESOLVED MOVED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_proxy (show other bugs)
Version: 2.4.6
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: FixedInTrunk, PatchAvailable
Depends on:
Blocks:
 
Reported: 2014-01-28 12:09 UTC by Andre W.
Modified: 2014-02-05 12:49 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andre W. 2014-01-28 12:09:22 UTC
Hello,

i tried to upgrade an Apache 2.4.4 up to version 2.4.6 with the following ProxyPassMatch-Rules:

ProxyPassMatch ^(.*\.jsp(?:;.*)?)$ balancer://appcluster$1
ProxyPassMatch ^(.*\.do(?:;.*)?)$ balancer://appcluster$1
ProxyPassMatch ^(.*/servlet/.*(?:;.*)?)$ balancer://appcluster$1

During the syntax check the Apache 2.4.6 failed with the following error:

ProxyPass unable to parse: ^(.*\\.jsp(?:;.*)?)$

By changing the order of the rules and putting the servlet rule in front the other rules the Apache 2.4.6 starts without any problem:

ProxyPassMatch ^(.*/servlet/.*(?:;.*)?)$ balancer://appcluster$
ProxyPassMatch ^(.*\.jsp(?:;.*)?)$ balancer://appcluster$1
ProxyPassMatch ^(.*\.do(?:;.*)?)$ balancer://appcluster$1

I also found out the following bug for apache 2.2.x https://issues.apache.org/bugzilla/show_bug.cgi?id=46665, which shows nearly the same problem and recommends to change the rules i.e. 

ProxyPassMatch ^/(.*\.jsp(?:;.*)?)$ balancer://appcluster$1
ProxyPassMatch ^/(.*\.do(?:;.*)?)$ balancer://appcluster$1
ProxyPassMatch ^(.*/servlet/.*(?:;.*)?)$ balancer://appcluster$1

the curious point here for me is, why does apache 2.4.6 break if an "incorrect" match (in 2.4.4 the matches worked well, without any problems) is placed as first match, but not as a follwoing match if the first one has an prefixed / like ^(.*/servlet/.*(?:;.*)?)$.

Cheers,
André
Comment 1 Andre W. 2014-01-31 13:08:19 UTC
I have done some more informations here and found out that the problem is not the "/" inside the ProxyPassMatch, the problem is the perl regex "?:".

I have tried multiple configurations of apache and the problem appears if an APR-UTIL > 1.5.1 is used!

Current compile tests runs, with problem:

HTTP 2.4.6
APR 1.50
APR-UTIL 1.5.1
PCRE 8.34

The following breaks:
HTTP 2.4.6
APR 1.50
APR-UTIL 1.5.2
PCRE 8.34

Will close this case and open a bug inside the APR-UTIL library.

Best regards,
André
Comment 2 Ruediger Pluem 2014-01-31 14:57:34 UTC
I guess you get hit by the following Change in apr-util 1.5.2:

  *) apr_uri_parse(): Do not accept invalid characters in the scheme.
     Per RFC 3986 3.3, enforce that the first segment of a relative path does
     not contain a colon. PR 52479. [Stefan Fritsch]

But I guess the more interesting question is if doing an apr_uri_parse in ap_proxy_update_balancer is the correct thing to do in the regex case.
Comment 3 Ruediger Pluem 2014-01-31 15:15:25 UTC
Can you please try if the following patch solves your issue?

Index: proxy_util.c
===================================================================
--- proxy_util.c        (revision 1562932)
+++ proxy_util.c        (working copy)
@@ -1116,6 +1116,9 @@
                                                 const char *url)
 {
     apr_uri_t puri;
+    if (!url) {
+        return NULL;
+    }
     if (apr_uri_parse(p, url, &puri) != APR_SUCCESS) {
         return apr_psprintf(p, "unable to parse: %s", url);
     }
Index: mod_proxy.c
===================================================================
--- mod_proxy.c (revision 1562932)
+++ mod_proxy.c (working copy)
@@ -1584,13 +1584,26 @@
     /* Distinguish the balancer from worker */
     if (ap_proxy_valid_balancer_name(r, 9)) {
         proxy_balancer *balancer = ap_proxy_get_balancer(cmd->pool, conf, r, 0);
+        char *fake_copy;
+
+        /*
+         * In the regex case supplying a fake URL doesn't make sense as it
+         * cannot be parsed anyway with apr_uri_parse later on in
+         * ap_proxy_define_balancer / ap_proxy_update_balancer
+         */
+        if (use_regex) {
+            fake_copy = NULL;
+        }
+        else {
+            fake_copy = f;
+        }
         if (!balancer) {
-            const char *err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, r, f, 0);
+            const char *err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, r, fake_copy, 0);
             if (err)
                 return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
         }
         else {
-            ap_proxy_update_balancer(cmd->pool, balancer, f);
+            ap_proxy_update_balancer(cmd->pool, balancer, fake_copy);
         }
         for (i = 0; i < arr->nelts; i++) {
             const char *err = set_balancer_param(conf, cmd->pool, balancer, elts[i].key,
Comment 4 Andre W. 2014-02-03 14:39:08 UTC
i tried the patch and it worked with 2.4.6, apr 1.5.0 and apr-util 1.5.3, so my issue seems to be solved, for the moment.

Cheers,
André
Comment 5 Ruediger Pluem 2014-02-04 19:37:54 UTC
Committed to trunk as r156443.
Comment 6 Yann Ylavic 2014-02-05 10:21:09 UTC
(In reply to Ruediger Pluem from comment #5)
> Committed to trunk as r156443.

You probably meant r1564437..
Comment 7 Ruediger Pluem 2014-02-05 12:49:39 UTC
(In reply to Yann Ylavic from comment #6)
> (In reply to Ruediger Pluem from comment #5)
> > Committed to trunk as r156443.
> 
> You probably meant r1564437..

Yes. Thanks.