| <html> |
| <head> |
| <title>Apache server Content arbitration: MultiViews and *.var files</title> |
| </head> |
| |
| <body> |
| <IMG SRC="../images/apache_sub.gif" ALT=""> |
| <h3>Content Arbitration: MultiViews and *.var files</h3> |
| |
| The HTTP standard allows clients (i.e., browsers like Mosaic or |
| Netscape) to specify what data formats they are prepared to accept. |
| The intention is that when information is available in multiple |
| variants (e.g., in different data formats), servers can use this |
| information to decide which variant to send. This feature has been |
| supported in the CERN server for a while, and while it is not yet |
| supported in the NCSA server, it is likely to assume a new importance |
| in light of the emergence of HTML3 capable browsers. <p> |
| |
| The Apache module <A HREF="mod_negotiation.html">mod_negotiation</A> handles |
| content negotiation in two different ways; special treatment for the |
| pseudo-mime-type <code>application/x-type-map</code>, and the |
| MultiViews per-directory Option (which can be set in srm.conf, or in |
| .htaccess files, as usual). These features are alternate user |
| interfaces to what amounts to the same piece of code (in the new file |
| <code>http_mime_db.c</code>) which implements the content negotiation |
| portion of the HTTP protocol. <p> |
| |
| Each of these features allows one of several files to satisfy a |
| request, based on what the client says it's willing to accept; the |
| differences are in the way the files are identified: |
| |
| <ul> |
| <li> A type map (i.e., a <code>*.var</code> file) names the files |
| containing the variants explicitly |
| <li> In a MultiViews search, the server does an implicit filename |
| pattern match, and chooses from among the results. |
| </ul> |
| |
| Apache also supports a new pseudo-MIME type, |
| text/x-server-parsed-html3, which is treated as text/html;level=3 |
| for purposes of content negotiation, and as server-side-included HTML |
| elsewhere. |
| |
| <h3>Type maps (*.var files)</h3> |
| |
| A type map is a document which is typed by the server (using its |
| normal suffix-based mechanisms) as |
| <code>application/x-type-map</code>. Note that to use this feature, |
| you've got to have an <code>AddType</code> some place which defines a |
| file suffix as <code>application/x-type-map</code>; the easiest thing |
| may be to stick a |
| <pre> |
| |
| AddType application/x-type-map var |
| |
| </pre> |
| in <code>srm.conf</code>. See comments in the sample config files for |
| details. <p> |
| |
| 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, e.g., |
| <pre> |
| |
| URI: foo; vary="type,language" |
| |
| URI: foo.en.html |
| Content-type: text/html; level=2 |
| Content-language: en |
| |
| URI: foo.fr.html |
| Content-type: text/html; level=2 |
| Content-language: fr |
| |
| </pre> |
| If the variants have different qualities, that may be indicated by the |
| "qs" parameter, as in this picture (available as jpeg, gif, or ASCII-art): |
| <pre> |
| |
| URI: foo; vary="type,language" |
| |
| 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 |
| |
| </pre><p> |
| |
| The full list of headers recognized is: |
| |
| <dl> |
| <dt> <code>URI:</code> |
| <dd> uri of the file containing the variant (of the given media |
| type, encoded with the given content encoding). These are |
| interpreted as URLs relative to the map file; they must be on |
| the same server (!), and they must refer to files to which the |
| client would be granted access if they were to be requested |
| directly. |
| <dt> <code>Content-type:</code> |
| <dd> media type --- level may be specified, along with "qs". These |
| are often referred to as MIME types; typical media types are |
| <code>image/gif</code>, <code>text/plain</code>, or |
| <code>text/html; level=3</code>. |
| <dt> <code>Content-language:</code> |
| <dd> The language of the variant, specified as an internet standard |
| language code (e.g., <code>en</code> for English, |
| <code>kr</code> for Korean, etc.). |
| <dt> <code>Content-encoding:</code> |
| <dd> If the file is compressed, or otherwise encoded, rather than |
| containing the actual raw data, this says how that was done. |
| For compressed files (the only case where this generally comes |
| up), content encoding should be |
| <code>x-compress</code>, or <code>gzip</code>, as appropriate. |
| <dt> <code>Content-length:</code> |
| <dd> The size of the file. Clients can ask to receive a given media |
| type only if the variant isn't too big; specifying a content |
| length in the map allows the server to compare against these |
| thresholds without checking the actual file. |
| </dl> |
| |
| <h3>Multiviews</h3> |
| |
| This is a per-directory option, meaning it can be set with an |
| <code>Options</code> directive within a <code><Directory></code> |
| section in <code>access.conf</code>, or (if <code>AllowOverride</code> |
| is properly set) in <code>.htaccess</code> files. Note that |
| <code>Options All</code> does not set <code>MultiViews</code>; you |
| have to ask for it by name. (Fixing this is a one-line change to |
| <code>httpd.h</code>). |
| |
| <p> |
| |
| The effect of <code>MultiViews</code> is as follows: if the server |
| receives a request for <code>/some/dir/foo</code>, if |
| <code>/some/dir</code> has <code>MultiViews</code> enabled, and |
| <code>/some/dir/foo</code> 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. |
| |
| <p> |
| |
| This applies to searches for the file named by the |
| <code>DirectoryIndex</code> directive, if the server is trying to |
| index a directory; if the configuration files specify |
| <pre> |
| |
| DirectoryIndex index |
| |
| </pre> then the server will arbitrate between <code>index.html</code> |
| and <code>index.html3</code> if both are present. If neither are |
| present, and <code>index.cgi</code> is there, the server will run it. |
| |
| <p> |
| |
| If one of the files found by the globbing is a CGI script, it's not |
| obvious what should happen. My code gives that case gets 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. This is the only jiggering of quality ratings done by the |
| MultiViews code; aside from that, all Qualities in the synthesized |
| type maps are 1.0. |
| |
| <p> |
| |
| <B>New as of 0.8:</B> Documents in multiple languages can also be resolved through the use |
| of the <code>AddLanguage</code> and <code>LanguagePriority</code> |
| directives: |
| |
| <pre> |
| AddLanguage en .en |
| AddLanguage fr .fr |
| AddLanguage de .de |
| AddLanguage da .da |
| AddLanguage el .el |
| AddLanguage it .it |
| |
| # LanguagePriority allows you to give precedence to some languages |
| # in case of a tie during content negotiation. |
| # Just list the languages in decreasing order of preference. |
| |
| LanguagePriority en fr de |
| </pre> |
| |
| Here, a request for "foo.html" matched against "foo.html.en" and |
| "foo.html.fr" would return an French document to a browser that |
| indicated a preference for French, or an English document otherwise. |
| In fact, a request for "foo" matched against "foo.html.en", |
| "foo.html.fr", "foo.ps.en", "foo.pdf.de", and "foo.txt.it" would do |
| just what you expect - treat those suffices as a database and compare |
| the request to it, returning the best match. The languages and data |
| types share the same suffix name space. |
| |
| <p> |
| |
| Note that this machinery only comes into play if the file which the |
| user attempted to retrieve does <em>not</em> exist by that name; if it |
| does, it is simply retrieved as usual. (So, someone who actually asks |
| for <code>foo.jpeg</code>, as opposed to <code>foo</code>, never gets |
| <code>foo.gif</code>). |
| |
| <P><HR><P> |
| <A HREF="../"><IMG SRC="../images/apache_home.gif" ALT="Home"></A> |
| <A HREF="./"><IMG SRC="../images/apache_index.gif" ALT="Index"></A> |
| |
| </body> </html> |