Sharepoint with Apache reverse proxy using a subdirectory

apache-2.2reverse-proxysharepointsharepoint-2007

Our team is new to Apache. We have a SharePoint 2007 app that sits on
our internal server, at an address we'll call
http://internal.site.com.

We are required to use Apache as a reverse proxy from the
external-facing site to the internal server. the external server is at
an address we'll call http://external.site.com/appname.

The issue comes with SharePoint's relative links. links in the
sharepoint page might point to "/_layouts/dir/subdir/page.aspx" but
when passed through to the proxy, this link shows in the page as
http://external.site.com/_layouts/… (no /appname appended on). So it
seems we have to do a URL re-write.

But then this is extended to other issues — relative URLs in
stylesheets, javascript, etc. that SharePoint generates (i.e. we have
no control over).

SharePoint also creates some URLs along the lines of
"\u002flayouts\u002fuserdisp.aspx?Force=True\u0026ID="

So far, I think the best way to address this is, for each URL
(including in stylesheets, javascript, etc.):

  1. Switch the incorrectly-facing slashes.
  2. Turn any relative URLs (URLs beginning with "/" is how i'm assuming
    we can define this") and turn them into
    http://external.site.com/appname/[URL]"
  3. Use ProxyPass and ProxyPass reverse to transform the paths (which
    should all now be absolute and correctly formatted).

This may be right or wrong and I welcome your opinions on how to do it better.

In pursuit of that goal, so far I've got a config file that I'm
certain is wrong in many ways, but I think is a start. I'd like your
opinions on how to better implement my idea as well.

ProxyRequests off
<Proxy *>
 Order deny,allow
 Allow from all
</Proxy>

ProxyPass /appname/ http://internal.site.com/
ProxyPassReverse /appname/ http://internal.site.com/


<Location /appname/>

ProxyHTMLEnable On
ProxyHTMLExtended On
ProxyHTMLLogVerbose On

#List of HTML elements to change
ProxyHTMLLinks               a                              href
ProxyHTMLLinks               area                       href
ProxyHTMLLinks               link                         href
ProxyHTMLLinks               img                         src longdesc usemap
ProxyHTMLLinks               object                   classid codebase
data usemap
ProxyHTMLLinks               q                             cite
ProxyHTMLLinks               blockquote         cite
ProxyHTMLLinks               ins                          cite
ProxyHTMLLinks               del                          cite
ProxyHTMLLinks               form                      action
ProxyHTMLLinks               input                     src usemap
ProxyHTMLLinks               head                      profile
ProxyHTMLLinks               base                      href
ProxyHTMLLinks               script                     src for

# To support scripting events (with ProxyHTMLExtended On),
# you'll need to declare them too.

ProxyHTMLEvents           onclick ondblclick onmousedown onmouseup \
                               onmouseover onmousemove onmouseout onkeypress \
                               onkeydown onkeyup onfocus onblur onload \
                               onunload onsubmit onreset onselect onchange

#Goal: Map any URL that starts with a / (i.e. a relative link) to
http://internal.site.com/
ProxyHTMLURLMap ^/ http://internal.site.com/

</Location>

Thank you in advance for any help you can give!

All the best,
Sean

Best Answer

The difficulty you're facing is a common one: you want to access a web application using a different URI path than the application expects. The standard Apache proxy machinery only takes care of links in the headers (e.g., Location: headers) but not in the content of the document, so links that use absolute paths like /images/foo.png no longer reach the right place (relative paths should usually work just fine).

A common solution is to use the mod_proxy_html module, which will let you perform substitutions in the content of your web pages. In fact, this tutorial covers exactly the situation you've described.