Apache mod_proxy or mod_rewrite for hide a root of a webserver behind a path

apache-2.2mod-proxymod-rewrite

I have 2 apache 2.2.21 one external and one internal, I need to map the internal apache behind a path in external apache, but I have some problems with absolute url.

I tried these configurations:

RewriteEngine  on
RewriteRule    ^/externalpath/(.*)$  http://internal-apache.test.com/$1  [L,P,QSA]
ProxyPassReverse /externalpath/ http://internal-apache.test.com/

or

<Location /externalpath/>
  ProxyPass http://internal-apache.test.com/
  ProxyPassReverse http://internal-apache.test.com/
</Location>

My internal apache use absolute path for search resources as images, css and html and I can't change it now.

Some suggestions?
Thank you

Best Answer

A number of alternatives:

One) Rewrite the internal app to use relative paths instead of absolute.

Two) Redeploy the internal app in a subdirectory rather than in the root of your internal-apache.

Three) One and two are often unlikely to happen... If you're lucky the internal app only uses two or three subdirectories and those are unused on your main site, simply write a bunch of ProxyPass lines:

# Expose Internal App to the internet.
ProxyPass /externalpath/  http://internal-apache.test.com/
ProxyPassReverse /externalpath/  http://internal-apache.test.com/
# Internal app uses a bunch of absolute paths. 
ProxyPass /css/  http://internal-apache.test.com/css/
ProxyPassReverse /css/  http://internal-apache.test.com/css/
ProxyPass /icons/  http://internal-apache.test.com/icons/
ProxyPassReverse /icons/  http://internal-apache.test.com/icons/

Four) Create a seperate subdomain for the internal app and simply reverse proxy everything:

<VirtualHost *:80>
   ServerName app.test.com/
   # Expose Internal App to the internet.
   ProxyPass /  http://internal-apache.test.com/
   ProxyPassReverse /  http://internal-apache.test.com/
</VirtualHost>

Five) Sometimes developers are completely clueless and have their applications not only generate absolute URL's but even include the hostname part in their URL's and the resulting HTML code looks like this: <img src=http://internal-apache.test.com/icons/logo.png>.

A) You can use combo solution of a split horizon DNS and scenario 4. Both internal and external users use the internal-apache.test.com address, but your internal DNS points directly to the ip-address of internal-apache.test.com's server. For external users the public record for internal-apache.test.com points to the ip-address of your public webserver and you can then use solution 4.

B) You can actually get apache to to not only proxy requests to your internal-apache, but also rewrite the response body before it will be transmitted to your users. (Normally a proxy only rewrites HTTP headers/responses). mod_substitute in apache 2.2. I haven't tested if it stacks well with mod_proxy, but maybe the following works:

<Location /externalpath/>
  ProxyPass http://internal-apache.test.com/
  ProxyPassReverse http://internal-apache.test.com/ 
  AddOutputFilterByType SUBSTITUTE text/html
  Substitute "s|internal-apache.test.com/|public-apache.test.com/externalpath/|i" 
</Location>