Reverse Proxy Pain

Mod_proxy, Mod_cache, and Mod_proxy_html can’t save this site.

Recently, I was experimenting with mod_cache, mod_proxy, and mod_proxy_html in a reverse proxy configuration.  A friend had a site and was interesting in breaking off pieces for his own maintenance and this seemed like another great reason to use these modules and show how one can stitch together various parts of the sites from various external sites. Everything worked as planned with the exception of the top page and it wasn’t until I was using nginx that I saw the following code which I had not run into before.  See line 17 and the onload body command.

Hopefully this was done on purpose because for the life of me, I can’t understand why you would send a page to a user browser only to ask them to load another page.  Why wouldn’t you do it up front in the server and save the user the latency for first page display.  Anyway here is an example of the offending site and the page from my nginx cache and a reminder to myself that mod_proxy_html won’t find that by default thus breaking the reverse proxy.

HTTP/1.1 200 OK
Date: Sun, 23 Jan 2011 23:56:35 GMT
Server: Apache
Last-Modified: Mon, 08 Dec 2008 05:49:09 GMT
ETag: "7b605d-368-493cb555"
Accept-Ranges: bytes
Content-Length: 872
Connection: close
Content-Type: text/html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="" xml:lang="en" lang="en"> 
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<body bgcolor="#ffffff" onload="self.location=''">
<h1>Welcome to TWiki</h1>
  <li> <a href="readme.txt">readme.txt</a> </li>
  <li> <a href="license.txt">license.txt</a> </li>
  <li> <a href="TWikiDocumentation.html">TWikiDocumentation.html</a> </li>
  <li> <a href="TWikiHistory.html">TWikiHistory.html</a> </li>
 <p><b>Note:</b> These pages do not need to be accessible by http. Access
 <tt></tt> after you install TWiki</p>

The Apache code looks like the following:

   # disk cache
    CacheEnable disk /
    CacheRoot /nfsdisk/clients/proxy/
    CacheIgnoreCacheControl On
    CacheIgnoreNoLastMod On
    CacheIgnoreQueryString On
    CacheLastModifiedFactor 0.5
    CacheStoreNoStore On
    CacheStorePrivate On
    CacheDirLevels 1
    CacheDirLength 3
    # 60*60 = 3600 = 1hr (when no expire specified)
    CacheDefaultExpire 3600
    # 1 day to cache a document before requesting new document
    CacheMaxExpire 86400
    #CacheIgnoreHeaders Set-Cookie
    CacheIgnoreHeaders Expires Set-Cookie If-Modified-Since

    # memory cache (2048*1024 = 4M)
    # 2K size is maximum size we allow in
    <IfModule mod_mem_cache.c>
       CacheEnable mem /graphics
       MCacheSize 2048
       MCacheMaxObjectCount 100
       MCacheMinObjectSize 1
       MCacheMaxObjectSize 2048

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

    <Location />
        ProxyPassReverseCookiePath / /

        # rewrite any absolute pathnames if found
        ProxyHTMLEnable On
        # ProxyHTMLURLMap from-pattern to-pattern [flags] [cond]

And the nginx code is a little simpler at:

    proxy_cache_path  /usr/share/nginx/cache  levels=1:2 
                    keys_zone=STATIC:10m inactive=24h  max_size=1m;
    server {
        listen       80;

        access_log  /nfsdisk/clients/  main;

        # Main location
        location / {
            proxy_pass   ;
            proxy_set_header       Host;

            proxy_cache            STATIC;
            proxy_cache_valid      200  1d;
            proxy_cache_use_stale  error timeout invalid_header updating
                                   http_500 http_502 http_503 http_504;