httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Sutton <p...@ukweb.com>
Subject Negotiation updates, and transparent neg.
Date Mon, 19 Aug 1996 13:53:26 GMT
In some mail I sent a couple of weeks ago I noted that Apache doesn't
do content negotiation fully according to HTTP/1.1.  For example, it
doesn't handle any Charset negotiation, or 'q' values on
Accept-Language lines. I've made some changes to implement these.

While doing this, I thought it would be useful to update the code so
that it can handler additional negotiation algorithms, in particular,
to allow implementation of transparent negotiation. I did this, then
actually implemented to negotiation from the Holtman draft.  Even if
this gets changed around a lot in the future, the code can now easily
accept new negotiation algorithms and customisations. I've implemented
most of the Holtman draft except for (a) cache control stuff and (b)
features (which are vaguely defined). Note that the Holtman stuff does
not affect existing functionality unless the browser sends a
Negotiate: header.

So, my patch does two things:

  * Updates Apache to properly support HTTP/1.1 server-driven
    negotiation
  * Updates Apache to support most of the Holtman draft

I've FTP'ed it to hyperreal, in /httpd/incoming/mod_negotiation.patch

Changes:
--------

 To support HTTP/1.1:

   1. Accept-Language negotiated correctly using 'q' values
      (also now matches on language prefix, and handles '*')
   2. Accept-Charset negotation done
   3. Accept-Encoding updated to never send unacceptable encodings
   4. After a 406 error status, the body will include a HTML
      list of variants
   5. Sets Vary: to just the headers negotiated on

 For Holtman draft:

   1. Transparent negotiation _only_ enabled if Negotiate:
      header received
   2. Implements 'short accept header' response
   3. Implements the Network Algorithm
   4. Implements "List" (300) and "Choice" responses
   5. For "List" 300 responses, outputs variants as HTML list
   6. Updated Vary: header (including 'negotiate' tag)
   7. Generates "Alternates:" header where appropriate
   8. Sets Variant-Vary, Content-Location as appropriate
   9. Adds error code 506 Variant Also Varies status

Patch Details
-------------

The patch modifies five files:

   http_protocol.c/
            httpd.h  -- adds 506 error status
   alloc.c/alloc.h   -- adds table_set_data() func to set a table
                        entry whose value is not a string
   mod_negotiation.c -- all the rest

Implementation Notes
--------------------

The new code in mod_negotiation.c is fairly throughly commented.

The biggest problem implementing this was getting the functionality
where a 300 or 406 error status output a list of variants in the
body. Normally, the module would return the appropriate status (300 or
406) which the called (process_request_internal or whatever) could
then pass on to the error response routine. The problem is, how does
the error handler get at the variant information? One way would be a
callback to the module, keyed on error status code...  but that might
be too general. Perhaps there is a simple way to do this that I am
missing?

I didn't want to play around with the API or data structures, so
I've faked this up like this: if the module would return 300
or 406 status, it instead changes the handler text of the request to
a special text. The module then has a handler for this text, which
actually does the output. This is only needed if mod_negotiation is
called during the type_checker phase... if called with the var-map
handler, it can output the HTML code directly.

But that isn't quite all. As well as getting the right code executed
to output for 300 and 406 status, the mod_negotiation internal data
structure storing the variants needs to be available during this
handler call. That is, it needs to be stored with the
request_rec. There is a 'notes' structure for just this sort of
purpose, but it can only store strings, not binary data. I added a
function, table_set_data() to store binary data in the notes structure
(keyed on a normal string). Since other modules should ignore notes
data that they don't understand, this shouldn't be a problem.

---

Phew, that's it.

Paul


Mime
View raw message