diff options
author | David Reid <dreid@apache.org> | 2000-01-15 21:13:50 +0100 |
---|---|---|
committer | David Reid <dreid@apache.org> | 2000-01-15 21:13:50 +0100 |
commit | 5973d1edff9461ea0873ec7c069b7d1e21df86ab (patch) | |
tree | f07bad29b53af70c7a9ecc28e7d1c434bb0d7171 /docs/manual/developer/hooks.html | |
parent | Another file for the documentation. (diff) | |
download | apache2-5973d1edff9461ea0873ec7c069b7d1e21df86ab.tar.xz apache2-5973d1edff9461ea0873ec7c069b7d1e21df86ab.zip |
The remaining files for the new documentation.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@84468 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'docs/manual/developer/hooks.html')
-rw-r--r-- | docs/manual/developer/hooks.html | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/docs/manual/developer/hooks.html b/docs/manual/developer/hooks.html new file mode 100644 index 0000000000..39f4e8bad1 --- /dev/null +++ b/docs/manual/developer/hooks.html @@ -0,0 +1,202 @@ +<!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" +> + +<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> +</body> +</html> |