You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Ben Laurie <be...@algroup.co.uk> on 2000/12/31 18:19:39 UTC

How to Handle Handlers and Order Hooks (and Other Matters)

OK, so the obvious thing is that handlers should be sorted like hooks. I
initially thought that they should also be sorted according to their
wildness but the more I think about it, the more I think that the whole
handler structure should disappear and be replaced by YAH (Yet Another
Hook). The down side of this is a slight loss of efficiency. The upside
is that handlers can be more subtle about how they match the content
type/handler string (and other things they may want to match), when they
match it, and how they interact with other handlers.

You could argue that they could still do this with an extension of the
current system (i.e. string matching as a prefilter before calling the
handler, which then can be more subtle if desired). Yes, this is true,
but the same must surely be true of all sorts of other hooks, so why
single this one out? Also, it reduces the clarity of the process and
potentially makes handlers do silly things (like match "*" because they
really want to match something completely different) in order to squeeze
into the structure.

So, what I'm inclined to think is that if we want to use "hints" to
prefilter hook calls, we should do it in general, not just for handlers.

With that out of the way, I'd propose to axe the handler structure, and
introduce a new handler_hook, which would look like this:

int handler_hook(const char *handler, request_rec *r);

where handler is the thing currently matched against the string (i.e.
the handler set by SetHandler and friends, or the MIME type). It can
return DECLINED, OK or an error. Anything except DECLINED will stop
processing. Obviously, the first thing most handlers will do is a string
comparison against handler...

OK, next is the question of configured control of ordering.

This one is potentially really easy. We just leverage the existing
{prede,suc)cessor arguments in the hooking calls. What we do is allow
the config file to specify ordering between pairs of modules for a
particular hook, something akin to:

HookOrder handler mod_dir mod_autoindex

which would cause mod_dir's handler hook to run before mod_autoindex'.
There are two issues, one new, one not new. The first is naming - we
_really_ should have a global namespace for modules. Its time to stop
avoiding this question! I propose we use something akin to Java -
derived from DNS. I see no need to use backwards DNS, though. My initial
thought is that global module names would look like this:
"<FQDN>/<localname>". So, mod_autoindex would be
"httpd.apache.org/autoindex", for example. Mod_backhand would be
"cnds.jhu.edu/backhand" (say). Then the HookOrder directive would look
like:

HookOrder handler httpd.apache.org/dir httpd.apache.org/autoindex

(if people object the URL-ish look, we could use "-" instead of "/",
which makes it clear we're doing something totally different). Oh, I'd
include the module name somewhere in the module structure, so we can
enumerate them, BTW.

OK, the other issue is this - should we introduce the concept of
mandatory and overridable {prede,suc}cessors? The idea being that
overridable ones can be overridden by config (but specify the "usually
appropriate" order), but mandatory ones can't? Or should we say that if
they are what we'd consider overridable, then they MUST be configured. I
don't hugely like the second option, because I firmly believe that you
should be able to run Apache with an almost empty configuration. And,
that it should be as obvious as possible what needs configuring when it
does.

Oh, BTW, if we do this, we get I/O filtering ordering for free. Cool, or
what?

So, once more, opinions, please.

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff

Re: How to Handle Handlers and Order Hooks (and Other Matters)

Posted by rb...@covalent.net.
> > I dislike calling every handler, even if we could tell before-hand that we
> > aren't going to use it.
> > 
> > Could the handlers register a hook with the following call:
> > 
> > ap_register_handler(char *handler, func *handler_func, pred, succ, order);
> > 
> > The core could then keep track of everything internally.  Allowing us to
> > use a simple table to determine which Handler should be called, but making
> > things look like hooks to Apache.
> 
> I agree, but I believe that the ability for the core to prefilter hook
> functions is something that can be done for other hooks, too. So, if we
> are going to have this ability, we should have it across the board,
> rather than special-casing this particular one. Once you agree that,
> then you should agree that an acceptable interim solution is to _not_
> prefilter for now, but note that we should. Its an optimisation.

I agree that this might be useful for other hook functions.  I disagree
that this is just an optimization.  While it is an optimization, what
concerns me is that it has implications for the API.  I would prefer to
not have to change the way handlers work in the middle of the 2.0
series.  If we do change such a basic API, then we have lost all hope for
compatability.  If we do the original design with the idea in mind, then
we might be able to keep a single API throughout.  I agree this is harder,
but it is worth trying.

Did you see my comment about filters at the bottom?

> However, I'm now halfway through type-safe generic hooks (i.e. ones that
> modules can export but don't screw up if the module isn't there). I
> think I have a rather elegant solution to this, so I'm going to stick
> with it for now. I'll present it later today, I hope.

I look forward to seeing it.  BTW, I have the NULL pool hack completely
removed now, but I can't commit it.  As soon as I can, I'll see if this
solves our big memory leak on FreeBSD.  :-)

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: How to Handle Handlers and Order Hooks (and Other Matters)

