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