Reverse Proxy Server 2: mod proxy html 2

 

Uniform Server 5.0-Nano
Reverse Proxy.

On the previous page I mentioned a Firefox error message “The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression.“ This message is highlighting a server configuration problem I avoided an in-depth look at this issue by providing a partial solution.

This page covers a complete solution in particular the root cause of the above issue.

Mod Deflate

On the previous page a partial solution was to disable Mod Deflate on the back-end server. However; default installations of Uniform Sever Mod Deflate is enabled and for a very good reason it saves bandwidth.

Edit file C:\server_b\UniServer\usr\local\apache2\conf\httpd.conf un-comment following line as shown LoadModule deflate_module modules/mod_deflate.so this enables gzip compression. The module automatically compresses files defined in the configuration block <IfModule mod_deflate.c></IfModule>

As a slight diversion it’s worth taking a look at this block in a little more detail.

<IfModule mod_deflate.c>
 AddEncoding x-compress Z
 AddEncoding x-gzip gz tgz
 DeflateCompressionLevel 9
 AddOutputFilterByType DEFLATE text/html text/plain text/xml
    text/css application/javascript

 # Setup custom deflate log
 DeflateFilterNote Input instream
 DeflateFilterNote Output outstream
 DeflateFilterNote Ratio ratio
 LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
 #CustomLog logs/deflate.log deflate

 <Directory />
  # Insert filter
  SetOutputFilter DEFLATE
  # Netscape 4.x has some problems...
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  # Netscape 4.06-4.08 have some more problems
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  # MSIE masquerades as Netscape, but it is fine
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
  # Don't compress images
  SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
  SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
  SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar|7z)$
      no-gzip dont-vary
  # Make sure proxies don't deliver the wrong content
  Header append Vary User-Agent env=!dont-vary  
  </Directory>
</IfModule>
</IfModule>


1) Use this directive to target files for compression:

  • Allow ONLY certain types of files using AddOutputFilterByType


2) A pre-configured custom deflate log can be enabled

  • Un-comment line as shown: CustomLog logs/deflate.log deflate

A file deflate.log is created in folder UniServer\usr\local\apache2\logs
Containing lines with the following format note the compression ratio

  • GET /about.html HTTP/1.1" 607/1283 47%
  • GET /links.html HTTP/1.1" 482/1152 41%


3) Use this directive for Browser exclusions:

  • BrowserMatch


4) Use this directive to exclude files from compression:

  • Allow ALL except certain file extensions using SetEnvIfNoCase


5) To prevent storing two or more copies of the same file dependent on client request involving a proxy or cache server .

  • Use this directive: Header append Vary User-Agent env=!dont-vary

Note 1: Two lines above should be on a single line as shown below:

  • AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript
  • SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar|7z)$ no-gzip dont-vary

Note 2: Enable logging during test only. For production disable because file size quickly becomes large.

Top

Cause and Solution 3

Back to error message “The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression.“

<VirtualHost *>
  ServerName localhost:80
  DocumentRoot C:/server_a1/UniServer/www

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

ProxyPass /info/ http://localhost:82/
ProxyHTMLURLMap http://localhost:82 /info
<Location /info/>
  ProxyPassReverse  http://localhost:82/
  #SetOutputFilter proxy-html
  SetOutputFilter INFLATE;proxy-html;DEFLATE
  ProxyHTMLURLMap /          /info/
  ProxyHTMLURLMap /info      /info
</Location>


</VirtualHost>


The above error message is produced because compressed html files are passed to mod_proxy_html for processing. It thinks the page is malformed attempts correction resulting in a corrupt page.

The deflate module is used for compressing text, HTML and XML. The output filter is set to DEFLATE (compress). However we want to use the 'proxy-html' output filter. Trouble is when SetOutputFilter is set to proxy-html it overrides DEFLATE.

Page passed to mod proxy html remains compressed (deflated), links cannot be rewritten however the page is normalised in an attempt to correct this effectively corrupts the page.

Solution:

  • Replace: SetOutputFilter proxy-html
  • With: SetOutputFilter INFLATE;proxy-html;DEFLATE
    • INFLATE decompress
    • proxy-html use mod proxy-html filter
    • DEFLATE compress file

Although the above solution is a little more processor intensive it does allow you to minimise bandwidth when a back-end server is connected to the Internet.

Top

Test

A quick test.

Edit configuration file:

  • C:\server_a\UniServer\usr\local\apache2\conf\httpd.conf
  • Disable line as shown: #SetOutputFilter proxy-html
  • Add line as shown above: SetOutputFilter INFLATE;proxy-html;DEFLATE

Edit configuration file:

  • C:\server_b\UniServer\usr\local\apache2\conf\httpd.conf
  • Enable compression un-comment the line as shown:
  • LoadModule deflate_module modules/mod_deflate.so

Restart both servers, type into browser http://localhost/info/ all links will work as expected.

Top

Template

<VirtualHost *>
  ServerName localhost:80
  DocumentRoot C:/server_a1/UniServer/www

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

ProxyPass /info/ http://localhost:82/
ProxyHTMLURLMap http://localhost:82 /info
<Location /info/>
  ProxyPassReverse  http://localhost:82/
  SetOutputFilter INFLATE;proxy-html;DEFLATE
  ProxyHTMLURLMap /          /info/
  ProxyHTMLURLMap /info      /info
</Location>

ProxyPass         /wiki/  http://localhost:84/wiki/
ProxyHTMLURLMap http://localhost:84/wiki /wiki
<Location /wiki/>
 ProxyPassReverse http://localhost:84/wiki/
 SetOutputFilter INFLATE;proxy-html;DEFLATE
 ProxyHTMLURLMap /           /wiki/
 ProxyHTMLURLMap /wiki       /wiki
</Location>

ProxyPass /wordpress/ http://localhost:85/wordpress/
ProxyHTMLURLMap http://localhost:85/wordpress /wordpress
<Location /wordpress/>
 ProxyPassReverse http://localhost:85/wordpress/
 SetOutputFilter INFLATE;proxy-html;DEFLATE
 ProxyHTMLURLMap /              /wordpress/
 ProxyHTMLURLMap /wordpress     /wordpress
</Location>

ProxyPass /joomla/ http://localhost:86/joomla/
ProxyHTMLURLMap http://localhost:86/joomla /joomla
<Location /joomla/>
 ProxyPassReverse http://localhost:86/joomla/
 SetOutputFilter INFLATE;proxy-html;DEFLATE
 ProxyHTMLURLMap /            /joomla/
 ProxyHTMLURLMap /joomla      /joomla
</Location>


</VirtualHost>


  • The above solution makes for an easy to use template following is an example of what I mean.
  • It’s a copy and past exercise
  1. Copy the first block
  2. Paste below last block
  3. Change the folder name
  4. Change the server name
  5. Repeat for each back-end server


The example shows how symmetrical each block is. I have shown a typical solution that assumes each back-end server runs a dedicated application such as MediaWiki, Wordpress and Joomla.

You can proxy many of the standard applications using this template since they require no special tweaks.

That said some applications require special consideration for example an SVN server.

Top

Summary

The above shows how easy it is to proxy standard applications.

With a minor tweak you can preserver compression between a proxy and backend server thus retaining precious bandwidth.

I mentioned that certain applications require special consideration on the next page and SVN server is covered.

Top


  Ric