Posted by Ben Laurie <be...@algroup.co.uk>.
rbb@covalent.net wrote:
> 
> I wanted the day to think about this.  :-)
> 
> I almost like it.  My only concern, is the matching.  If I understand what
> you are saying, each handler would register a function, without specifying
> the char *, then the core would call every handler, and pass them the
> (Handler, Mime-Type, etc).  The handler would then either return quickly
> with a DECLINED, or it would try to process the request.  Is that correct?

Yes.

> I dislike calling every handler, even if we could tell before-hand that we
> aren't going to use it.
> 
> Could the handlers register a hook with the following call:
> 
> ap_register_handler(char *handler, func *handler_func, pred, succ, order);
> 
> The core could then keep track of everything internally.  Allowing us to
> use a simple table to determine which Handler should be called, but making
> things look like hooks to Apache.

I agree, but I believe that the ability for the core to prefilter hook
functions is something that can be done for other hooks, too. So, if we
are going to have this ability, we should have it across the board,
rather than special-casing this particular one. Once you agree that,
then you should agree that an acceptable interim solution is to _not_
prefilter for now, but note that we should. Its an optimisation.

However, I'm now halfway through type-safe generic hooks (i.e. ones that
modules can export but don't screw up if the module isn't there). I
think I have a rather elegant solution to this, so I'm going to stick
with it for now. I'll present it later today, I hope.

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff

Re: How to Handle Handlers and Order Hooks (and Other Matters)

Posted by rb...@covalent.net.
> >  We also don't really use the standard hooks
> > mechanism for the filters at all, so this probably won't help much in that
> > respect.
> 
> ?? What about the insert_filter hook? Ordering those would determine the
> order of filters, right?

That was the original idea, but it just doesn't work that way for the most
part.  The thing is, that most filters are content filters, and content
filters don't tend to be inserted by the module that implements them.  For
example, the INCLUDES filter.  If mod_include was going to insert itself
into the request chain, then mod_include would need to have a config
directive that to specify when it is should be inserted into the filter
chain.  Of course, if that happens, then EVERY module would need to same
general logic.

The insert_filter hook works great for connection filters, but content
filters tend to need to be specified in the config file, so the hooks
stuff just doesn't work.  What we need is a much more powerful version of
AddOutputFilter.  What I have designed (but not implemented, maybe later
today), is something like:

DefineFilterStack  Include_stack  INCLUDES CACHE

SetFilter Include_stack .html .htm
AddFilter Include_stack text/html


Basically, we define a bunch of filter chains, and then just specify the
correct filter chain for each file/directory.

Ryan


_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: How to Handle Handlers and Order Hooks (and Other Matters)

Posted by Ben Laurie <be...@algroup.co.uk>.
rbb@covalent.net wrote:
> Almost, but not really.  We still need to figure out how to specify a
> filter for use in a request (I have the logic figured out, but I haven't
> written the code yet).

Possibly so.

>  We also don't really use the standard hooks
> mechanism for the filters at all, so this probably won't help much in that
> respect.

?? What about the insert_filter hook? Ordering those would determine the
order of filters, right?

OTOH, they may want to do it per-request, I spose.

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff

Re: How to Handle Handlers and Order Hooks (and Other Matters)

Posted by rb...@covalent.net.
I wanted the day to think about this.  :-)

