-->
Previous Table of Contents Next


In your access.conf file, find the line that sets the options for the part of the site for which you want to enable content negotiation. (You can also set content negotiation for the whole site.) If MultiViews isn’t present in that line, it must be. Ironically enough, the All value doesn’t include MultiViews. This is again for backward compatibility. So, you might have a line that looks like


Options Indexes Includes Multiviews

or


Options All MultiViews

When the MultiViews parameter is changed, you need to restart your server to implement the new configuration.

With MultiViews turned on, you can do the following: Place a JPEG image in a directory, such as /path/, and call it image.jpg. Now, make an equivalent GIF format image and place it in the same /path/ directory as image.gif. The URLs for these two objects are


http://host/path/image.jpg

and


http://host/path/image.gif

respectively. Now, if you ask your Web browser to fetch


http://host/path/image

the server will go into the /path/ directory, see the two image files, and then determine which image format to send based on what the client says it can support. In the case where the client says it can accept JPEG or GIF images equally, the server will choose the version of the image that’s smaller and send that to the client. Usually, JPEG images are much smaller than GIF images.

So if you made your HTML look something like the following,


<HTML><HEAD>

<TITLE>Welcome to the Gizmo Home Page!</TITLE>

</HEAD><BODY>

<IMG SRC="/header" ALT="GIZMO Logo">

Welcome to Gizmo!

<IMG SRC="/products" ALT="Products">

<IMG SRC="/services" ALT="Services">

you can have separate GIF and JPEG files for header, products, and services. The clients will, for the most part, get what they claim they can support.


NOTE:  If you have a file named image and a file named image.gif, the file named image will be returned if a request is made for image. Likewise, a request specifically for image.gif would never return image.jpg, even if the client knew how to render JPEG images.

Human-Language Negotiation

If MultiViews is enabled, you can also distinguish resources by the language they’re in, such as French, English, and Japanese. This is done by adding more entries to the file suffix name space, which map to the languages the server wants to use, and then by giving them a ranking in which ties can be broken. Specifically, in the srm.conf file, add two new directives—AddLanguage and LanguagePriority. The formats are as follows:


AddLanguage en .en

AddLanguage it .it

AddLanguage fr .fr

AddLanguage jp .jp

LanguagePriority en fr jp it

Suppose that you want to negotiate the language on the file index.html, which you have available in English, French, Italian, and Japanese. You would create index.html.en, index.html.fr, index.html.it, and index.html.jp, respectively, and then reference the document as index.html. When a multilingual client connects, it should indicate in one of the request headers (specifically, Accept-Language) which languages it prefers, and the browser expresses that in standard two-letter notation. The server sees what the clients can accept and gives them “the best one.” LanguagePriority is what organizes that decision of “the best one.” If English is unacceptable to the client, try French; otherwise, try Japanese; otherwise, try Italian. LanguagePriority also states which one should be served if there’s no Accept-Language header.

Because the language-mapping suffixes and the content-type suffixes share the same name space, you can mix them around. index.fr.html is the same as index.html.fr. Just make sure that you reference it with the correct negotiable resource.

As-Is Files

Often, you want to use headers in your documents, such as Expires:, but don’t want to make the page a CGI script. The easiest way is to add the httpd/send-as-is MIME type to the srm.conf file.


AddType httpd/send-as-is asis

This means that any file that ends in .asis can include its own MIME headers. However, it must include two carriage returns before the actual body of the content. Actually, it should include two carriage-return/line-feed combinations, but Apache is forgiving and will insert the line feed for you. So if you want to send a document with a special custom MIME type that you don’t want registered with the server, you can send the following:


Content-type: text/foobar



This is text in a very special "foobar" MIME type.

The most significant application I’ve run across for this is as an extremely efficient mechanism for doing server-push (inline graphic animation) objects without CGI scripts. The reason a CGI script is needed to create a server-push usually is that the content type usually includes the multipart separator (because a server-push is actually a MIME multipart message). In the following examples, XXXXXXXX indicates the boundary between the parts of the multipart message:


Content-type: multipart/x-mixed-replace;boundary=XXXXXXXX

--XXXXXXXX

Content-type: image/gif



....(GIF data)....

--XXXXXXXX

Content-type: image/gif



....(GIF data)....

--XXXXXXXX

....

By making a stream of data a simple file with the .asis parameter in the AddType directive instead of with a CGI script, you potentially save yourself a lot of overhead. Just about the only thing you lose is the capability to do timed pushes. For many people, slow Internet connection acts as a sufficient time valve.

If you have MultiViews turned on, you can add .asis to the end of a filename, and none of your links needs to be renamed. For example, foobar.html can easily become foobar.html.asis, yet you can still call it foobar.html.

One last compelling application of “asis” is being able to do HTTP redirection without needing access to server config files. For example, the following .asis file will redirect people to another location:


Status 302 Moved

Location: http://some.other.place.com/path/

Content-type: text/html



<HTML>

<HEAD><TITLE>We've Moved!</TITLE></HEAD>

<BODY>

<H1>We used to be here, but now we're

<A HREF="http://some.other.place.com/path/">over there. </A>

</H1>

</BODY></HTML>

The HTML body is there simply for clients who don’t understand the 302 response.


Previous Table of Contents Next