50ffee853244da52f9332f307936f188b4574304
[manu/mod-proxy-html.git] / guide.html
1 <?xml version="1.0" encoding="utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html lang="en"><head>
4 <title>Technical guide: mod_proxy_html</title>
5 <style type="text/css">
6 @import url(/index.css) ;
7 </style>
8 </head><body>
9 <div id="apache">
10 <h1>mod_proxy_html: Technical Guide</h1>
11 <p><a href="./">mod_proxy_html</a> Version 2.4 (Sept-Nov 2004).</p>
12 <h2>Contents</h2>
13 <ul id="toc">
14 <li><a href="#url">URL Rewriting</a>
15 <ul>
16 <li><a href="#html">HTML Links</a></li>
17 <li><a href="#event">Scripting Events</a></li>
18 <li><a href="#cdata">Embedded Scripts and Stylesheets</a></li>
19 </ul>
20 </li>
21 <li><a href="#output">Output Transformation</a>
22 <ul>
23 <li><a href="#fpi">FPI (Doctype)</a></li>
24 <li><a href="#ml">HTML vs XHTML</a></li>
25 <li><a href="#charset">Character Encoding</a></li>
26 </ul>
27 </li>
28 <li><a href="#meta">meta http-equiv support</a></li>
29 <li><a href="#misc">Other Fixups</a></li>
30 <li><a href="#debug">Debugging your Configuration</a></li>
31 <li><a href="#browser">Workarounds for Browser Bugs</a></li>
32 </ul>
33 <h2 id="url">URL Rewriting</h2>
34 <p>Rewriting URLs into a proxy's address space is of course the primary
35 purpose of this module.  From Version 2.0, this capability has been
36 extended from rewriting HTML URLs to processing scripts and stylesheets
37 that <em>may</em> contain URLs.</p>
38 <p>Because the module doesn't contain parsers for javascript or CSS, this
39 additional processing means we have had to introduce some heuristic parsing.
40 What that means is that the parser cannot automatically distinguish between
41 a URL that should be replaced and one that merely appears as text.  It's
42 up to you to match the right things!  To help you do this, we have introduced
43 some new features:</p>
44 <ol>
45 <li>The <code>ProxyHTMLExtended</code> directive.  The extended processing
46 will only be activated if this is On.  The default is Off, which gives you
47 the old behaviour.</li>
48 <li>Regular Expression match-and-replace.  This can be used anywhere,
49 but is most useful where context information can help distinguish URLs
50 that should be replaced and avoid false positives.  For example,
51 to rewrite URLs of CSS @import, we might define a rule<br />
52 <code>ProxyHTMLURLMap   url\(http://internal.example.com([^\)]*)\)      url(http://proxy.example.com$1) Rihe</code><br />
53 This explicitly rewrites from one servername to another, and uses regexp
54 memory to match a path and append it unchanged in $1, while using the
55 <code>url(...)</code> context to reduce the danger of a match that shouldn't
56 be rewritten.  The <b>R</b> flag invokes regexp processing for this rule;
57 <b>i</b> makes the match case-insensitive; while <b>h</b> and <b>e</b>
58 save processing cycles by preventing the match being applied to HTML links
59 and scripting events, where it is clearly irrelevant.</li>
60 </ol>
61 <h3 id="html">HTML Links</h3>
62 <p>HTML links are those attributes defined by the HTML 4 and XHTML 1
63 DTDs as of type <strong>%URI</strong>.  For example, the <strong>href</strong>
64 attribute of the <strong>a</strong> element.  For a full list, see the
65 declaration of <code>linked_elts</code> in <code>pstartElement</code>.
66 Rules are applicable provided the <b>h</b> flag is not set.</p>
67 <p>An HTML link always contains exactly one URL.  So whenever mod_proxy_html
68 finds a matching <code>ProxyHTMLURLMap</code> rule, it will apply the
69 transformation once and stop processing the attribute.</p>
70 <h3 id="event">Scripting Events</h3>
71 <p>Scripting events are the contents of event attributes as defined in the
72 HTML4 and XHTML1 DTDs; for example <code>onclick</code>.  For a full list,
73 see the declaration of <code>events</code> in <code>pstartElement</code>.
74 Rules are applicable provided the <b>e</b> flag is not set.</p>
75 <p>A scripting event may contain more than one URL, and will contain other
76 text.  So when <code>ProxyHTMLExtended</code> is On, all applicable rules
77 will be applied in order until and unless a rule with the <b>L</b> flag
78 matches.  A rule may match more than once, provided the matches do not
79 overlap, so a URL/pattern that appears more than once is rewritten
80 every time it matches.</p>
81 <h3 id="cdata">Embedded Scripts and Stylesheets</h3>
82 <p>Embedded scripts and stylesheets are the contents of
83 <code>&lt;script&gt;</code> and <code>&lt;style&gt;</code> elements.
84 Rules are applicable provided the <b>c</b> flag is not set.</p>
85 <p>A script or stylesheet may contain more than one URL, and will contain other
86 text.  So when <code>ProxyHTMLExtended</code> is On, all applicable rules
87 will be applied in order until and unless a rule with the <b>L</b> flag
88 matches.  A rule may match more than once, provided the matches do not
89 overlap, so a URL/pattern that appears more than once is rewritten
90 every time it matches.</p>
91 <h2 id="output">Output Transformation</h2>
92 <p>mod_proxy_html uses a SAX parser.  This means that the input stream
93 - and hence the output generated - will be normalised in various ways,
94 even where nothing is actually rewritten.  To an HTML or XML parser,
95 the document is not changed by normalisation, except as noted below.
96 Exceptions to this may arise where the input stream is malformed, when
97 the output of mod_proxy_html may be undefined.  These should of course
98 be fixed at the backend: if mod_proxy_html doesn't work as expected,
99 then neither will browsers in real life, except by coincidence.</p>
100 <h3 id="fpi">FPI (Doctype)</h3>
101 <p>Strictly speaking, HTML and XHTML documents are required to have a
102 Formal Public Identifier (FPI), also know as a Document Type Declaration.
103 This references a Document Type Definition (DTD) which defines the grammar/
104 syntax to which the contents of the document must conform.</p>
105 <p>The parser in mod_proxy_html loses any FPI in the input document, but
106 gives you the option to insert one.  You may select either HTML or XHTML
107 (see below), and if your backend is sloppy you may also want to use the
108 "Legacy" keyword to make it declare documents "Transitional".  You may
109 also declare a custom DTD, or (if your backend is seriously screwed
110 so no DTD would be appropriate) omit it altogether.</p>
111 <h3 id="ml">HTML vs XHTML</h3>
112 <p>The differences between HTML 4.01 and XHTML 1.0 are essentially negligible,
113 and mod_proxy_html can transform between the two.  You can safely select
114 either, regardless of what the backend generates, and mod_proxy_html will
115 apply the appropriate rules in generating output.  HTML saves a few bytes.</p>
116 <p>If you declare a custom DTD, you should specify whether to generate
117 HTML or XHTML syntax in the output.  This affects empty elements:
118 HTML <b>&lt;br&gt;</b> vs XHTML <b>&lt;br /&gt;</b>.</p>
119 <h3 id="charset">Character Encoding</h3>
120 <p>The parser uses <strong>UTF-8</strong> (Unicode) internally, and
121 mod_proxy_html <em>always</em> generates output as UTF-8.  This is
122 supported by all general-purpose web software, and supports more
123 character sets and languages than any other charset.</p>
124 <p>The character encoding should be declared in HTTP: for example<br />
125 <code>Content-Type: text/html; charset=latin1</code><br />
126 mod_proxy_html has always supported this in its input, and ensured
127 this happens in output.  But prior to version 2, it did not fully
128 support detection (sniffing) the charset when a backend fails to
129 set the HTTP Header.</p>
130 <p>From version 2.0, mod_proxy_html will detect the encoding of its input
131 as follows:</p>
132 <ol>
133 <li>The HTTP headers, where available, always take precedence over other
134 information.</li>
135 <li>If the first 2-4 bytes are an XML Byte Order Mark (BOM), this is used.</li>
136 <li>If the document starts with an XML declaration
137 <code>&lt;?xml .... ?&gt;</code>, this determines encoding by XML rules.</li>
138 <li>If the document contains the HTML hack
139 <code>&lt;meta http-equiv="Content-Type" ...&gt;</code>, any charset declared
140 here is used.</li>
141 <li>In the absence of any of the above indications, the HTML-over-HTTP default
142 encoding <b>ISO-8859-1</b> is assumed.</li>
143 <li>The parser is set to ignore invalid characters, so a malformed input
144 stream will generate glitches (unexpected characters) rather than risk
145 aborting a parse altogether.</li>
146 </ol>
147 <h2 id="meta">meta http-equiv support</h2>
148 <p>The HTML <code>meta</code> element includes a form
149 <code>&lt;meta http-equiv="Some-Header" contents="some-value"&gt;</code>
150 which should notionally be converted to a real HTTP header by the webserver.
151 In practice, it is more commonly supported in browsers than servers, and
152 is common in constructs such as ClientPull (aka "meta refresh").
153 The <code>ProxyHTMLMeta</code> directive supports the server generating
154 real HTTP headers from these.  However, it does not strip them from the
155 HTML (except for Content-Type, which is removed in case it contains
156 conflicting charset information).</p>
157 <h2 id="misc">Other Fixups</h2>
158 <p>For additional minor functions of mod_proxy_html, please see the
159 <code>ProxyHTMLFixups</code> and <code>ProxyHTMLStripComments</code>
160 directives in the <a href="config.html">Configuration Guide</a>.</p>
161 <h2 id="debug">Debugging your Configuration</h2>
162 <p>From Version 2.1, mod_proxy_html supports a <code>ProxyHTMLLogVerbose</code>
163 directive, to enable verbose logging at <code>LogLevel Info</code>.  This
164 is designed to help with setting up your proxy configuration and
165 diagnosing unexpected behaviour; it is not recommended for normal
166 operation, and can be disabled altogether at compile time for extra
167 performance (see the top of the source).</p>
168 <p>When verbose logging is enabled, the following messages will be logged:</p>
169 <ol>
170 <li>In <strong>Charset Detection</strong>, it will report what charset is
171 detected and how (HTTP rules, XML rules, or HTML rules).  Note that,
172 regardless of verbose logging, an error or warning will be logged if an
173 unsupported charset is detected or if no information can be found.</li>
174 <li>When <code>ProxyHTMLMeta</code> is enabled, it logs each header/value
175 pair processed.</li>
176 <li>Whenever a <code>ProxyHTMLURLMap</code> rule matches and causes a
177 rewrite, it is logged.  The message contains abbreviated context information:
178 <strong>H</strong> denotes an HTML link matched; <strong>E</strong>
179 denotes a match in a scripting event, <strong>C</strong> denotes a match
180 in an inline script or stylesheet.  When the match is a regexp
181 find-and-replace, it is also marked as <strong>RX</strong>.</li>
182 </ol>
183 <h2 id="browser">Workarounds for Browser Bugs</h2>
184 <p>Because mod_proxy_html unsets the Content-Length header, it risks
185 losing the performance advantage of HTTP Keep-Alive.  It therefore sets
186 up HTTP Chunked Encoding when responding to HTTP/1.1 requests.  This
187 enables keep-alive again for HTTP/1.1 agents.</p>
188 <p>Unfortunately some buggy agents will send an HTTP/1.1 request but
189 choke on an HTTP/1.1 response.  Typically you will see numbers before
190 and after, and possibly in the middle of, a page.  To work around this, set the
191 <code>force-response-1.0</code> environment variable in httpd.conf.
192 For example,<br /><code>BrowserMatch MSIE force-response-1.0</code></p>
193 </div>
194 <div id="navbar"><a class="internal" href="./" title="Up">Up</a>
195 *
196 <a class="internal" href="/" title="WebThing Apache Centre">Home</a>
197 *
198 <a class="internal" href="/contact.html" title="Contact WebThing">Contact</a>
199 *
200 <a class="external" href="http://www.webthing.com/" title="WebThing Ltd">Web&#222;ing</a>
201 *
202 <a class="external" href="http://www.apache.org/" title="Apache Software Foundation">Apache</a></div></body></html>