|
Apache HTTP Server Version 1.3Using XSSI and ErrorDocument to configure customized international server error responses
Index
IntroductionThis document describes an easy way to provide your apache WWW server with a set of customized error messages which take advantage of Content Negotiation and eXtended Server Side Includes (XSSI) to return error messages generated by the server in the client's native language.
By using XSSI, all
customized messages
can share a homogenous and consistent style and layout, and maintenance work
(changing images, changing links) is kept to a minimum because all layout
information can be kept in a single file. Content Negotiation then selects the appropriate language version of a particular error message text, honoring the language preferences passed in the client's request. (Users usually select their favorite languages in the preferences options menu of today's browsers). When an error document in the client's primary language version is unavailable, the secondary languages are tried or a default (fallback) version is used. You have full flexibility in designing your error documents to your personal taste (or your company's conventions). For demonstration purposes, we present a simple generic error document scheme. For this hypothetic server, we assume that all error messages...
An example of a "document not found" message for a german client might
look like this: Creating an ErrorDocument directoryFor this concept to work as easily as possible, we must take advantage of as much server support as we can get:
LanguagePriority en fr de Alias /errordocs /usr/local/apache/errordocs <Directory /usr/local/apache/errordocs> AllowOverride none Options MultiViews IncludesNoExec FollowSymLinks AddType text/html .shtml AddHandler server-parsed .shtml </Directory> # "400 Bad Request", ErrorDocument 400 /errordocs/400 # "401 Authorization Required", ErrorDocument 401 /errordocs/401 # "403 Forbidden", ErrorDocument 403 /errordocs/403 # "404 Not Found", ErrorDocument 404 /errordocs/404 # "500 Internal Server Error", ErrorDocument 500 /errordocs/500The directory for the error messages (here: /usr/local/apache/errordocs/) must then be created with the appropriate permissions (readable and executable by the server uid or gid, only writable for the administrator). Naming the individual error document filesBy defining the MultiViews option, the server was told to automatically scan the directory for matching variants (looking at language and content type suffixes) when a requested document was not found. In the configuration, we defined the names for the error documents to be just their error number (without any suffix).The names of the individual error documents are now determined like this (I'm using 403 as an example, think of it as a placeholder for any of the configured error documents):
The common header and footer filesBy putting as much layout information in two special "include files", the error documents can be reduced to a bare minimum.
One of these layout files defines the HTML document header
and a configurable list of paths to the icons to be shown in the resulting
error document. These paths are exported as a set of XSSI environment
variables and are later evaluated by the "footer" special file.
The title of the current error (which is
put into the TITLE tag and an H1 header) is simply passed in from the main
error document in a variable called The second layout file describes the footer to be displayed at the bottom of every error message. In this example, it shows an apache logo, the current server time, the server version string and adds a mail reference to the site's webmaster.
For simplicity, the header file is simply called
Example: for English, French and German versions
(default english)
Both files are then simply included into the error document by using the
directives See the listings below to see an actual HTML implementation of the discussed example. Creating ErrorDocuments in different languagesAfter all this preparation work, little remains to be said about the actual documents. They all share a simple common structure:<!--#set var="title" value="error description title" --> <!--#include virtual="head" --> explanatory error text <!--#include virtual="foot" -->In the listings section, you can see an example of a [400 Bad Request] error document. Documents as simple as that certainly cause no problems to translate or expand. The fallback languageDo we need a special handling for languages other than those we have translations for? We did set the LanguagePriority, didn't we?!Well, the LanguagePriority directive is for the case where the client does not express any language priority at all. But what happens in the situation where the client wants one of the languages we do not have, and none of those we do have? Without doing anything, the Apache server will usually return a [406 no acceptable variant] error, listing the choices from which the client may select. But we're in an error message already, and important error information might get lost when the client had to choose a language representation first. So, in this situation it appears to be easier to define a fallback language (by copying or linking, e.g., the english version to a language-less version). Because the negotiation algorithm prefers "more specialized" variants over "more generic" variants, these generic alternatives will only be chosen when the normal negotiation did not succeed. A simple shell script to do it (execute within the errordocs/ dir): for f in *.shtml.en do ln -s $f `basename $f .en` done
HTML listing of the discussed exampleSo, to summarize our example, here's the complete listing of the 400.shtml.en document. You will notice that it contains almost nothing but the error text (with conditional additions). Starting with this example, you will find it easy to add more error documents, or to translate the error documents to different languages.<!--#set var="title" value="Bad Request" --><!--#include virtual="head" --><P> Your browser sent a request that this server could not understand: <BLOCKQUOTE> <STRONG><!--#echo var="REQUEST_URI" --></STRONG> </BLOCKQUOTE> The request could not be understood by the server due to malformed syntax. The client should not repeat the request without modifications. </P> <P> <!--#if expr="\"$HTTP_REFERER\" != \"\"" --> Please inform the owner of <A HREF="<!--#echo var="HTTP_REFERER" -->">the referring page</A> about the malformed link. <!--#else --> Please check your request for typing errors and retry. <!--#endif --> </P> <!--#include virtual="foot" --> Here is the complete head.shtml file (the funny line breaks avoid empty lines in the document after XSSI processing). Note the configuration section at top. That's where you configure the images and logos as well as the apache documentation directory. Look how this file displays two different logos depending on the content of the virtual host name ($SERVER_NAME), and that an animated apache logo is shown if the browser appears to support it (the latter requires server configuration lines of the form BrowserMatch "^Mozilla/[2-4]" anigif for browser types which support animated GIFs). <!--#if expr="\"$SERVER_NAME\" = /.*\.mycompany\.com/" --><!--#set var="IMG_CorpLogo" value="http://$SERVER_NAME:$SERVER_PORT/errordocs/CorpLogo.gif" --><!--#set var="ALT_CorpLogo" value="Powered by Linux!" --><!--#else --><!--#set var="IMG_CorpLogo" value="http://$SERVER_NAME:$SERVER_PORT/errordocs/PrivLogo.gif" --><!--#set var="ALT_CorpLogo" value="Powered by Linux!" --><!--#endif --><!--#set var="IMG_BgImage" value="http://$SERVER_NAME:$SERVER_PORT/errordocs/BgImage.gif" --><!--#set var="DOC_Apache" value="http://$SERVER_NAME:$SERVER_PORT/Apache/" --><!--#if expr="$anigif" --><!--#set var="IMG_Apache" value="http://$SERVER_NAME:$SERVER_PORT/icons/apache_anim.gif" --><!--#else --><!--#set var="IMG_Apache" value="http://$SERVER_NAME:$SERVER_PORT/icons/apache_pb.gif" --><!--#endif --><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <HTML> <HEAD> <TITLE> [<!--#echo var="REDIRECT_STATUS" -->] <!--#echo var="title" --> </TITLE> </HEAD> <BODY BGCOLOR="white" BACKGROUND="<!--#echo var="IMG_BgImage" -->"><UL> <H1 ALIGN="center"> [<!--#echo var="REDIRECT_STATUS" -->] <!--#echo var="title" --> <IMG SRC="<!--#echo var="IMG_CorpLogo" -->" ALT="<!--#echo var="ALT_CorpLogo" -->" ALIGN=right> </H1> <HR><!-- ======================================================== --> <DIV> and this is the foot.shtml.en file: </DIV> <HR> <DIV ALIGN="right"><SMALL><SUP>Local Server time: <!--#echo var="DATE_LOCAL" --> </SUP></SMALL></DIV> <DIV ALIGN="center"> <A HREF="<!--#echo var="DOC_Apache" -->"> <IMG SRC="<!--#echo var="IMG_Apache" -->" BORDER=0 ALIGN="bottom" ALT="Powered by <!--#echo var="SERVER_SOFTWARE" -->"></A><BR> <SMALL><SUP><!--#set var="var" value="Powered by $SERVER_SOFTWARE -- File last modified on $LAST_MODIFIED" --><!--#echo var="var" --></SUP></SMALL> </DIV> <ADDRESS>If the indicated error looks like a misconfiguration, please inform <A HREF="mailto:<!--#echo var="SERVER_ADMIN" -->" SUBJECT="Feedback about Error message [<!--#echo var="REDIRECT_STATUS" -->] <!--#echo var="title" -->, req=<!--#echo var="REQUEST_URI" -->"> <!--#echo var="SERVER_NAME" -->'s WebMaster</A>. </ADDRESS> </UL></BODY> </HTML> More welcome!If you have tips to contribute, send mail to Martin.Kraemer@Mch.SNI.De |
|||||||||||||||||
With any suggestions or questions please feel free to contact us |