httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From (Robert S. Thau)
Subject Re: pre-send API hook...
Date Sun, 09 Jun 1996 20:27:17 GMT

      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

Ummm... I don't think you've established whether this is the *right*
way to solve those problems.  In any case, if you feel the need to
hack the API, you should really think *first* about whether there are
other applications for the idea, and if so, what they might look like
--- tossing stuff around in the API should *not* be done casually.
(A lot of things were added to early versions to make mod_negotiation
function as a module --- every one of which is presently in use by
something else as well).

I don't think the the r->no_cache business is sufficient argument,
BTW; as I indicated in my last note, the proper treatment of
r->no_cache really is dependant on protocol version, among many other
things.  In other words, the exact way *how* to signal that a response
should not be cached is a protocol issue, and http_protocol.c exists
to keep those things straight (even if it is sometimes by smashing a
header or two which *might* have been set by a module; this is a case
of "mother knows best").

A deliberate goal for the API design was to keep things that are
conditional on protocol version *out* of the modules, and that's not
something I'll abandon easily (particularly not with session-layer
coming down the pike).

  It works like this:

  1) send_http_header() is modified to include a call to (say) 
  2) invoke_presend_handler is just like invoke_handler but only matches a
     specific MAGIC_PRESEND_TYPE.

This, in any case, is clearly wrong.  The "media type" application/x-httpd-cgi
is enough of an abuse (and one we're trying to get away from with Alexei's
actions stuff).

  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?".

Well, you said it...

  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

Ummm... I thought that setting headers in the table, and leaving the
exact formatting up to http_protocol.c was the way it already worked.
The r->headers_out table is *not* an exact mirror of the outgoing
headers, and never was supposed to be --- viz. the headers that are
added in basic_http_header et al.

    process_request_ would then naturally be
    able to call presend_handler too, just prior to calling
    send_http_headers.  Something for 1.3 perhaps...

Ah.  You want to break every response handler down the middle between
the code that runs *before* the "presend handler" and what runs
afterwards.  So, let's say mod_cgi.c starts off some script, reads the
CGI headers, and is at the point of deciding whether to do an internal
redirect.  If it decides to do that, it's important that
send_http_header not have been called already, since the headers in
this particular request_rec are not relevant to the redirected-to
object.  This means that the headers haven't been sent at all yet,
which poses a wee bit of a problem if the cgi_handler instead decides
to send the script's output straight back to the client.  The natural
thing for it to do would be to call send_http_header in this case.
But you've "revoked" its permission to do so.

(The same problem arises in several other uses of internal_redirect,
including handling in mod_dir.c, and mod_negotiation of
course; it can also be found in somewhat milder form in things that
*don't* call internal_redirect --- in particular mod_asis.c, which
doesn't know the complete set of headers to send until it has opened
and parsed the target file).

One way out of this would be having the first call to rprintf,
send_fd, or whatever send the HTTP headers behind the module's back.
However, there's a problem with this from a stylistic standpoint,
because an action like this is something that you really should be
conscious of while writing the code --- otherwise, there's no visible
marker to say that "setting r->headers_out past this point will have
no effect" --- i.e., when it is useful to set a new header in the
table, and when it is too late.  (This follows a general rule that
libraries of all sorts shouldn't do too many things behind their
callers' backs).

So, how can we remove this blemish?  Well, we could require an
explicit function call for the module to indicate to the core that the
headers_out array is complete, and no further changes are
contemplated.  So, the cgi_handler in particular would call this
function after reading the CGI headers and deciding that the response
was to be passed directly to the client.  That core function would
then be the natural place to deal with with whatever's there, format
it correctly, deal with any inconsistencies, add standard stuff like
Server: which modules shouldn't be bothered with, maybe even call a
"presend handler" if we agree on the need for one, and send it all to
the client.  But that's where we started, isn't it?

BTW, if you really think this is such a kludge, I can't help wondering
why you're only mentioning it now.  When I first released the
Shambhala effort to the group, I was *expecting* a lot of
back-and-forth over API details, and requests for improvements.  I got
nothing.  And at this point, regardless your opinion of the merits,
it's a little late for such a drastic change...


View raw message