You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Andrew Wilson <an...@aaaaaaaa.demon.co.uk> on 1996/06/09 20:30:40 UTC

pre-send API hook...

Hi,

    A pre-send API hook (I love that terminology, although...) is a
bunch of code that gets invoked immediately before the MIME headers
get written out.  By which time we know enough information to build
sensible Expires: headers, and probably other things though I'l
admit I'm biased towards just solving mod_expires.c's problems for
now.

It works like this:

1) send_http_header() is modified to include a call to (say) 
   invoke_presend_handler().
2) invoke_presend_handler is just like invoke_handler but only matches a
   specific MAGIC_PRESEND_TYPE.
3) the modules making use of this add an entry to their handler_rec which
   maps MAGIC_PRESEND_TYPE to come custom code they supply.

Aside from allowing mod_expires.c to read r->no_cache this also
has effect of not breaking the API for existing 3rd party modules.
No need to add new code to existing modules.  Just munge the core
a little so that new funky modules can get to work.

For the sake of mod expires I can move all the code from the 'fixups'
area, which was always the wrong place for the code anyway, and
into presend_handler.

On question is what to do with errors reported by the presend_handler,
if there are any, which proably ranks close to "why don't you just
try to redesign the API properly instead of kludging it Andy?".

Aside, on module API design:

    I guess one of the first things I'd look at is revoking the
    modules' right to call send_http_headers (baaaad design),
    instead forcing modules to deal with the idea that
    they can provide header information in the ->headers_out table,
    but that it's down to the main code in http_request.c's
    process_request[_internal] to make the final call to
    send_http_headers.  process_request_ would then naturally be
    able to call presend_handler too, just prior to calling
    send_http_headers.  Something for 1.3 perhaps...

Some details about the MAGIC_PRESEND_TYPE fix:

A modified send_http_header() would read like:

--- cut here ---
void send_http_header(request_rec *r)
{    
    conn_rec *c = r->connection;
    BUFF *fd = c->client;
    const long int zero=0L;
    array_header *hdrs_arr;
    table_entry *hdrs;
    int i;
    
    core_dir_config *dir_conf =
      (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
    char *default_type = dir_conf->default_type;

    /* possibly care about the return value?!? */
    invoke_presend_handler(r);

    if (r->assbackwards) {
        bsetopt(fd, BO_BYTECT, &zero);
        r->sent_bodyct = 1;
        return;
    }   

...
--- cut here ---

invoke_presend_handler would look like this:

--- cut here ---
int invoke_send_handler (request_rec *r)
{
   module *modp;
   handler_rec *handp;
   char *content_type = r->content_type ? r->content_type : default_type (r);

   for (modp = top_module; modp; modp = modp->next)
   {
       if (!modp->handlers) continue;

       for (handp = modp->handlers; handp->content_type; ++handp) {
           if (!strcasecmp (MAGIC_PRESEND_TYPE, handp->content_type)) {
               int result = (*handp->handler)(r);

               /* unless it breaks we don't care what it does */
               if (result != SERVER_ERROR)
                   return result;
           }
       }
   }
   return OK;
}
--- cut here ---

Modules that wished to make use of this new facility would define
handlers for a MAGIC_PRESEND_TYPE:

handler_rec expires_handlers[] = {
{ "*/*", some_widlcard_handler },
{ "foo/bar", foo_bar_handler },
{ "MAGIC_PRESEND_TYPE", presend_handler },
{ NULL }
};   


Ay.  now going to lie down for a short while ;)