1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><!--
4 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5 This file is generated from xml source: DO NOT EDIT
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8 <title>International Customized Server Error Messages - Apache HTTP Server</title>
9 <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
10 <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
11 <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" />
12 <link href="../images/favicon.ico" rel="shortcut icon" /></head>
13 <body id="manual-page"><div id="page-header">
14 <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p>
15 <p class="apache">Apache HTTP Server Version 2.0</p>
16 <img alt="" src="../images/feather.gif" /></div>
17 <div class="up"><a href="./"><img title="<-" alt="<-" src="../images/left.gif" /></a></div>
19 <a href="http://www.apache.org/">Apache</a> > <a href="http://httpd.apache.org/">HTTP Server</a> > <a href="http://httpd.apache.org/docs/">Documentation</a> > <a href="../">Version 2.0</a> > <a href="./">Miscellaneous Documentation</a></div><div id="page-content"><div id="preamble"><h1>International Customized Server Error Messages</h1>
21 <p><span>Available Languages: </span><a href="../en/misc/custom_errordocs.html" title="English"> en </a></p>
25 <div class="warning"><h3>Warning:</h3>
26 <p>This document has not been fully updated
27 to take into account changes made in the 2.0 version of the
28 Apache HTTP Server. Some of the information may still be
29 relevant, but please use it with care.</p>
32 <p>This document describes an easy way to provide your Apache
33 HTTP Server with a set of customized error messages which take
34 advantage of <a href="../content-negotiation.html">Content
35 Negotiation</a> and <code class="module"><a href="../mod/mod_include.html">mod_include</a></code> to return
36 error messages generated by the server in the client's native
40 <div id="quickview"><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#intro">Introduction</a></li>
41 <li><img alt="" src="../images/down.gif" /> <a href="#createdir">Creating an ErrorDocument directory</a></li>
42 <li><img alt="" src="../images/down.gif" /> <a href="#proxy">Customizing Proxy Error Messages</a></li>
43 <li><img alt="" src="../images/down.gif" /> <a href="#listings">HTML Listing of the Discussed Example</a></li>
45 <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
47 <h2><a name="intro" id="intro">Introduction</a></h2>
51 <p>By using SSI, all <code class="directive"><a href="../mod/core.html#errordocument">ErrorDocument</a></code> messages
52 can share a homogenous and consistent style and layout, and
53 maintenance work (changing images, changing links) is kept to a
54 minimum because all layout information can be kept in a single
57 <p>Error documents can be shared across different servers, or
58 even hosts, because all varying information is inserted at the
59 time the error document is returned on behalf of a failed
62 <p>Content Negotiation then selects the appropriate language
63 version of a particular error message text, honoring the
64 language preferences passed in the client's request. (Users
65 usually select their favorite languages in the preferences
66 options menu of today's browsers). When an error document in
67 the client's primary language version is unavailable, the
68 secondary languages are tried or a default (fallback) version
71 <p>You have full flexibility in designing your error documents
72 to your personal taste (or your company's conventions). For
73 demonstration purposes, we present a simple generic error
74 document scheme. For this hypothetic server, we assume that all
78 <li>possibly are served by different virtual hosts (different
79 host name, different IP address, or different port) on the
82 <li>show a predefined company logo in the right top of the
83 message (selectable by virtual host),</li>
85 <li>print the error title first, followed by an explanatory
86 text and (depending on the error context) help on how to
87 resolve the error,</li>
89 <li>have some kind of standardized background image,</li>
91 <li>display an apache logo and a feedback email address at
92 the bottom of the error message.</li>
95 <p>An example of a "document not found" message for a german
96 client might look like this:</p>
98 <p><img src="../images/custom_errordocs.gif" alt="[Needs graphics capability to display]" /></p>
100 <p>All links in the document as well as links to the server's
101 administrator mail address, and even the name and port of the
102 serving virtual host are inserted in the error document at
103 "run-time", i.e., when the error actually occurs.</p>
104 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
105 <div class="section">
106 <h2><a name="createdir" id="createdir">Creating an ErrorDocument directory</a></h2>
110 <p>For this concept to work as easily as possible, we must take
111 advantage of as much server support as we can get:</p>
114 <li>By defining the MultiViews <code class="directive"><a href="../mod/core.html#options">Options</a></code>, we
115 enable the language selection of the most appropriate
116 language alternative (content negotiation).</li>
118 <li>By setting the <code class="directive"><a href="../mod/mod_negotiation.html#languagepriority">LanguagePriority</a></code>
119 directive we define a set of default fallback languages in
120 the situation where the client's browser did not express any
121 preference at all.</li>
123 <li>By enabling <code class="module"><a href="../mod/mod_include.html">mod_include</a></code>
124 (and disallowing execution of cgi scripts for
125 security reasons), we allow the server to include building
126 blocks of the error message, and to substitute the value of
127 certain environment variables into the generated document
128 (dynamic HTML) or even to conditionally include or omit parts
131 <li>The <code class="directive"><a href="../mod/mod_mime.html#addhandler">AddHandler</a></code> and <code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code> directives
132 are useful for automatically SSI-expanding all files with a
133 <code>.shtml</code> suffix to <em>text/html</em>.</li>
135 <li>By using the <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> directive, we
136 keep the error document directory outside of the document
137 tree because it can be regarded more as a server part than
138 part of the document tree.</li>
140 <li>The <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> block
141 restricts these "special" settings to the error document
142 directory and avoids an impact on any of the settings for the
143 regular document tree.</li>
145 <li>For each of the error codes to be handled (see RFC2068
146 for an exact description of each error code, or look at
147 <code>src/main/http_protocol.c</code> if you wish to see
148 apache's standard messages), an <code class="directive"><a href="../mod/core.html#errordocument">ErrorDocument</a></code> in
149 the aliased <code>/errordocs</code> directory is defined.
150 Note that we only define the basename of the document here
151 because the MultiViews option will select the best candidate
152 based on the language suffixes and the client's preferences.
153 Any error situation with an error code <em>not</em> handled
154 by a custom document will be dealt with by the server in the
155 standard way (<em>i.e.</em>, a plain error message in
158 <li>Finally, the <code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code> directive tells
159 apache that it is not necessary to look for a .htaccess file
160 in the /errordocs directory: a minor speed optimization.</li>
163 <p>The resulting <code>httpd.conf</code> configuration would then
164 look similar to this:</p>
166 <div class="note"><h3>Note</h3>Note that you can define your own
167 error messages using this method for only part of the document
168 tree, e.g., a /~user/ subtree. In this case, the configuration
169 could as well be put into the .htaccess file at the root of the
170 subtree, and the <Directory> and </Directory>
171 directives -but not the contained directives- must be
174 <div class="example"><p><code>
175 LanguagePriority en fr de <br />
176 Alias /errordocs /usr/local/apache/errordocs <br />
178 <Directory /usr/local/apache/errordocs> <br />
179 <span class="indent">
180 AllowOverride none <br />
181 Options MultiViews IncludesNoExec FollowSymLinks <br />
182 AddType text/html .shtml <br />
183 <FilesMatch "\.shtml[.$]"> <br />
184 <span class="indent">
185 SetOutputFilter INCLUDES <br />
187 </FilesMatch> <br />
189 </Directory> <br />
191 # "400 Bad Request", <br />
192 ErrorDocument 400 /errordocs/400 <br />
193 # "401 Authorization Required", <br />
194 ErrorDocument 401 /errordocs/401 <br />
195 # "403 Forbidden", <br />
196 ErrorDocument 403 /errordocs/403 <br />
197 # "404 Not Found", <br />
198 ErrorDocument 404 /errordocs/404 <br />
199 # "500 Internal Server Error", <br />
200 ErrorDocument 500 /errordocs/500 <br />
203 <p>The directory for the error messages (here:
204 <code>/usr/local/apache/errordocs/</code>) must then be created
205 with the appropriate permissions (readable and executable by
206 the server uid or gid, only writable for the administrator).</p>
208 <h3><a name="naming" id="naming">Naming the Individual Error Document files</a></h3>
212 <p>By defining the <code>MultiViews</code> option, the server was
213 told to automatically scan the directory for matching variants
214 (looking at language and content type suffixes) when a
215 requested document was not found. In the configuration, we
216 defined the names for the error documents to be just their
217 error number (without any suffix).</p>
219 <p>The names of the individual error documents are now
220 determined like this (I'm using 403 as an example, think of it
221 as a placeholder for any of the configured error
225 <li>No file errordocs/403 should exist. Otherwise, it would
226 be found and served (with the DefaultType, usually
227 text/plain), all negotiation would be bypassed.</li>
229 <li>For each language for which we have an internationalized
230 version (note that this need not be the same set of languages
231 for each error code - you can get by with a single language
232 version until you actually <em>have</em> translated
233 versions), a document
234 <code>errordocs/403.shtml.<em>lang</em></code> is created and
235 filled with the error text in that language (<a href="#createdocs">see below</a>).</li>
237 <li>One fallback document called
238 <code>errordocs/403.shtml</code> is created, usually by
239 creating a symlink to the default language variant (<a href="#fallback">see below</a>).</li>
243 <h3><a name="headfoot" id="headfoot">The Common Header and Footer Files</a></h3>
247 <p>By putting as much layout information in two special "include
248 files", the error documents can be reduced to a bare minimum.</p>
250 <p>One of these layout files defines the HTML document header
251 and a configurable list of paths to the icons to be shown in
252 the resulting error document. These paths are exported as a set
253 of SSI environment variables and are later evaluated by the
254 "footer" special file. The title of the current error (which is
255 put into the TITLE tag and an H1 header) is simply passed in
256 from the main error document in a variable called
257 <code>title</code>.</p>
259 <p><strong>By changing this file, the layout of all generated
260 error messages can be changed in a second.</strong> (By
261 exploiting the features of SSI, you can easily define
262 different layouts based on the current virtual host, or even
263 based on the client's domain name).</p>
265 <p>The second layout file describes the footer to be displayed
266 at the bottom of every error message. In this example, it shows
267 an apache logo, the current server time, the server version
268 string and adds a mail reference to the site's webmaster.</p>
270 <p>For simplicity, the header file is simply called
271 <code>head.shtml</code> because it contains server-parsed
272 content but no language specific information. The footer file
273 exists once for each language translation, plus a symlink for
274 the default language.</p>
276 <div class="example"><p><code>
277 for English, French and German versions (default english) <br />
279 foot.shtml.en, <br />
280 foot.shtml.fr, <br />
281 foot.shtml.de, <br />
282 foot.shtml symlink to <br />
286 <p>Both files are included into the error document by using the
287 directives <code><!--#include virtual="head" --></code>
288 and <code><!--#include virtual="foot" --></code>
289 respectively: the rest of the magic occurs in mod_negotiation
290 and in mod_include.</p>
292 <p>See <a href="#listings">the listings below</a> to see an
293 actual HTML implementation of the discussed example.</p>
296 <h3><a name="createdocs" id="createdocs">Creating ErrorDocuments in Different Languages</a></h3>
300 <p>After all this preparation work, little remains to be said
301 about the actual documents. They all share a simple common
304 <div class="example"><p><code>
305 <!--#set var="title" value="<em>error description title</em>" --> <br />
306 <!--#include virtual="head" --> <br />
307 <span class="indent">
308 <em>explanatory error text</em> <br />
310 <!--#include virtual="foot" -->
313 <p>In the <a href="#listings">listings section</a>, you can see an
314 example of a [400 Bad Request] error document. Documents as
315 simple as that certainly cause no problems to translate or
319 <h3><a name="fallback" id="fallback">The Fallback Language</a></h3>
323 <p>Do we need a special handling for languages other than those we
324 have translations for? We did set the LanguagePriority, didn't
327 <p>Well, the LanguagePriority directive is for the case where
328 the client does not express any language priority at all. But
329 what happens in the situation where the client wants one of the
330 languages we do not have, and none of those we do have?</p>
332 <p>Without doing anything, the Apache server will usually
333 return a [406 no acceptable variant] error, listing the choices
334 from which the client may select. But we're in an error message
335 already, and important error information might get lost when
336 the client had to choose a language representation first.</p>
338 <p>So, in this situation it appears to be easier to define a
339 fallback language (by copying or linking, <em>e.g.</em>, the
340 english version to a language-less version). Because the
341 negotiation algorithm prefers "more specialized" variants over
342 "more generic" variants, these generic alternatives will only
343 be chosen when the normal negotiation did not succeed.</p>
345 <p>A simple shell script to do it (execute within the
348 <div class="example"><p><code>
349 for f in *.shtml.en <br />
351 <span class="indent">
352 ln -s $f `basename $f .en` <br />
358 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
359 <div class="section">
360 <h2><a name="proxy" id="proxy">Customizing Proxy Error Messages</a></h2>
364 <p>As of Apache-1.3, it is possible to use the
365 <code>ErrorDocument</code> mechanism for proxy error messages
366 as well (previous versions always returned fixed predefined
369 <p>Most proxy errors return an error code of [500 Internal
370 Server Error]. To find out whether a particular error document
371 was invoked on behalf of a proxy error or because of some other
372 server error, and what the reason for the failure was, you can
373 check the contents of the new <code>ERROR_NOTES</code> CGI
374 environment variable: if invoked for a proxy error, this
375 variable will contain the actual proxy error message text in
378 <p>The following excerpt demonstrates how to exploit the
379 <code>ERROR_NOTES</code> variable within an error document:</p>
381 <div class="example"><p><code>
382 <!--#if expr="$REDIRECT_ERROR_NOTES = ''" --> <br />
385 <span class="indent">
386 The server encountered an unexpected condition <br />
387 which prevented it from fulfilling the request. <br />
392 <span class="indent">
393 <a href="mailto:<!--#echo var="SERVER_ADMIN" -->" <br />
394 SUBJECT="Error message [<!--#echo var="REDIRECT_STATUS" -->] <!--#echo var="title" --> for <!--#echo var="REQUEST_URI" -->"> <br />
395 Please forward this error screen to <!--#echo var="SERVER_NAME" -->'s <br />
396 WebMaster</a>; it includes useful debugging information about <br />
397 the Request which caused the error. <br />
399 <pre><!--#printenv --></pre> <br />
403 <!--#else --> <br />
404 <span class="indent">
405 <!--#echo var="REDIRECT_ERROR_NOTES" --><br />
411 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
412 <div class="section">
413 <h2><a name="listings" id="listings">HTML Listing of the Discussed Example</a></h2>
417 <p>So, to summarize our example, here's the complete listing of
418 the <code>400.shtml.en</code> document. You will notice that it
419 contains almost nothing but the error text (with conditional
420 additions). Starting with this example, you will find it easy
421 to add more error documents, or to translate the error
422 documents to different languages.</p>
424 <div class="example"><p><code>
425 <!--#set var="title" value="Bad Request"--> <br />
426 <!--#include virtual="head" --><br />
429 <span class="indent">
430 Your browser sent a request that this server could not understand: <br />
431 <blockquote> <br />
432 <span class="indent">
433 <strong><!--#echo var="REQUEST_URI" --></strong><br />
435 </blockquote> <br />
437 The request could not be understood by the server due to malformed <br />
438 syntax. The client should not repeat the request without <br />
439 modifications. <br />
444 <span class="indent">
445 <!--#if expr="$HTTP_REFERER != ''" --> <br />
446 <span class="indent">
447 Please inform the owner of <br />
448 <a href="<!--#echo var="HTTP_REFERER" -->">the referring page</a> about <br />
449 the malformed link. <br />
452 <!--#else --> <br />
453 <span class="indent">
454 Please check your request for typing errors and retry. <br />
457 <!--#endif --> <br />
461 <!--#include virtual="foot" -->
464 <p>Here is the complete <code>head.shtml.en</code> file (the funny
465 line breaks avoid empty lines in the document after SSI
466 processing). Note the configuration section at top. That's
467 where you configure the images and logos as well as the apache
468 documentation directory. Look how this file displays two
469 different logos depending on the content of the virtual host
470 name ($SERVER_NAME), and that an animated apache logo is shown
471 if the browser appears to support it (the latter requires
472 server configuration lines of the form </p>
474 <div class="example"><p><code>BrowserMatch "^Mozilla/[2-4]" anigif</code></p></div>
476 <p>for browser types which support animated GIFs).</p>
478 <div class="example"><p><code>
479 <!--#if expr="$SERVER_NAME = /.*\.mycompany\.com/" --><br />
480 <span class="indent">
481 <!--#set var="IMG_CorpLogo" value="http://$SERVER_NAME:$SERVER_PORT/errordocs/CorpLogo.gif" --><br />
482 <!--#set var="ALT_CorpLogo" value="Powered by Linux!" --><br />
485 <!--#else --> <br />
486 <span class="indent">
487 <!--#set var="IMG_CorpLogo" value="http://$SERVER_NAME:$SERVER_PORT/errordocs/PrivLogo.gif" --> <br />
488 <!--#set var="ALT_CorpLogo" value="Powered by Linux!" --> <br />
490 <!--#endif--> <br />
492 <!--#set var="IMG_BgImage" value="http://$SERVER_NAME:$SERVER_PORT/errordocs/BgImage.gif" --> <br />
493 <!--#set var="DOC_Apache" value="http://$SERVER_NAME:$SERVER_PORT/Apache/" --> <br />
495 <!--#if expr="$anigif" --> <br />
496 <span class="indent">
497 <!--#set var="IMG_Apache" value="http://$SERVER_NAME:$SERVER_PORT/icons/apache_anim.gif" --> <br />
499 <!--#else--><br />
500 <span class="indent">
501 <!--#set var="IMG_Apache" value="http://$SERVER_NAME:$SERVER_PORT/icons/apache_pb.gif" --><br />
503 <!--#endif--><br />
506 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <br />
509 <span class="indent">
511 [<!--#echo var="REDIRECT_STATUS" -->] <!--#echo var="title" --> <br />
512 </title> <br />
516 <body bgcolor="white" background="<!--#echo var="IMG_BgImage" -->"> <br />
517 <span class="indent">
518 <h1 align="center"> <br />
519 [<!--#echo var="REDIRECT_STATUS" -->]
520 <!--#echo var="title" --> <br />
521 <img src="<!--#echo var="IMG_CorpLogo" -->" <br />
522 alt="<!--#echo var="ALT_CorpLogo" -->" align="right"> <br />
526 <!-- ======================================================== --> <br />
531 <p>and this is the <code>foot.shtml.en</code> file:</p>
533 <div class="example"><p><code>
534 <span class="indent">
538 <div align="right"> <br />
539 <span class="indent">
540 <small>Local Server time:
541 <!--#echo var="DATE_LOCAL" --></small> <br />
545 <div align="center"><br />
546 <span class="indent">
547 <a href="<!--#echo var="DOC_Apache" -->"> <br />
548 <img src="<!--#echo var="IMG_Apache" -->" border="0" align="bottom" <br />
549 alt="Powered by <!--#echo var="SERVER_SOFTWARE" -->"></a> <br />
552 <small><!--#set var="var" value="Powered by $SERVER_SOFTWARE -- <br />
553 File last modified on $LAST_MODIFIED" --> <br />
554 <!--#echo var="var" --></small> <br />
558 <p>If the indicated error looks like a misconfiguration, please inform <br />
559 <a href="mailto:<!--#echo var="SERVER_ADMIN" -->" <br />
560 subject="Feedback about Error message [<!--#echo var="REDIRECT_STATUS" -->] <br />
561 <!--#echo var="title" -->, req=<!--#echo var="REQUEST_URI" -->"> <br />
562 <!--#echo var="SERVER_NAME" -->'s WebMaster</a>.<br />
570 <p>If you have tips to contribute, send mail to <a href="mailto:martin@apache.org">martin@apache.org</a></p>
572 <div class="bottomlang">
573 <p><span>Available Languages: </span><a href="../en/misc/custom_errordocs.html" title="English"> en </a></p>
574 </div><div id="footer">
575 <p class="apache">Copyright 2009 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
576 <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div>