Recipe 11.8 Disabling Content Negotiation
Problem
Content negotiation causes a big
reduction in performance.
Solution
Disable content negotiation where it is not needed. If you do require
content negotiation, use the type-map handler,
rather than the MultiViews option:
Options -MultiViews
AddHandler type-map var
Discussion
If at all possible, disable content negotiation. However, if you must
do content negotiation—if, for example, you have a multilingual
web site—you should use the type-map handler,
rather than the
MultiViews method.
When MultiViews is used, Apache needs to get a
directory listing each time a request is made. The resource requested
is compared to the directory listing to see what variants of that
resource might exist. For example, if index.html
is requested, the variants index.html.en and
index.html.fr might exist to satisfy that
request. Each matching variant is compared with the
user's preferences, expressed in the various
Accept headers passed by the client. This
information allows Apache to determine which resource is best suited
to the user's needs.
However, this process can be very time-consuming, particularly for
large directories or resources with large numbers of variants. By
putting the information in a .var file and
allowing the type-map handler to be used instead,
you eliminate the requirement to get a directory listing, and greatly
reduce the amount of work that Apache must do to determine the
correct variant to send to the user.
The .var file just needs to contain a listing of
the variants of a particular resource and describe their important
attributes.
If you have, for example, English, French, and Hebrew variants of the
resource
index.html, you may express this in a
.var file called
index.html.var containing information about each
of the various variants. This file might look like the following:
URI: index.html.en
Content-language: en
Content-type: text/html
URI: index.html.fr
Content-language: en
Content-type: text/html
URI: index.html.he.iso8859-8
Content-language: he
Content-type: text/html;charset=ISO-8859-8
This file should be placed in the same directory as the variants of
this resource, which are called index.html.en,
index.html.fr, and
index.html.he.iso8859-8.
Note that the Hebrew variant of the document indicates an alternate
character set, both in the name of the file itself, and in the
Content-type header field.
Enable the .var file by adding a
AddHandler directive to your configuration file,
as follows:
AddHandler type-map .var
|
Each of the file extensions used in these filenames should have an
associated directive in your configuration file. This is not
something that you should have to add—these should appear in
your default configuration file. Each of the language indicators will
have an associated
AddLanguage directive, while the character set
indicator will have an
AddCharset directive.
|
|
In contrast to MultiViews, this technique gets all
of its information from this .var file instead
of from a directory listing, which is much less efficient.
You can further reduce the performance impact of content negotiation
by indicating that negotiated documents can be cached. This is
accomplished by the directive:
CacheNegotiatedDocs On
Caching negotiated documents can cause unpleasant results, such as
people getting files in a language that they cannot read or in
document formats that they don't know how to render.
If possible, you should completely avoid content negotiation in any
form, as it will greatly slow down your server no matter which
technique you use.
See Also
|