summaryrefslogtreecommitdiffstats
path: root/docs/manual/developer/hooks.html
diff options
context:
space:
mode:
authorDavid Reid <dreid@apache.org>2000-01-15 21:13:50 +0100
committerDavid Reid <dreid@apache.org>2000-01-15 21:13:50 +0100
commit5973d1edff9461ea0873ec7c069b7d1e21df86ab (patch)
treef07bad29b53af70c7a9ecc28e7d1c434bb0d7171 /docs/manual/developer/hooks.html
parentAnother file for the documentation. (diff)
downloadapache2-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.html202
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>