]> granicus.if.org Git - apache/blob - docs/manual/developer/hooks.xml
update transformation
[apache] / docs / manual / developer / hooks.xml
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
3 <?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
4 <!-- $LastChangedRevision$ -->
5
6 <!--
7  Licensed to the Apache Software Foundation (ASF) under one or more
8  contributor license agreements.  See the NOTICE file distributed with
9  this work for additional information regarding copyright ownership.
10  The ASF licenses this file to You under the Apache License, Version 2.0
11  (the "License"); you may not use this file except in compliance with
12  the License.  You may obtain a copy of the License at
13
14      http://www.apache.org/licenses/LICENSE-2.0
15
16  Unless required by applicable law or agreed to in writing, software
17  distributed under the License is distributed on an "AS IS" BASIS,
18  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  See the License for the specific language governing permissions and
20  limitations under the License.
21 -->
22
23 <manualpage metafile="hooks.xml.meta">
24 <parentdocument href="./">Developer Documentation</parentdocument>
25
26 <title>Hook Functions in the Apache HTTP Server 2.x</title>
27
28 <summary>
29     <note type="warning"><title>Warning</title>
30       <p>This document is still in development and may be partially out of
31       date.</p>
32     </note>
33
34     <p>In general, a hook function is one that the Apache HTTP Server 
35     will call at some point during the processing of a request. 
36     Modules can provide functions that are called, and specify when 
37     they get called in comparison to other modules.</p>
38 </summary>
39
40 <section id="create"><title>Creating a hook function</title>
41     <p>In order to create a new hook, four things need to be
42     done:</p>
43
44     <section id="create-declare"><title>Declare the hook function</title>
45       <p>Use the <code>AP_DECLARE_HOOK</code> macro, which needs to be given
46       the return type of the hook function, the name of the hook, and the
47       arguments. For example, if the hook returns an <code>int</code> and
48       takes a <code>request_rec *</code> and an <code>int</code> and is
49       called <code>do_something</code>, then declare it like this:</p>
50       <highlight language="c">
51         AP_DECLARE_HOOK(int, do_something, (request_rec *r, int n))
52       </highlight>
53
54       <p>This should go in a header which modules will include if
55       they want to use the hook.</p>
56     </section>
57
58     <section id="create-create"><title>Create the hook structure</title>
59       <p>Each source file that exports a hook has a private structure
60       which is used to record the module functions that use the hook.
61       This is declared as follows:</p>
62
63       <highlight language="c">
64 APR_HOOK_STRUCT(
65   APR_HOOK_LINK(do_something)
66   ...
67 )
68       </highlight>
69     </section>
70
71     <section id="create-implement"><title>Implement the hook caller</title>
72       <p>The source file that exports the hook has to implement a
73       function that will call the hook. There are currently three
74       possible ways to do this. In all cases, the calling function is
75       called <code>ap_run_<var>hookname</var>()</code>.</p>
76
77       <section><title>Void hooks</title>
78         <p>If the return value of a hook is <code>void</code>, then all the
79         hooks are called, and the caller is implemented like this:</p>
80
81         <highlight language="c">
82           AP_IMPLEMENT_HOOK_VOID(do_something, (request_rec *r, int n), (r, n))
83         </highlight>
84
85         <p>The second and third arguments are the dummy argument
86         declaration and the dummy arguments as they will be used when
87         calling the hook. In other words, this macro expands to
88         something like this:</p>
89
90         <highlight language="c">
91 void ap_run_do_something(request_rec *r, int n)
92 {
93     ...
94     do_something(r, n);
95 }
96         </highlight>
97       </section>
98
99       <section><title>Hooks that return a value</title>
100         <p>If the hook returns a value, then it can either be run until
101         the first hook that does something interesting, like so:</p>
102
103         <highlight language="c">
104           AP_IMPLEMENT_HOOK_RUN_FIRST(int, do_something, (request_rec *r, int n), (r, n), DECLINED)
105         </highlight>
106
107         <p>The first hook that does <em>not</em> return <code>DECLINED</code>
108         stops the loop and its return value is returned from the hook
109         caller. Note that <code>DECLINED</code> is the traditional 
110         hook return value meaning "I didn't do anything", but it can be
111         whatever suits you.</p>
112
113         <p>Alternatively, all hooks can be run until an error occurs.
114         This boils down to permitting <em>two</em> return values, one of
115         which means "I did something, and it was OK" and the other
116         meaning "I did nothing". The first function that returns a
117         value other than one of those two stops the loop, and its
118         return is the return value. Declare these like so:</p>
119
120         <highlight language="c">
121           AP_IMPLEMENT_HOOK_RUN_ALL(int, do_something, (request_rec *r, int n), (r, n), OK, DECLINED)
122         </highlight>
123
124         <p>Again, <code>OK</code> and <code>DECLINED</code> are the traditional
125         values. You can use what you want.</p>
126       </section>
127     </section>
128
129     <section id="create-call"><title>Call the hook callers</title>
130       <p>At appropriate moments in the code, call the hook caller,
131       like so:</p>
132
133       <highlight language="c">
134 int n, ret;
135 request_rec *r;
136
137 ret=ap_run_do_something(r, n);
138       </highlight>
139     </section>
140 </section>
141
142 <section id="hooking"><title>Hooking the hook</title>
143     <p>A module that wants a hook to be called needs to do two
144     things.</p>
145
146     <section id="hooking-implement"><title>Implement the hook function</title>
147       <p>Include the appropriate header, and define a static function
148       of the correct type:</p>
149
150       <highlight language="c">
151 static int my_something_doer(request_rec *r, int n)<br />
152 {
153     ...
154     return OK;
155 }
156       </highlight>
157     </section>
158
159     <section id="hooking-add"><title>Add a hook registering function</title>
160       <p>During initialisation, the server will call each modules hook
161       registering function, which is included in the module
162       structure:</p>
163
164       <highlight language="c">
165 static void my_register_hooks()
166 {
167     ap_hook_do_something(my_something_doer, NULL, NULL, APR_HOOK_MIDDLE);
168 }
169
170 mode MODULE_VAR_EXPORT my_module =
171 {
172     ...
173     my_register_hooks       /* register hooks */
174 };
175       </highlight>
176     </section>
177
178     <section id="hooking-order"><title>Controlling hook calling order</title>
179       <p>In the example above, we didn't use the three arguments in
180       the hook registration function that control calling order.
181       There are two mechanisms for doing this. The first, rather
182       crude, method, allows us to specify roughly where the hook is
183       run relative to other modules. The final argument control this.
184       There are three possible values: <code>APR_HOOK_FIRST</code>,
185       <code>APR_HOOK_MIDDLE</code> and <code>APR_HOOK_LAST</code>.</p>
186
187       <p>All modules using any particular value may be run in any
188       order relative to each other, but, of course, all modules using
189       <code>APR_HOOK_FIRST</code> will be run before <code>APR_HOOK_MIDDLE</code>
190       which are before <code>APR_HOOK_LAST</code>. Modules that don't care
191       when they are run should use <code>APR_HOOK_MIDDLE</code>. <em>These 
192       values are spaced out, so that positions like <code>APR_HOOK_FIRST-2</code>
193       are possible to hook slightly earlier than other functions.</em></p>
194
195       <p>Note that there are two more values,
196       <code>APR_HOOK_REALLY_FIRST</code> and <code>APR_HOOK_REALLY_LAST</code>. These
197       should only be used by the hook exporter.</p>
198
199       <p>The other method allows finer control. When a module knows
200       that it must be run before (or after) some other modules, it
201       can specify them by name. The second (third) argument is a
202       NULL-terminated array of strings consisting of the names of
203       modules that must be run before (after) the current module. For
204       example, suppose we want "mod_xyz.c" and "mod_abc.c" to run
205       before we do, then we'd hook as follows:</p>
206
207       <highlight language="c">
208 static void register_hooks()
209 {
210     static const char * const aszPre[] = { "mod_xyz.c", "mod_abc.c", NULL };
211
212     ap_hook_do_something(my_something_doer, aszPre, NULL, APR_HOOK_MIDDLE);
213 }
214       </highlight>
215
216       <p>Note that the sort used to achieve this is stable, so
217       ordering set by <code>APR_HOOK_<var>ORDER</var></code> is preserved, as far
218       as is possible.</p>
219
220     </section>
221 </section>
222 </manualpage>
223