Use ProxyPassMatch on all URLs except the root path

apache-2.2proxypass

I have searched high a low for a solution for this, and hoping it is just me. What I'm trying to do is redirect all traffic from a URL we host, to another server managed by another provider we purchase from so we can customize the root URL.

I'm using httpd 2.2.3 (Apache). This is configured in a VirtualHost section, it is also SSL (I don't think that should matter however).

Everything works great, except the exclusion.

What I have (simplified) is:

ProxyPreserveHost On

<VirtualHost 1.2.3.4:443>        SSLProxyEngine On
    ProxyPassMatch ^/$   !
    ProxyPassMatch ^/(.*)$      https://proxy.example.com/$1
    ProxyPassReverse /  https://proxy.example.com/

    SSLEngine on
    ...

</VirtualHost>

However it always goes to the remote site. I have tried a bunch of combinations such as:

    ProxyPassMatch /$   !
    ProxyPassMatch ^/(.*)$      https://proxy.example.com/$1
    ProxyPassMatch com/   !
    ProxyPassMatch ^/(.*)$      https://proxy.example.com/$1

I also tried going the other way (to match anything with something after the /, ie:

    ProxyPassMatch ^/(..+)$     https://proxy.example.com/$1
    ProxyPassMatch /    !
    ProxyPassMatch ^/(..*)$     https://proxy.example.com/$1
    ProxyPassMatch /    !

Now the documentation says it matches the URL, but I have found no evidence that this is what it actually does (ie: second variant above with com/).

I have also tried a bunch of other combinations which either match everything, or match nothing.

My thinking is I'm not understanding the URL that is getting given to the regular expression, but not sure how to look at it. I have turned up the debug level in Apache to debug, and it does not give anything useful either.

Cheers.

Best Answer

If I had to guess, I would say your problem comes from the "^/.*$" match, which will match '/'. If you dropped the explicit match to / and replaced the proxy pass with "^/.+$" is may resolve your issue. No promises though.

The difference is the * is equivalent to .{0,} while + is equivalent to .{1,}, so .* will match any or no characters, whereas you want a match on at least one.

ie: The line should read:

ProxyPassMatch ^/(.+)$ proxy.example.com/$1