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