16.3 Content Negotiation

Content negotiation is a wonderful feature that was introduced with HTTP/1.1. Unfortunately it is not yet widely supported. Probably the most popular usage scenario for content negotiation is language negotiation for multilingual sites. Users specify in their browsers' preferences the languages they can read and order them according to their ability. When the browser sends a request to the server, among the headers it sends it also includes an Accept-Language header. The server uses the Accept-Language header to determine which of the available representations of the document best fits the user's preferences. But content negotiation is not limited to language. Quoting the specification:

HTTP/1.1 includes the following request-header fields for enabling server-driven 
negotiation through description of user agent capabilities and user preferences: 
Accept (section 14.1), Accept-Charset (section 14.2), Accept-Encoding (section 14.3), 
Accept-Language (section 14.4), and User-Agent (section 14.43). However, an origin 
server is not limited to these dimensions and MAY vary the response based on any 
aspect of the request, including information outside the request-header fields or 
within extension header fields not defined by this specification.

16.3.1 The Vary Header

To signal to the recipient that content negotiation has been used to determine the best available representation for a given request, the server must include a Vary header. This tells the recipient which request headers have been used to determine the representation that is used. So an answer may be generated like this:

$r->header_out('Vary', join ", ", 
               qw(accept accept-language accept-encoding user-agent));

The header of a very cool page may greet the user with something like this:

Hallo Harri, Dein NutScrape versteht zwar PNG aber leider kein GZIP.

However, this header has the side effect of being expensive for a caching proxy. As of this writing, Squid (Version 2.3.STABLE4) does not cache resources that come with a Vary header at all. So without a clever workaround, the Squid accelerator is of no use for these documents.

    Part I: mod_perl Administration
    Part II: mod_perl Performance
    Part VI: Appendixes