Content negotiation is provided by the mod_negotiation module, which is compiled in by default.
Accept-Language: fr
Note that this preference will only be applied when there is a choice
of representations and they vary by language.
As an example of a more complex request, this browser has been
configured to accept French and English, but prefer French, and to
accept various media types, preferring HTML over plain text or other
text types, and preferring GIF or JPEG over other media types, but also
allowing any other media type as a last resort:
Accept-Language: fr; q=1.0, en; q=0.5
Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6,
image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1
Apache 1.2 supports 'server driven' content negotiation, as defined in
the HTTP/1.1 specification. It fully supports the Accept,
Accept-Language, Accept-Charset and Accept-Encoding request headers.
The terms used in content negotiation are: a resource is an item which can be requested of a server, which might be selected as the result of a content negotiation algorithm. If a resource is available in several formats, these are called representations or variants. The ways in which the variants for a particular resource vary are called the dimensions of negotiation.
*.var
file) which
names the files containing the variants explicitly
type-map
(or, for backwards-compatibility with
older Apache configurations, the mime type
application/x-type-map
). Note that to use this feature,
you've got to have a SetHandler
some place which defines a
file suffix as type-map
; this is best done with a
AddHandler type-map var
in srm.conf
. See comments in the sample config files for
details.
Type map files have an entry for each available variant; these entries
consist of contiguous RFC822-format header lines. Entries for
different variants are separated by blank lines. Blank lines are
illegal within an entry. It is conventional to begin a map file with
an entry for the combined entity as a whole (although this
is not required, and if present will be ignored). An example
map file is:
URI: foo
URI: foo.en.html
Content-type: text/html
Content-language: en
URI: foo.fr.de.html
Content-type: text/html; charset=iso-8859-2
Content-language: fr, de
If the variants have different source qualities, that may be indicated
by the "qs" parameter to the media type, as in this picture (available
as jpeg, gif, or ASCII-art):
URI: foo
URI: foo.jpeg
Content-type: image/jpeg; qs=0.8
URI: foo.gif
Content-type: image/gif; qs=0.5
URI: foo.txt
Content-type: text/plain; qs=0.01
qs values can vary between 0.000 and 1.000. Note that any variant with a qs value of 0.000 will never be chosen. Variants with no 'qs' parameter value are given a qs factor of 1.0.
The full list of headers recognized is:
URI:
Content-type:
image/gif
, text/plain
, or
text/html; level=3
.
Content-language:
en
for English,
kr
for Korean, etc.).
Content-encoding:
x-compress
, or x-gzip
, as appropriate.
Content-length:
Options
directive within a <Directory>
,
<Location>
or <Files>
section in access.conf
, or (if AllowOverride
is properly set) in .htaccess
files. Note that
Options All
does not set MultiViews
; you
have to ask for it by name. (Fixing this is a one-line change to
http_core.h
).
The effect of MultiViews
is as follows: if the server
receives a request for /some/dir/foo
, if
/some/dir
has MultiViews
enabled, and
/some/dir/foo
does not exist, then the server reads the
directory looking for files named foo.*, and effectively fakes up a
type map which names all those files, assigning them the same media
types and content-encodings it would have if the client had asked for
one of them by name. It then chooses the best match to the client's
requirements, and forwards them along.
This applies to searches for the file named by the
DirectoryIndex
directive, if the server is trying to
index a directory; if the configuration files specify
DirectoryIndex index
then the server will arbitrate between index.html
and index.html3
if both are present. If neither are
present, and index.cgi
is there, the server will run it.
If one of the files found when reading the directive is a CGI script, it's not obvious what should happen. The code gives that case special treatment --- if the request was a POST, or a GET with QUERY_ARGS or PATH_INFO, the script is given an extremely high quality rating, and generally invoked; otherwise it is given an extremely low quality rating, which generally causes one of the other views (if any) to be retrieved.
In some circumstances, Apache can 'fiddle' the quality factor of a particular dimension to achieve a better result. The ways Apache can fiddle quality factors is explained in more detail below.
Dimension | Notes |
---|---|
Media Type | Browser indicates preferences on Accept: header. Each item can have an associated quality factor. Variant description can also have a quality factor. |
Language | Browser indicates preferences on Accept-Language: header. Each item can have a quality factor. Variants can be associated with none, one or more languages. |
Encoding | Browser indicates preference with Accept-Encoding: header. |
Charset | Browser indicates preference with Accept-Charset: header. Variants can indicate a charset as a parameter of the media type. |
LanguagePriority
directive (if present),
else the order of languages on the Accept-Language header.
Accept: image/*, */*
would indicate that any type starting "image/" is acceptable,
as is any other type (so the first "image/*" is redundant). Some
browsers routinely send wildcards in addition to explicit types they
can handle. For example:
Accept: text/html, text/plain, image/gif, image/jpeg, */*
The intention of this is to indicate that the explicitly
listed types are preferred, but if a different representation is
available, that is ok too. However under the basic algorithm, as given
above, the */* wildcard has exactly equal preference to all the other
types, so they are not being preferred. The browser should really have
sent a request with a lower quality (preference) value for *.*, such
as:
Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01
The explicit types have no quality factor, so they default to a
preference of 1.0 (the highest). The wildcard */* is given
a low preference of 0.01, so other types will only be returned if
no variant matches an explicitly listed type.
If the Accept: header contains no q factors at all, Apache sets the q value of "*/*", if present, to 0.01 to emulate the desired behavior. It also sets the q value of wildcards of the format "type/*" to 0.02 (so these are preferred over matches against "*/*". If any media type on the Accept: header contains a q factor, these special values are not applied, so requests from browsers which send the correct information to start with work as expected.
The reason for setting this language quality factor for variant with no language to a very low value is to allow for a default variant which can be supplied if none of the other variants match the browser's language preferences. For example, consider the situation with three variants:
For requests which come from a HTTP/1.0 compliant client (either a browser or a cache), the directive CacheNegotiatedDocs can be used to allow caching of responses which were subject to negotiation. This directive can be given in the server config or virtual host, and takes no arguments. It has no effect on requests from HTTP/1.1 clients.