I almost like it.  My only concern, is the matching.  If I understand what
you are saying, each handler would register a function, without specifying
the char *, then the core would call every handler, and pass them the
(Handler, Mime-Type, etc).  The handler would then either return quickly
with a DECLINED, or it would try to process the request.  Is that correct?

I dislike calling every handler, even if we could tell before-hand that we
aren't going to use it.

Could the handlers register a hook with the following call:

ap_register_handler(char *handler, func *handler_func, pred, succ, order);

The core could then keep track of everything internally.  Allowing us to
use a simple table to determine which Handler should be called, but making
things look like hooks to Apache.

Ryan

On Mon, 1 Jan 2001, Ben Laurie wrote:

> Stunned you into silence, eh? I need some feedback one way or the other.
> Or should I just do it and await the screams?
> 
> Cheers,
> 
> Ben.
> 
> Ben Laurie wrote:
> > 
> > OK, so the obvious thing is that handlers should be sorted like hooks. I
> > initially thought that they should also be sorted according to their
> > wildness but the more I think about it, the more I think that the whole
> > handler structure should disappear and be replaced by YAH (Yet Another
> > Hook). The down side of this is a slight loss of efficiency. The upside
> > is that handlers can be more subtle about how they match the content
> > type/handler string (and other things they may want to match), when they
> > match it, and how they interact with other handlers.
> > 
> > You could argue that they could still do this with an extension of the
> > current system (i.e. string matching as a prefilter before calling the
> > handler, which then can be more subtle if desired). Yes, this is true,
> > but the same must surely be true of all sorts of other hooks, so why
> > single this one out? Also, it reduces the clarity of the process and
> > potentially makes handlers do silly things (like match "*" because they
> > really want to match something completely different) in order to squeeze
> > into the structure.
> > 
> > So, what I'm inclined to think is that if we want to use "hints" to
> > prefilter hook calls, we should do it in general, not just for handlers.
> > 
> > With that out of the way, I'd propose to axe the handler structure, and
> > introduce a new handler_hook, which would look like this:
> > 
> > int handler_hook(const char *handler, request_rec *r);
> > 
> > where handler is the thing currently matched against the string (i.e.
> > the handler set by SetHandler and friends, or the MIME type). It can
> > return DECLINED, OK or an error. Anything except DECLINED will stop
> > processing. Obviously, the first thing most handlers will do is a string
> > comparison against handler...
> > 
> > OK, next is the question of configured control of ordering.
> > 
> > This one is potentially really easy. We just leverage the existing
> > {prede,suc)cessor arguments in the hooking calls. What we do is allow
> > the config file to specify ordering between pairs of modules for a
> > particular hook, something akin to:
> > 
> > HookOrder handler mod_dir mod_autoindex
> > 
> > which would cause mod_dir's handler hook to run before mod_autoindex'.
> > There are two issues, one new, one not new. The first is naming - we
> > _really_ should have a global namespace for modules. Its time to stop
> > avoiding this question! I propose we use something akin to Java -
> > derived from DNS. I see no need to use backwards DNS, though. My initial
> > thought is that global module names would look like this:
> > "<FQDN>/<localname>". So, mod_autoindex would be
> > "httpd.apache.org/autoindex", for example. Mod_backhand would be
> > "cnds.jhu.edu/backhand" (say). Then the HookOrder directive would look
> > like:
> > 
> > HookOrder handler httpd.apache.org/dir httpd.apache.org/autoindex
> > 
> > (if people object the URL-ish look, we could use "-" instead of "/",
> > which makes it clear we're doing something totally different). Oh, I'd
> > include the module name somewhere in the module structure, so we can
> > enumerate them, BTW.
> > 
> > OK, the other issue is this - should we introduce the concept of
> > mandatory and overridable {prede,suc}cessors? The idea being that
> > overridable ones can be overridden by config (but specify the "usually
> > appropriate" order), but mandatory ones can't? Or should we say that if
> > they are what we'd consider overridable, then they MUST be configured. I
> > don't hugely like the second option, because I firmly believe that you
> > should be able to run Apache with an almost empty configuration. And,
> > that it should be as obvious as possible what needs configuring when it
> > does.
> > 
> > Oh, BTW, if we do this, we get I/O filtering ordering for free. Cool, or
> > what?

Almost, but not really.  We still need to figure out how to specify a
filter for use in a request (I have the logic figured out, but I haven't
written the code yet).  We also don't really use the standard hooks
mechanism for the filters at all, so this probably won't help much in that
respect.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------



Re: How to Handle Handlers and Order Hooks (and Other Matters)

Posted by Ben Laurie <be...@algroup.co.uk>.
Stunned you into silence, eh? I need some feedback one way or the other.
Or should I just do it and await the screams?

Cheers,

Ben.

Ben Laurie wrote:
> 
> OK, so the obvious thing is that handlers should be sorted like hooks. I
> initially thought that they should also be sorted according to their
> wildness but the more I think about it, the more I think that the whole
> handler structure should disappear and be replaced by YAH (Yet Another
> Hook). The down side of this is a slight loss of efficiency. The upside
> is that handlers can be more subtle about how they match the content
> type/handler string (and other things they may want to match), when they
> match it, and how they interact with other handlers.
> 
> You could argue that they could still do this with an extension of the
> current system (i.e. string matching as a prefilter before calling the
> handler, which then can be more subtle if desired). Yes, this is true,
> but the same must surely be true of all sorts of other hooks, so why
> single this one out? Also, it reduces the clarity of the process and
> potentially makes handlers do silly things (like match "*" because they
> really want to match something completely different) in order to squeeze
> into the structure.
> 
> So, what I'm inclined to think is that if we want to use "hints" to
> prefilter hook calls, we should do it in general, not just for handlers.
> 
> With that out of the way, I'd propose to axe the handler structure, and
> introduce a new handler_hook, which would look like this:
> 
> int handler_hook(const char *handler, request_rec *r);
> 
> where handler is the thing currently matched against the string (i.e.
> the handler set by SetHandler and friends, or the MIME type). It can
> return DECLINED, OK or an error. Anything except DECLINED will stop
> processing. Obviously, the first thing most handlers will do is a string
> comparison against handler...
> 
> OK, next is the question of configured control of ordering.
> 
> This one is potentially really easy. We just leverage the existing
> {prede,suc)cessor arguments in the hooking calls. What we do is allow
> the config file to specify ordering between pairs of modules for a
> particular hook, something akin to:
> 
> HookOrder handler mod_dir mod_autoindex
> 
> which would cause mod_dir's handler hook to run before mod_autoindex'.
> There are two issues, one new, one not new. The first is naming - we
> _really_ should have a global namespace for modules. Its time to stop
> avoiding this question! I propose we use something akin to Java -
> derived from DNS. I see no need to use backwards DNS, though. My initial
> thought is that global module names would look like this:
> "<FQDN>/<localname>". So, mod_autoindex would be
> "httpd.apache.org/autoindex", for example. Mod_backhand would be
> "cnds.jhu.edu/backhand" (say). Then the HookOrder directive would look
> like:
> 
> HookOrder handler httpd.apache.org/dir httpd.apache.org/autoindex
> 
> (if people object the URL-ish look, we could use "-" instead of "/",
> which makes it clear we're doing something totally different). Oh, I'd
> include the module name somewhere in the module structure, so we can
> enumerate them, BTW.
> 
> OK, the other issue is this - should we introduce the concept of
> mandatory and overridable {prede,suc}cessors? The idea being that
> overridable ones can be overridden by config (but specify the "usually
> appropriate" order), but mandatory ones can't? Or should we say that if
> they are what we'd consider overridable, then they MUST be configured. I
> don't hugely like the second option, because I firmly believe that you
> should be able to run Apache with an almost empty configuration. And,
> that it should be as obvious as possible what needs configuring when it
> does.
> 
> Oh, BTW, if we do this, we get I/O filtering ordering for free. Cool, or
> what?
> 
> So, once more, opinions, please.
> 
> Cheers,
> 
> Ben.
> 
> --
> http://www.apache-ssl.org/ben.html
> 
> "There is no limit to what a man can do or how far he can go if he
> doesn't mind who gets the credit." - Robert Woodruff

--
http://www.apache-ssl.org/ben.html

"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff