hooks.html.en revision 1eba1be63201689b2d3e651d3a35f0bc2057e2c0
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><!--
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend This file is generated from xml source: DO NOT EDIT
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8b7e19de6d547ab1ad4256316fbf0d2497f724f8humbedooh<title>Apache 2.0 Hook Functions - Apache HTTP Server</title>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<link href="/style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<link href="/style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen<link href="/style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" />
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen<link href="/images/favicon.ico" rel="shortcut icon" /></head>
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/directives.html">Directives</a> | <a href="/faq/">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<div class="up"><a href="./"><img title="<-" alt="<-" src="/images/left.gif" /></a></div>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<a href="http://www.apache.org/">Apache</a> > <a href="http://httpd.apache.org/">HTTP Server</a> > <a href="http://httpd.apache.org/docs-project/">Documentation</a> > <a href="../">Version 2.1</a></div><div id="page-content"><div id="preamble"><h1>Apache 2.0 Hook Functions</h1>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>This document is still in development and may be partially out of
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd <p>In general, a hook function is one that Apache will call at
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd some point during the processing of a request. Modules can
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend provide functions that are called, and specify when they get
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend called in comparison to other modules.</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<div id="quickview"><ul id="toc"><li><img alt="" src="/images/down.gif" /> <a href="#create">Creating a hook function</a></li>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<li><img alt="" src="/images/down.gif" /> <a href="#hooking">Hooking the hook</a></li>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<h2><a name="create" id="create">Creating a hook function</a></h2>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>In order to create a new hook, four things need to be
8b7e19de6d547ab1ad4256316fbf0d2497f724f8humbedooh <h3><a name="create-declare" id="create-declare">Declare the hook function</a></h3>
8b7e19de6d547ab1ad4256316fbf0d2497f724f8humbedooh <p>Use the <code>AP_DECLARE_HOOK</code> macro, which needs to be given
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend the return type of the hook function, the name of the hook, and the
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend arguments. For example, if the hook returns an <code>int</code> and
dc06c0ac17fcd3d721bb865d7fc5d2cefe67c57ftrawick takes a <code>request_rec *</code> and an <code>int</code> and is
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend called <code>do_something</code>, then declare it like this:</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend AP_DECLARE_HOOK(int, do_something, (request_rec *r, int n))
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>This should go in a header which modules will include if
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend they want to use the hook.</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <h3><a name="create-create" id="create-create">Create the hook structure</a></h3>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>Each source file that exports a hook has a private structure
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend which is used to record the module functions that use the hook.
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend This is declared as follows:</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend APR_HOOK_STRUCT(<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend APR_HOOK_LINK(do_something)<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <h3><a name="create-implement" id="create-implement">Implement the hook caller</a></h3>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>The source file that exports the hook has to implement a
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend function that will call the hook. There are currently three
8b7e19de6d547ab1ad4256316fbf0d2497f724f8humbedooh possible ways to do this. In all cases, the calling function is
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>If the return value of a hook is <code>void</code>, then all the
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend hooks are called, and the caller is implemented like this:</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend AP_IMPLEMENT_HOOK_VOID(do_something, (request_rec *r, int n), (r, n))
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>The second and third arguments are the dummy argument
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend declaration and the dummy arguments as they will be used when
d8925e7b1eb8644294705d7132173f6fcfe0350ahumbedooh calling the hook. In other words, this macro expands to
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend something like this:</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend void ap_run_do_something(request_rec *r, int n)<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend do_something(r, n);<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>If the hook returns a value, then it can either be run until
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend the first hook that does something interesting, like so:</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend AP_IMPLEMENT_HOOK_RUN_FIRST(int, do_something, (request_rec *r, int n), (r, n), DECLINED)
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>The first hook that does <em>not</em> return <code>DECLINED</code>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend stops the loop and its return value is returned from the hook
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend caller. Note that <code>DECLINED</code> is the tradition Apache
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend hook return meaning "I didn't do anything", but it can be
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend whatever suits you.</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>Alternatively, all hooks can be run until an error occurs.
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend This boils down to permitting <em>two</em> return values, one of
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend which means "I did something, and it was OK" and the other
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend meaning "I did nothing". The first function that returns a
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend value other than one of those two stops the loop, and its
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend return is the return value. Declare these like so:</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend AP_IMPLEMENT_HOOK_RUN_ALL(int, do_something, (request_rec *r, int n), (r, n), OK, DECLINED)
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>Again, <code>OK</code> and <code>DECLINED</code> are the traditional
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend values. You can use what you want.</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <h3><a name="create-call" id="create-call">Call the hook callers</a></h3>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>At appropriate moments in the code, call the hook caller,
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend like so:</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend int n, ret;<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend request_rec *r;<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend ret=ap_run_do_something(r, n);
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend<h2><a name="hooking" id="hooking">Hooking the hook</a></h2>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>A module that wants a hook to be called needs to do two
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend things.</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <h3><a name="hooking-implement" id="hooking-implement">Implement the hook function</a></h3>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>Include the appropriate header, and define a static function
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend of the correct type:</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend static int my_something_doer(request_rec *r, int n)<br />
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin return OK;<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <h3><a name="hooking-add" id="hooking-add">Add a hook registering function</a></h3>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>During initialisation, Apache will call each modules hook
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin registering function, which is included in the module
8951c7d73bfa2ae5a2c8fe5bd27f3e677be02564noirin structure:</p>
1050464f9f91f75e7a1c5c3daf3fb7b8aa74592ahumbedooh static void my_register_hooks()<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend ap_hook_do_something(my_something_doer, NULL, NULL, HOOK_MIDDLE);<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend mode MODULE_VAR_EXPORT my_module =<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend my_register_hooks /* register hooks */<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <h3><a name="hooking-order" id="hooking-order">Controlling hook calling order</a></h3>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>In the example above, we didn't use the three arguments in
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend the hook registration function that control calling order.
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend There are two mechanisms for doing this. The first, rather
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend crude, method, allows us to specify roughly where the hook is
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend run relative to other modules. The final argument control this.
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend There are three possible values: <code>HOOK_FIRST</code>,
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>All modules using any particular value may be run in any
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend order relative to each other, but, of course, all modules using
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <code>HOOK_FIRST</code> will be run before <code>HOOK_MIDDLE</code>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend which are before <code>HOOK_LAST</code>. Modules that don't care
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend when they are run should use <code>HOOK_MIDDLE</code>. <em>(I spaced
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend these out so people could do stuff like <code>HOOK_FIRST-2</code>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend to get in slightly earlier, but is this wise? - Ben)</em></p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>Note that there are two more values,
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <code>HOOK_REALLY_FIRST</code> and <code>HOOK_REALLY_LAST</code>. These
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend should only be used by the hook exporter.</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend <p>The other method allows finer control. When a module knows
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend that it must be run before (or after) some other modules, it
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend can specify them by name. The second (third) argument is a
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend NULL-terminated array of strings consisting of the names of
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend modules that must be run before (after) the current module. For
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend example, suppose we want "mod_xyz.c" and "mod_abc.c" to run
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend before we do, then we'd hook as follows:</p>
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend static void register_hooks()<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend static const char * const aszPre[] = { "mod_xyz.c", "mod_abc.c", NULL };<br />
38dd0bd0209a7e29ea44e66bfc3bec8edc03e9aend ap_hook_do_something(my_something_doer, aszPre, NULL, HOOK_MIDDLE);<br />
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd <p>Note that the sort used to achieve this is stable, so
5effc8b39fae5cd169d17f342bfc265705840014rbowen ordering set by <code>HOOK_<var>ORDER</var></code> is preserved, as far
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen as is possible.</p>
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen <p class="cite"><cite>Ben Laurie</cite>, 15th August 1999</p>
<p class="apache">Maintained by the <a href="http://httpd.apache.org/docs-project/">Apache HTTP Server Documentation Project</a></p>
<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/directives.html">Directives</a> | <a href="/faq/">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p></div>