| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> |
| <html> |
| <head> |
| <title>Apache 2.0 Hook Functions</title> |
| </head> |
| |
| <!-- Background white, links blue (unvisited), navy (visited), red (active) --> |
| <BODY |
| BGCOLOR="#FFFFFF" |
| TEXT="#000000" |
| LINK="#0000FF" |
| VLINK="#000080" |
| ALINK="#FF0000" |
| > |
| |
| <!--#include virtual="header.html" --> |
| |
| <H1 align="center">Apache Hook Functions</H1> |
| |
| <P>In general, a hook function is one that Apache will call at some |
| point during the processing of a request. Modules can provide |
| functions that are called, and specify when they get called in |
| comparison to other modules.</P> |
| |
| <H2>Creating a hook function</H2> |
| |
| <P>In order to create a new hook, four things need to be done:</P> |
| |
| <H3>Declare the hook function</H3> |
| |
| <P>Use the DECLARE_HOOK macro, which needs to be given the name of the |
| hook, the return type of the hook function and the arguments. For |
| example, if the hook returns an <TT>int</TT> and takes a |
| <TT>request_rec *</TT> and an <TT>int</TT> and is called |
| "do_something", then declare it like this:</P> |
| |
| <TT>DECLARE_HOOK(int,do_something,(request_rec *r,int n))</TT> |
| |
| <P>This should go in a header which modules will include if they want |
| to use the hook.</P> |
| |
| <H3>Create the hook structure</H3> |
| |
| <P>Each source file that exports a hook has a private structure which |
| is used to record the module functions that use the hook. This is |
| declared as follows:</P> |
| |
| <PRE> |
| HOOK_STRUCT( |
| HOOK_LINK(do_something) |
| ... |
| ) |
| </PRE> |
| |
| <H3>Implement the hook caller</H3> |
| |
| <P>The source file that exports the hook has to implement a function |
| that will call the hook. There are currently three possible ways to do |
| this. In all cases, the calling function is called |
| <TT>ap_run_<I>hookname</I>()</TT>.</P> |
| |
| <H4>Void hooks</H4> |
| |
| <P>If the return value of a hook is <TT>void</TT>, then all the hooks are |
| called, and the caller is implemented like this:</P> |
| |
| <TT>IMPLEMENT_HOOK_VOID(do_something,(request_rec *r,int |
| n),(r,n))</TT> |
| |
| <P>The second and third arguments are the dummy argument declaration and |
| the dummy arguments as they will be used when calling the hook. In |
| other words, this macro expands to something like this:</P> |
| |
| <PRE> |
| void ap_run_do_something(request_rec *r,int n) |
| { |
| ... |
| do_something(r,n); |
| } |
| </PRE> |
| |
| <H4>Hooks that return a value</H4> |
| |
| <P>If the hook returns a value, then it can either be run until the first |
| hook that does something interesting, like so:</P> |
| |
| <TT>IMPLEMENT_HOOK_RUN_FIRST(int,do_something,(request_rec *r,int n),(r,n),DECLINED)</TT> |
| |
| <P>The first hook that <I>doesn't</I> return <TT>DECLINED</TT> stops |
| the loop and its return value is returned from the hook caller. Note |
| that <TT>DECLINED</TT> is the tradition Apache hook return meaning "I |
| didn't do anything", but it can be whatever suits you.</P> |
| |
| <P>Alternatively, all hooks can be run until an error occurs. This |
| boils down to permitting <I>two</I> return values, one of which means |
| "I did something, and it was OK" and the other meaning "I did |
| nothing". The first function that returns a value other than one of |
| those two stops the loop, and its return is the return value. Declare |
| these like so:</P> |
| |
| <TT>IMPLEMENT_HOOK_RUN_ALL(int,do_something,(request_rec *r,int |
| n),(r,n),OK,DECLINED)</TT> |
| |
| <P>Again, <TT>OK</TT> and <TT>DECLINED</TT> are the traditional |
| values. You can use what you want.</P> |
| |
| <H3>Call the hook callers</H3> |
| |
| <P>At appropriate moments in the code, call the hook caller, like |
| so:</P> |
| |
| <PRE> |
| int n,ret; |
| request_rec *r; |
| |
| ret=ap_run_do_something(r,n); |
| </PRE> |
| |
| <H2>Hooking the hook</H2> |
| |
| <P>A module that wants a hook to be called needs to do two |
| things.</P> |
| |
| <H3>Implement the hook function</H3> |
| |
| <P>Include the appropriate header, and define a static function of the |
| correct type:</P> |
| |
| <PRE> |
| static int my_something_doer(request_rec *r,int n) |
| { |
| ... |
| return OK; |
| } |
| </PRE> |
| |
| <H3>Add a hook registering function</H3> |
| |
| <P>During initialisation, Apache will call each modules hook |
| registering function, which is included in the module structure:</P> |
| |
| <PRE> |
| static void my_register_hooks() |
| { |
| ap_hook_do_something(my_something_doer,NULL,NULL,HOOK_MIDDLE); |
| } |
| |
| mode MODULE_VAR_EXPORT my_module = |
| { |
| ... |
| my_register_hooks /* register hooks */ |
| }; |
| </PRE> |
| |
| <H3>Controlling hook calling order</H3> |
| |
| <P>In the example above, we didn't use the three arguments in the hook |
| registration function that control calling order. There are two |
| mechanisms for doing this. The first, rather crude, method, allows us |
| to specify roughly where the hook is run relative to other |
| modules. The final argument control this. There are three possible |
| values:</P> |
| |
| <PRE> |
| HOOK_FIRST |
| HOOK_MIDDLE |
| HOOK_LAST |
| </PRE> |
| |
| <P>All modules using any particular value may be run in any order |
| relative to each other, but, of course, all modules using |
| <TT>HOOK_FIRST</TT> will be run before <TT>HOOK_MIDDLE</TT> which are |
| before <TT>HOOK_LAST</TT>. Modules that don't care when they are run |
| should use <TT>HOOK_MIDDLE</TT>. <I>(I spaced these out so people |
| could do stuff like <TT>HOOK_FIRST-2</TT> to get in slightly earlier, |
| but is this wise? - Ben)</I></P> |
| |
| <P>Note that there are two more values, <TT>HOOK_REALLY_FIRST</TT> and |
| <TT>HOOK_REALLY_LAST</TT>. These should only be used by the hook |
| exporter.</P> |
| |
| <P>The other method allows finer control. When a module knows that it |
| must be run before (or after) some other modules, it can specify them |
| by name. The second (third) argument is a NULL-terminated array of |
| strings consisting of the names of modules that must be run before |
| (after) the current module. For example, suppose we want "mod_xyz.c" |
| and "mod_abc.c" to run before we do, then we'd hook as follows:</P> |
| |
| <PRE> |
| static void register_hooks() |
| { |
| static const char * const aszPre[]={ "mod_xyz.c", "mod_abc.c", NULL }; |
| |
| ap_hook_do_something(my_something_doer,aszPre,NULL,HOOK_MIDDLE); |
| } |
| </PRE> |
| |
| <P>Note that the sort used to achieve this is stable, so ordering set |
| by <TT>HOOK_<I>ORDER</I></TT> is preserved, as far as is |
| possible.</P> |
| |
| <I>Ben Laurie, 15th August 1999</I> |
| |
| <!--#include virtual="footer.html" --> |
| |
| </body> |
| </html> |