mirror of
				https://github.com/apache/httpd.git
				synced 2025-10-31 19:10:37 +03:00 
			
		
		
		
	Harrie Hazewinkel <harrie@covalent.net> git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@89426 13f79535-47bb-0310-9956-ffa450edef68
		
			
				
	
	
		
			208 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!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 AP_DECLARE_HOOK macro, which needs to be given the return
 | |
| type of the hook function, the name of the hook, 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>AP_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>
 | |
| APR_HOOK_STRUCT(
 | |
|             APR_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>AP_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>AP_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>AP_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>
 |