1<?xml version="1.0" encoding="ISO-8859-1"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><!--
4        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5              This file is generated from xml source: DO NOT EDIT
6        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7      -->
8<title>Developing modules for the Apache HTTP Server 2.4 - Apache HTTP Server</title>
9<link href="/style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
10<link href="/style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
11<link href="/style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="/style/css/prettify.css" />
12<script src="/style/scripts/prettify.min.js" type="text/javascript">
13</script>
14
15<link href="/images/favicon.ico" rel="shortcut icon" /></head>
16<body id="manual-page"><div id="page-header">
17<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p>
18<p class="apache">Apache HTTP Server Version 2.4</p>
19<img alt="" src="/images/feather.gif" /></div>
20<div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="/images/left.gif" /></a></div>
21<div id="path">
22<a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.4</a> &gt; <a href="./">Developer</a></div><div id="page-content"><div id="preamble"><h1>Developing modules for the Apache HTTP Server 2.4</h1>
23<div class="toplang">
24<p><span>Available Languages: </span><a href="/en/developer/modguide.html" title="English">&nbsp;en&nbsp;</a></p>
25</div>
26
27<p>This document explains how you can develop modules for the Apache HTTP 
28Server 2.4</p>
29</div>
30<div id="quickview"><ul id="toc"><li><img alt="" src="/images/down.gif" /> <a href="#introduction">Introduction</a></li>
31<li><img alt="" src="/images/down.gif" /> <a href="#basics">Defining a module</a></li>
32<li><img alt="" src="/images/down.gif" /> <a href="#hooking">Getting started: Hooking into the server</a></li>
33<li><img alt="" src="/images/down.gif" /> <a href="#handling">Building a handler</a></li>
34<li><img alt="" src="/images/down.gif" /> <a href="#configuration">Adding configuration options</a></li>
35<li><img alt="" src="/images/down.gif" /> <a href="#context">Context aware configurations</a></li>
36<li><img alt="" src="/images/down.gif" /> <a href="#summary">Summing up</a></li>
37<li><img alt="" src="/images/down.gif" /> <a href="#snippets">Some useful snippets of code</a></li>
38</ul><h3>See also</h3><ul class="seealso"><li><a href="request.html">Request Processing in Apache 2.4</a></li><li><a href="hooks.html">Apache 2.x Hook Functions</a></li></ul><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
39<div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
40<div class="section">
41<h2><a name="introduction" id="introduction">Introduction</a></h2>
42<h3><a name="what" id="what">What we will be discussing in this document</a></h3>
43<p>
44This document will discuss how you can create modules for the Apache 
45HTTP Server 2.4, by exploring an example module called 
46<code>mod_example</code>. In the first part of this document, the purpose 
47of this module will be to calculate and print out various digest values for 
48existing files on your web server, whenever we access the URL <code>
49http://hostname/filename.sum</code>. For instance, if we want to know the 
50MD5 digest value of the file located at <code>
51http://www.example.com/index.html</code>, we would visit <code>
52http://www.example.com/index.html.sum</code>. 
53</p>
54
55<p>
56In the second part of this document, which deals with configuration 
57directive and context awareness, we will be looking at a module that simply 
58writes out its own configuration to the client.
59</p>
60
61
62<h3><a name="prerequisites" id="prerequisites">Prerequisites</a></h3>
63<p>
64First and foremost, you are expected to have a basic knowledge of how the C 
65programming language works. In most cases, we will try to be as pedagogical 
66as possible and link to documents describing the functions used in the 
67examples, but there are also many cases where it is necessary to either 
68just assume that "it works" or do some digging yourself into what the hows 
69and whys of various function calls. 
70</p>
71<p>
72Lastly, you will need to have a basic understanding of how modules are 
73loaded and configured in the Apache HTTP Server, as well as how to get the headers for 
74Apache if you do not have them already, as these are needed for compiling 
75new modules.
76</p>
77
78<h3><a name="compiling" id="compiling">Compiling your module</a></h3>
79<p>
80To compile the source code we are building in this document, we will be 
81using <a href="/programs/apxs.html">APXS</a>. Assuming your source file 
82is called mod_example.c, compiling, installing and activating the module is 
83as simple as: 
84</p>
85<div class="example"><pre>apxs -i -a -c mod_example.c</pre></div>
86
87
88</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
89<div class="section">
90<h2><a name="basics" id="basics">Defining a module</a></h2>
91<p>
92<img src="/images/build_a_mod_3.png" alt="Module name tags" /><br />
93Every module starts with the same declaration, or name tag if you will, 
94that defines a module as <em>a separate entity within Apache</em>:</p>
95
96
97
98<pre class="prettyprint lang-c">module AP_MODULE_DECLARE_DATA   example_module =
99{ 
100    STANDARD20_MODULE_STUFF,
101    create_dir_conf, /* Per-directory configuration handler */
102    merge_dir_conf,  /* Merge handler for per-directory configurations */
103    create_svr_conf, /* Per-server configuration handler */
104    merge_svr_conf,  /* Merge handler for per-server configurations */
105    directives,      /* Any directives we may have for httpd */
106    register_hooks   /* Our hook registering function */
107};</pre>
108
109
110
111<p>
112This bit of code lets the server know that we have now registered a new module 
113in the system, and that its name is <code>example_module</code>. The name 
114of the module is used primarily for two things:<br />
115</p>
116<ul>
117<li>Letting the server know how to load the module using the LoadModule</li>
118<li>Setting up a namespace for the module to use in configurations</li>
119</ul>
120<p>
121For now, we're only concerned with the first purpose of the module name, 
122which comes into play when we need to load the module:
123</p>
124<pre class="prettyprint lang-config">LoadModule example_module modules/mod_example.so</pre>
125
126<p>
127In essence, this tells the server to open up <code>mod_example.so</code> and look for a module 
128called <code>example_module</code>.
129</p>
130<p>
131Within this name tag of ours is also a bunch of references to how we would 
132like to handle things: Which directives do we respond to in a configuration 
133file or .htaccess, how do we operate within specific contexts, and what 
134handlers are we interested in registering with the Apache HTTP service. We'll 
135return to all these elements later in this document.
136</p>
137</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
138<div class="section">
139<h2><a name="hooking" id="hooking">Getting started: Hooking into the server</a></h2>
140<h3><a name="hook_intro" id="hook_intro">An introduction to hooks</a></h3>
141<p>
142When handling requests in Apache HTTP Server 2.4, the first thing you will need to do is 
143create a hook into the request handling process. A hook is essentially a 
144message telling the server that you are willing to either serve or at least 
145take a glance at certain requests given by clients. All handlers, whether 
146it's mod_rewrite, mod_authn_*, mod_proxy and so on, are hooked into 
147specific parts of the request process. As you are probably aware, modules 
148serve different purposes; Some are authentication/authorization handlers, 
149others are file or script handlers while some third modules rewrite URIs or 
150proxies content. Furthermore, in the end, it is up to the user of the server 
151how and when each module will come into place. Thus, the server itself does not 
152presume to know which module is responsible for handling a specific 
153request, and will ask each module whether they have an interest in a given 
154request or not. It is then up to each module to either gently decline 
155serving a request, accept serving it or flat out deny the request from 
156being served, as authentication/authorization modules do: <br />
157<img src="/images/build_a_mod_2.png" alt="Hook handling in httpd" /><br />
158To make it a bit easier for handlers such as our mod_example to know 
159whether the client is requesting content we should handle or not, the server 
160has directives for hinting to modules whether their assistance is needed or 
161not. Two of these are <code class="directive"><a href="/mod/mod_mime.html#addhandler">AddHandler</a></code> 
162and <code class="directive"><a href="/mod/core.html#sethandler">SetHandler</a></code>. Let's take a look at 
163an example using <code class="directive"><a href="/mod/mod_mime.html#addhandler">AddHandler</a></code>. In 
164our example case, we want every request ending with .sum to be served by 
165<code>mod_example</code>, so we'll add a configuration directive that tells 
166the server to do just that:
167</p>
168<pre class="prettyprint lang-config">AddHandler example-handler .sum</pre>
169
170<p>
171What this tells the server is the following: <em>Whenever we receive a request 
172for a URI ending in .sum, we are to let all modules know that we are 
173looking for whoever goes by the name of "example-handler" </em>. 
174Thus, when a request is being served that ends in .sum, the server will let all 
175modules know, that this request should be served by "example-handler
176". As you will see later, when we start building mod_example, we will 
177check for this handler tag relayed by <code>AddHandler</code> and reply to 
178the server based on the value of this tag.
179</p>
180
181<h3><a name="hook_declaration" id="hook_declaration">Hooking into httpd</a></h3>
182<p>
183To begin with, we only want to create a simple handler, that replies to the 
184client browser when a specific URL is requested, so we won't bother setting 
185up configuration handlers and directives just yet. Our initial module 
186definition will look like this:</p>
187
188
189
190<pre class="prettyprint lang-c">module AP_MODULE_DECLARE_DATA   example_module =
191{
192    STANDARD20_MODULE_STUFF,
193    NULL,
194    NULL,
195    NULL,
196    NULL,
197    NULL,
198    register_hooks   /* Our hook registering function */
199};</pre>
200
201
202
203
204<p>This lets the server know that we are not interesting in anything fancy, we 
205just want to hook onto the requests and possibly handle some of them. </p> 
206
207<p> The reference in our example declaration, <code>register_hooks</code> 
208is the name of a function we will create to manage how we hook onto the 
209request process. In this example module, the function has just one purpose; 
210To create a simple hook that gets called after all the rewrites, access 
211control etc has been handled. Thus, we will let the server know, that we want 
212to hook into its process as one of the last modules: 
213</p>
214
215
216<pre class="prettyprint lang-c">static void register_hooks(apr_pool_t *pool)
217{
218    /* Create a hook in the request handler, so we get called when a request arrives */
219    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
220}</pre>
221
222
223
224<p>
225The <code>example_handler</code> reference is the function that will handle 
226the request. We will discuss how to create a handler in the next chapter.
227</p>
228
229<h3><a name="hook_others" id="hook_others">Other useful hooks</a></h3>
230<p>
231Hooking into the request handling phase is but one of many hooks that you 
232can create. Some other ways of hooking are:
233</p>
234<ul>
235<li><code>ap_hook_child_init</code>: Place a hook that executes when a child process is spawned (commonly used for initializing modules after the server has forked)</li>
236<li><code>ap_hook_pre_config</code>: Place a hook that executes before any configuration data has been read (very early hook)</li>
237<li><code>ap_hook_post_config</code>: Place a hook that executes after configuration has been parsed, but before the server has forked</li>
238<li><code>ap_hook_translate_name</code>: Place a hook that executes when a URI needs to be translated into a filename on the server (think <code>mod_rewrite</code>)</li>
239<li><code>ap_hook_quick_handler</code>: Similar to <code>ap_hook_handler</code>, except it is run before any other request hooks (translation, auth, fixups etc)</li>
240<li><code>ap_hook_log_transaction</code>: Place a hook that executes when the server is about to add a log entry of the current request</li>
241</ul>
242
243
244</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
245<div class="section">
246<h2><a name="handling" id="handling">Building a handler</a></h2>
247<p>
248A handler is essentially a function that receives a callback when a request 
249to the server is made. It is passed a record of the current request (how it was 
250made, which headers and requests were passed along, who's giving the 
251request and so on), and is put in charge of either telling the server that it's 
252not interested in the request or handle the request with the tools provided.
253</p>
254<h3><a name="simple_handler" id="simple_handler">A simple "Hello, world!" 
255handler</a></h3> 
256<p>Let's start off by making a very simple request handler 
257that does the following:
258</p>
259<ol>
260<li>Check that this is a request that should be served by "example-handler"</li>
261<li>Set the content type of our output to <code>text/html</code></li>
262<li>Write "Hello, world!" back to the client browser</li>
263<li>Let the server know that we took care of this request and everything went fine</li>
264</ol>
265<p>
266In C code, our example handler will now look like this:
267</p>
268
269
270<pre class="prettyprint lang-c">static int example_handler(request_rec *r)
271{
272    /* First off, we need to check if this is a call for the "example-handler" handler.
273     * If it is, we accept it and do our things, if not, we simply return DECLINED,
274     * and the server will try somewhere else.
275     */
276    if (!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return (DECLINED);
277    
278    /* Now that we are handling this request, we'll write out "Hello, world!" to the client.
279     * To do so, we must first set the appropriate content type, followed by our output.
280     */
281    ap_set_content_type(r, "text/html");
282    ap_rprintf(r, "Hello, world!");
283    
284    /* Lastly, we must tell the server that we took care of this request and everything went fine.
285     * We do so by simply returning the value OK to the server.
286     */
287    return OK;
288}</pre>
289
290
291
292<p>
293Now, we put all we have learned together and end up with a program that 
294looks like 
295<a href="http://people.apache.org/~humbedooh/mods/examples/mod_example_1.c">mod_example_1.c</a>
296. The functions used in this example will be explained later in the section 
297<a href="#functions">"Some useful functions you should know"</a>. 
298</p>
299 
300<h3><a name="request_rec" id="request_rec">The request_rec structure</a></h3> 
301<p>The most essential part of any request is the <em>request record
302</em>. In a call to a handler function, this is represented by the <code>
303request_rec* </code> structure passed along with every call that is made. 
304This struct, typically just referred to as <code>r</code> in modules, 
305contains all the information you need for your module to fully process any 
306HTTP request and respond accordingly.</p> <p>Some key elements of the <code>
307request_rec </code> structure are:
308</p>
309<ul>
310<li><code>r-&gt;handler (char*):</code> Contains the name of the handler the server is currently asking to do the handling of this request</li>
311<li><code>r-&gt;method (char*):</code> Contains the HTTP method being used, f.x. GET or POST</li>
312<li><code>r-&gt;filename (char*):</code> Contains the translated filename the client is requesting</li>
313<li><code>r-&gt;args (char*):</code> Contains the query string of the request, if any</li>
314<li><code>r-&gt;headers_in (apr_table_t*):</code> Contains all the headers sent by the client</li>
315<li><code>r-&gt;connection (conn_rec*):</code> A record containing information about the current connection</li>
316<li><code>r-&gt;user (char*):</code> If the URI requires authentication, this is set to the username provided</li>
317<li><code>r-&gt;useragent_ip (char*):</code> The IP address of the client connecting to us</li>
318<li><code>r-&gt;pool (apr_pool_t*)</code>: The memory pool of this request. We'll discuss this in the 
319"<a href="#memory">Memory management</a>" chapter.</li>
320</ul>
321<p>
322A complete list of all the values contained within the <code>request_rec</code> structure can be found in 
323the <a href="http://svn.apache.org/repos/asf/httpd/httpd/trunk/include/httpd.h"><code>httpd.h</code></a> header 
324file or at <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/structrequest__rec.html">http://ci.apache.org/projects/httpd/trunk/doxygen/structrequest__rec.html</a>.
325</p>
326
327
328<p>
329Let's try out some of these variables in another example handler:<br />
330</p>
331
332
333<pre class="prettyprint lang-c">static int example_handler(request_rec *r)
334{
335    /* Set the appropriate content type */
336    ap_set_content_type(r, "text/html");
337
338    /* Print out the IP address of the client connecting to us: */
339    ap_rprintf(r, "&lt;h2&gt;Hello, %s!&lt;/h2&gt;", r-&gt;useragent_ip);
340    
341    /* If we were reached through a GET or a POST request, be happy, else sad. */
342    if ( !strcmp(r-&gt;method, "POST") || !strcmp(r-&gt;method, "GET") ) {
343        ap_rputs("You used a GET or a POST method, that makes us happy!&lt;br/&gt;", r);
344    }
345    else {
346        ap_rputs("You did not use POST or GET, that makes us sad :(&lt;br/&gt;", r);
347    }
348
349    /* Lastly, if there was a query string, let's print that too! */
350    if (r-&gt;args) {
351        ap_rprintf(r, "Your query string was: %s", r-&gt;args);
352    }
353    return OK;
354}</pre>
355
356
357
358
359
360<h3><a name="return_value" id="return_value">Return values</a></h3>
361<p>
362Apache relies on return values from handlers to signify whether a request 
363was handled or not, and if so, whether the request went well or not. If a 
364module is not interested in handling a specific request, it should always 
365return the value <code>DECLINED</code>. If it is handling a request, it 
366should either return the generic value <code>OK</code>, or a specific HTTP 
367status code, for example:
368</p>
369
370
371<pre class="prettyprint lang-c">static int example_handler(request_rec *r)
372{
373    /* Return 404: Not found */
374    return HTTP_NOT_FOUND;
375}</pre>
376
377
378
379<p>
380Returning <code>OK</code> or a HTTP status code does not necessarily mean 
381that the request will end. The server may still have other handlers that are 
382interested in this request, for instance the logging modules which, upon a 
383successful request, will write down a summary of what was requested and how 
384it went. To do a full stop and prevent any further processing after your 
385module is done, you can return the value <code>DONE</code> to let the server 
386know that it should cease all activity on this request and carry on with 
387the next, without informing other handlers.
388<br />
389<strong>General response codes:</strong>
390</p>
391<ul>
392<li><code>DECLINED</code>: We are not handling this request</li>
393<li><code>OK</code>: We handled this request and it went well</li>
394<li><code>DONE</code>: We handled this request and the server should just close this thread without further processing</li>
395</ul>
396<p>
397<strong>HTTP specific return codes (excerpt):</strong>
398</p>
399<ul>
400<li><code>HTTP_OK (200)</code>: Request was okay</li>
401<li><code>HTTP_MOVED_PERMANENTLY (301)</code>: The resource has moved to a new URL</li>
402<li><code>HTTP_UNAUTHORIZED (401)</code>: Client is not authorized to visit this page</li>
403<li><code>HTTP_FORBIDDEN (403)</code>: Permission denied</li>
404<li><code>HTTP_NOT_FOUND (404)</code>: File not found</li>
405<li><code>HTTP_INTERNAL_SERVER_ERROR (500)</code>: Internal server error (self explanatory)</li>
406</ul>
407
408
409<h3><a name="functions" id="functions">Some useful functions you should know</a></h3>
410
411<ul>
412<li>
413    <code>ap_rputs(const char *string, request_rec *r)</code>: <br />
414    Sends a string of text to the client. This is a shorthand version of <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#gac827cd0537d2b6213a7c06d7c26cc36e">
415    ap_rwrite</a>.
416    
417
418
419<pre class="prettyprint lang-c">ap_rputs("Hello, world!", r);</pre>
420
421
422
423
424</li>
425<li>
426    <code>
427    <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga5e91eb6ca777c9a427b2e82bf1eeb81d">ap_rprintf</a></code>: <br />
428    This function works just like <code>printf</code>, except it sends the result to the client. 
429    
430
431
432<pre class="prettyprint lang-c">ap_rprintf(r, "Hello, %s!", r-&gt;useragent_ip);</pre>
433
434
435
436</li>
437<li>
438    <code>
439    <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#gaa2f8412c400197338ec509f4a45e4579">ap_set_content_type</a>(request_rec *r, const char *type)</code>: <br />
440    Sets the content type of the output you are sending.
441    
442
443
444<pre class="prettyprint lang-c">ap_set_content_type(r, "text/plain"); /* force a raw text output */</pre>
445
446
447
448</li>
449
450
451</ul>
452
453
454<h3><a name="memory" id="memory">Memory management</a></h3>
455<p>
456Managing your resources in Apache HTTP Server 2.4 is quite easy, thanks to the memory pool 
457system. In essence, each server, connection and request have their own 
458memory pool that gets cleaned up when its scope ends, e.g. when a request 
459is done or when a server process shuts down. All your module needs to do is 
460latch onto this memory pool, and you won't have to worry about having to 
461clean up after yourself - pretty neat, huh?
462</p>
463
464<p>
465In our module, we will primarily be allocating memory for each request, so 
466it's appropriate to use the <code>r-&gt;pool</code> 
467reference when creating new objects. A few of the functions for allocating 
468memory within a pool are:
469</p>
470<ul>
471<li><code>void* <a href="http://apr.apache.org/docs/apr/1.4/group__apr__pools.html#ga85f1e193c31d109affda72f9a92c6915">apr_palloc</a>(
472apr_pool_t *p, apr_size_t size)</code>: Allocates <code>size</code> number of bytes in the pool for you</li>
473<li><code>void* <a href="http://apr.apache.org/docs/apr/1.4/group__apr__pools.html#gaf61c098ad258069d64cdf8c0a9369f9e">apr_pcalloc</a>(
474apr_pool_t *p, apr_size_t size)</code>: Allocates <code>size</code> number of bytes in the pool for you and sets all bytes to 0</li>
475<li><code>char* <a href="http://apr.apache.org/docs/apr/1.4/group__apr__strings.html#gabc79e99ff19abbd7cfd18308c5f85d47">apr_pstrdup</a>(
476apr_pool_t *p, const char *s)</code>: Creates a duplicate of the string <code>s</code>. This is useful for copying constant values so you can edit them</li>
477<li><code>char* <a href="http://apr.apache.org/docs/apr/1.4/group__apr__strings.html#ga3eca76b8d293c5c3f8021e45eda813d8">apr_psprintf</a>(
478apr_pool_t *p, const char *fmt, ...)</code>: Similar to <code>sprintf</code>, except the server supplies you with an appropriately allocated target variable</li>
479</ul>
480
481<p>Let's put these functions into an example handler:</p>
482
483
484
485<pre class="prettyprint lang-c">static int example_handler(request_rec *r)
486{
487    const char* original = "You can't edit this!";
488    char* copy;
489    int* integers;
490    
491    /* Allocate space for 10 integer values and set them all to zero. */
492    integers = apr_pcalloc(r-&gt;pool, sizeof(int)*10); 
493    
494    /* Create a copy of the 'original' variable that we can edit. */
495    copy = apr_pstrdup(r-&gt;pool, original);
496    return OK;
497}</pre>
498
499
500
501<p>
502This is all well and good for our module, which won't need any 
503pre-initialized variables or structures. However, if we wanted to 
504initialize something early on, before the requests come rolling in, we 
505could simply add a call to a function in our <code>register_hooks</code> 
506function to sort it out:
507</p>
508
509
510<pre class="prettyprint lang-c">static void register_hooks(apr_pool_t *pool)
511{
512    /* Call a function that initializes some stuff */
513    example_init_function(pool);
514    /* Create a hook in the request handler, so we get called when a request arrives */
515    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
516}</pre>
517
518
519
520<p>
521In this pre-request initialization function we would not be using the 
522same pool as we did when allocating resources for request-based functions. 
523Instead, we would use the pool given to us by the server for allocating memory 
524on a per-process based level.
525</p>
526
527
528<h3><a name="parsing" id="parsing">Parsing request data</a></h3>
529<p>
530In our example module, we would like to add a feature, that checks which 
531type of digest, MD5 or SHA1 the client would like to see. This could be 
532solved by adding a query string to the request. A query string is typically 
533comprised of several keys and values put together in a string, for instance 
534<code>valueA=yes&amp;valueB=no&amp;valueC=maybe</code>. It is up to the 
535module itself to parse these and get the data it requires. In our example, 
536we'll be looking for a key called <code>digest</code>, and if set to <code>
537md5</code>, we'll produce an MD5 digest, otherwise we'll produce a SHA1 
538digest.
539</p>
540<p>
541Since the introduction of Apache HTTP Server 2.4, parsing request data from GET and 
542POST requests have never been easier. All we require to parse both GET and 
543POST data is four simple lines:
544</p> 
545
546
547
548<pre class="prettyprint lang-c">
549<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__apr__tables.html#gad7ea82d6608a4a633fc3775694ab71e4">apr_table_t</a> *GET; <em>
550</em><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/structapr__array__header__t.html">apr_array_header_t</a>*POST; 
551<em>
552</em>
553<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__SCRIPT.html#gaed25877b529623a4d8f99f819ba1b7bd">
554ap_args_to_table</a>(r, &amp;GET); <em>
555</em><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__DAEMON.html#ga9d426b6382b49754d4f87c55f65af202">
556ap_parse_form_data</a>(r, NULL, &amp;POST, -1, 8192);</pre>
557
558
559
560<p>
561In our specific example module, we're looking for the <code>digest</code> 
562value from the query string, which now resides inside a table called <code>
563GET</code>. To extract this value, we need only perform a simple operation:
564</p>
565
566
567
568<pre class="prettyprint lang-c">/* Get the "digest" key from the query string, if any. */
569const char *digestType = apr_table_get(GET, "digest");
570
571/* If no key was returned, we will set a default value instead. */
572if (!digestType) digestType = "sha1";</pre>
573
574
575
576<p>
577The structures used for the POST and GET data are not exactly the same, so 
578if we were to fetch a value from POST data instead of the query string, we 
579would have to resort to a few more lines, as outlined in <a href="#get_post">this example</a> in the last chapter of this document.
580</p>
581
582
583<h3><a name="advanced_handler" id="advanced_handler">Making an advanced handler</a></h3>
584<p>
585Now that we have learned how to parse form data and manage our resources, 
586we can move on to creating an advanced version of our module, that spits 
587out the MD5 or SHA1 digest of files:
588</p>
589
590
591
592<pre class="prettyprint lang-c">static int example_handler(request_rec *r)
593{
594    int rc, exists;
595    apr_finfo_t finfo;
596    apr_file_t *file;
597    char *filename;
598    char buffer[256];
599    apr_size_t readBytes;
600    int n;
601    apr_table_t *GET;
602    apr_array_header_t *POST;
603    const char *digestType;
604    
605    
606    /* Check that the "example-handler" handler is being called. */
607    if (!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return (DECLINED);
608    
609    /* Figure out which file is being requested by removing the .sum from it */
610    filename = apr_pstrdup(r-&gt;pool, r-&gt;filename);
611    filename[strlen(filename)-4] = 0; /* Cut off the last 4 characters. */
612    
613    /* Figure out if the file we request a sum on exists and isn't a directory */
614    rc = apr_stat(&amp;finfo, filename, APR_FINFO_MIN, r-&gt;pool);
615    if (rc == APR_SUCCESS) {
616        exists =
617        (
618            (finfo.filetype != APR_NOFILE)
619        &amp;&amp;  !(finfo.filetype &amp; APR_DIR)
620        );
621        if (!exists) return HTTP_NOT_FOUND; /* Return a 404 if not found. */
622    }
623    /* If apr_stat failed, we're probably not allowed to check this file. */
624    else return HTTP_FORBIDDEN;
625    
626    /* Parse the GET and, optionally, the POST data sent to us */
627    
628    ap_args_to_table(r, &amp;GET);
629    ap_parse_form_data(r, NULL, &amp;POST, -1, 8192);
630    
631    /* Set the appropriate content type */
632    ap_set_content_type(r, "text/html");
633    
634    /* Print a title and some general information */
635    ap_rprintf(r, "&lt;h2&gt;Information on %s:&lt;/h2&gt;", filename);
636    ap_rprintf(r, "&lt;b&gt;Size:&lt;/b&gt; %u bytes&lt;br/&gt;", finfo.size);
637    
638    /* Get the digest type the client wants to see */
639    digestType = apr_table_get(GET, "digest");
640    if (!digestType) digestType = "MD5";
641    
642    
643    rc = apr_file_open(&amp;file, filename, APR_READ, APR_OS_DEFAULT, r-&gt;pool);
644    if (rc == APR_SUCCESS) {
645        
646        /* Are we trying to calculate the MD5 or the SHA1 digest? */
647        if (!strcasecmp(digestType, "md5")) {
648            /* Calculate the MD5 sum of the file */
649            union {
650                char      chr[16];
651                uint32_t  num[4];
652            } digest;
653            apr_md5_ctx_t md5;
654            apr_md5_init(&amp;md5);
655            readBytes = 256;
656            while ( apr_file_read(file, buffer, &amp;readBytes) == APR_SUCCESS ) {
657                apr_md5_update(&amp;md5, buffer, readBytes);
658            }
659            apr_md5_final(digest.chr, &amp;md5);
660            
661            /* Print out the MD5 digest */
662            ap_rputs("&lt;b&gt;MD5: &lt;/b&gt;&lt;code&gt;", r);
663            for (n = 0; n &lt; APR_MD5_DIGESTSIZE/4; n++) {
664                ap_rprintf(r, "%08x", digest.num[n]);
665            }
666            ap_rputs("&lt;/code&gt;", r);
667            /* Print a link to the SHA1 version */
668            ap_rputs("&lt;br/&gt;&lt;a href='?digest=sha1'&gt;View the SHA1 hash instead&lt;/a&gt;", r);
669        }
670        else {
671            /* Calculate the SHA1 sum of the file */
672            union {
673                char      chr[20];
674                uint32_t  num[5];
675            } digest;
676            apr_sha1_ctx_t sha1;
677            apr_sha1_init(&amp;sha1);
678            readBytes = 256;
679            while ( apr_file_read(file, buffer, &amp;readBytes) == APR_SUCCESS ) {
680                apr_sha1_update(&amp;sha1, buffer, readBytes);
681            }
682            apr_sha1_final(digest.chr, &amp;sha1);
683            
684            /* Print out the SHA1 digest */
685            ap_rputs("&lt;b&gt;SHA1: &lt;/b&gt;&lt;code&gt;", r);
686            for (n = 0; n &lt; APR_SHA1_DIGESTSIZE/4; n++) {
687                ap_rprintf(r, "%08x", digest.num[n]);
688            }
689            ap_rputs("&lt;/code&gt;", r);
690            
691            /* Print a link to the MD5 version */
692            ap_rputs("&lt;br/&gt;&lt;a href='?digest=md5'&gt;View the MD5 hash instead&lt;/a&gt;", r);
693        }
694        apr_file_close(file);
695        
696    }    
697    /* Let the server know that we responded to this request. */
698    return OK;
699}</pre>
700
701
702
703<p>
704This version in its entirety can be found here: 
705<a href="http://people.apache.org/~humbedooh/mods/examples/mod_example_2.c">mod_example_2.c</a>.
706</p>
707
708
709</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
710<div class="section">
711<h2><a name="configuration" id="configuration">Adding configuration options</a></h2>
712<p>
713In this next segment of this document, we will turn our eyes away from the 
714digest module and create a new example module, whose only function is to 
715write out its own configuration. The purpose of this is to examine how 
716the server works with configuration, and what happens when you start writing 
717advanced configurations 
718for your modules.
719</p>
720<h3><a name="config_intro" id="config_intro">An introduction to configuration 
721directives</a></h3>
722<p>
723If you are reading this, then you probably already know 
724what a configuration directive is. Simply put, a directive is a way of 
725telling an individual module (or a set of modules) how to behave, such as 
726these directives control how <code>mod_rewrite</code> works:
727</p>
728<pre class="prettyprint lang-config">RewriteEngine On
729RewriteCond %{REQUEST_URI} ^/foo/bar
730RewriteRule ^/foo/bar/(.*)$ /foobar?page=$1</pre>
731
732<p>
733Each of these configuration directives are handled by a separate function, 
734that parses the parameters given and sets up a configuration accordingly.
735</p>
736
737<h3><a name="config_simple" id="config_simple">Making an example configuration</a></h3>
738<p>To begin with, we'll create a basic configuration in C-space:</p>
739
740
741
742<pre class="prettyprint lang-c">typedef struct {
743    int         enabled;      /* Enable or disable our module */
744    const char *path;         /* Some path to...something */
745    int         typeOfAction; /* 1 means action A, 2 means action B and so on */
746} example_config;</pre>
747
748
749
750<p>
751Now, let's put this into perspective by creating a very small module that 
752just prints out a hard-coded configuration. You'll notice that we use the 
753<code>register_hooks</code> function for initializing the configuration 
754values to their defaults:
755</p>
756
757
758<pre class="prettyprint lang-c">typedef struct {
759    int         enabled;      /* Enable or disable our module */
760    const char *path;         /* Some path to...something */
761    int         typeOfAction; /* 1 means action A, 2 means action B and so on */
762} example_config;
763
764static example_config config;
765
766static int example_handler(request_rec *r)
767{
768    if (!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return(DECLINED);
769    ap_set_content_type(r, "text/plain");
770    ap_rprintf(r, "Enabled: %u\n", config.enabled);
771    ap_rprintf(r, "Path: %s\n", config.path);
772    ap_rprintf(r, "TypeOfAction: %x\n", config.typeOfAction);
773    return OK;
774}
775
776static void register_hooks(apr_pool_t *pool) 
777{
778    config.enabled = 1;
779    config.path = "/foo/bar";
780    config.typeOfAction = 0x00;
781    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
782}
783
784/* Define our module as an entity and assign a function for registering hooks  */
785
786module AP_MODULE_DECLARE_DATA   example_module =
787{
788    STANDARD20_MODULE_STUFF,
789    NULL,            /* Per-directory configuration handler */
790    NULL,            /* Merge handler for per-directory configurations */
791    NULL,            /* Per-server configuration handler */
792    NULL,            /* Merge handler for per-server configurations */
793    NULL,            /* Any directives we may have for httpd */
794    register_hooks   /* Our hook registering function */
795};</pre>
796
797
798
799<p>
800So far so good. To access our new handler, we could add the following to 
801our configuration:
802</p>
803<pre class="prettyprint lang-config">&lt;Location /example&gt;
804    SetHandler example-handler
805&lt;/Location&gt;</pre>
806
807<p>
808When we visit, we'll see our current configuration being spit out by our 
809module. 
810</p>
811
812
813<h3><a name="register_directive" id="register_directive">Registering directives with the server</a></h3>
814<p>
815What if we want to change our configuration, not by hard-coding new values 
816into the module, but by using either the httpd.conf file or possibly a 
817.htaccess file? It's time to let the server know that we want this to be 
818possible. To do so, we must first change our <em>name tag</em> to include a 
819reference to the configuration directives we want to register with the server:
820</p>
821
822
823<pre class="prettyprint lang-c">module AP_MODULE_DECLARE_DATA   example_module =
824{
825    STANDARD20_MODULE_STUFF,
826    NULL,               /* Per-directory configuration handler */
827    NULL,               /* Merge handler for per-directory configurations */
828    NULL,               /* Per-server configuration handler */
829    NULL,               /* Merge handler for per-server configurations */
830    example_directives, /* Any directives we may have for httpd */
831    register_hooks      /* Our hook registering function */
832};</pre>
833
834
835
836<p>
837This will tell the server that we are now accepting directives from the 
838configuration files, and that the structure called <code>example_directives
839</code> holds information on what our directives are and how they work. 
840Since we have three different variables in our module configuration, we 
841will add a structure with three directives and a NULL at the end:
842</p>
843
844
845<pre class="prettyprint lang-c">static const command_rec        example_directives[] =
846{
847    AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"),
848    AP_INIT_TAKE1("examplePath", example_set_path, NULL, RSRC_CONF, "The path to whatever"),
849    AP_INIT_TAKE2("exampleAction", example_set_action, NULL, RSRC_CONF, "Special action value!"),
850    { NULL }
851};</pre>
852
853
854
855<p>
856<img src="/images/build_a_mod_4.png" alt="Directives structure" /><br />
857As you can see, each directive needs at least 5 parameters set:
858</p>
859<ol>
860<li><code><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__CONFIG.html#ga07c7d22ae17805e61204463326cf9c34">AP_INIT_TAKE1</a></code>: This is a macro that tells the server that this directive takes one and only one argument. 
861If we required two arguments, we could use the macro <code><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__CONFIG.html#gafaec43534fcf200f37d9fecbf9247c21">AP_INIT_TAKE2</a></code> and so on (refer to httpd_conf.h 
862for more macros).</li>
863<li><code>exampleEnabled</code>: This is the name of our directive. More precisely, it is what the user must put in his/her 
864configuration in order to invoke a configuration change in our module.</li>
865<li><code>example_set_enabled</code>: This is a reference to a C function that parses the directive and sets the configuration 
866accordingly. We will discuss how to make this in the following paragraph.</li>
867<li><code>RSRC_CONF</code>: This tells the server where the directive is permitted. We'll go into details on this value in the 
868later chapters, but for now, <code>RSRC_CONF</code> means that the server will only accept these directives in a server context.</li>
869<li><code>"Enable or disable...."</code>: This is simply a brief description of what the directive does.</li>
870</ol>
871<p>
872(<em>The "missing" parameter in our definition, which is usually set to 
873<code>NULL</code>, is an optional function that can be run after the 
874initial function to parse the arguments have been run. This is usually 
875omitted, as the function for verifying arguments might as well be used to 
876set them.</em>)
877</p>
878
879<h3><a name="directive_handler" id="directive_handler">The directive handler function</a></h3>
880<p>
881Now that we have told the server to expect some directives for our module, it's 
882time to make a few functions for handling these. What the server reads in the 
883configuration file(s) is text, and so naturally, what it passes along to 
884our directive handler is one or more strings, that we ourselves need to 
885recognize and act upon. You'll notice, that since we set our <code>
886exampleAction</code> directive to accept two arguments, its C function also 
887has an additional parameter defined:</p> 
888
889
890<pre class="prettyprint lang-c">/* Handler for the "exampleEnabled" directive */
891const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg)
892{
893    if(!strcasecmp(arg, "on")) config.enabled = 1;
894    else config.enabled = 0;
895    return NULL;
896}
897
898/* Handler for the "examplePath" directive */
899const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg)
900{
901    config.path = arg;
902    return NULL;
903}
904
905/* Handler for the "exampleAction" directive */
906/* Let's pretend this one takes one argument (file or db), and a second (deny or allow), */
907/* and we store it in a bit-wise manner. */
908const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char* arg2)
909{
910    if(!strcasecmp(arg1, "file")) config.typeOfAction = 0x01;
911    else config.typeOfAction = 0x02;
912    
913    if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10;
914    else config.typeOfAction += 0x20;
915    return NULL;
916}</pre>
917
918
919
920
921
922<h3><a name="directive_complete" id="directive_complete">Putting it all together</a></h3>
923<p>
924Now that we have our directives set up, and handlers configured for them, 
925we can assemble our module into one big file:
926</p>
927
928
929<pre class="prettyprint lang-c">/* mod_example_config_simple.c: */
930#include &lt;stdio.h&gt;
931#include "apr_hash.h"
932#include "ap_config.h"
933#include "ap_provider.h"
934#include "httpd.h"
935#include "http_core.h"
936#include "http_config.h"
937#include "http_log.h"
938#include "http_protocol.h"
939#include "http_request.h"
940
941/*
942 ==============================================================================
943 Our configuration prototype and declaration:
944 ==============================================================================
945 */
946typedef struct {
947    int         enabled;      /* Enable or disable our module */
948    const char *path;         /* Some path to...something */
949    int         typeOfAction; /* 1 means action A, 2 means action B and so on */
950} example_config;
951
952static example_config config;
953
954/*
955 ==============================================================================
956 Our directive handlers:
957 ==============================================================================
958 */
959/* Handler for the "exampleEnabled" directive */
960const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg)
961{
962    if(!strcasecmp(arg, "on")) config.enabled = 1;
963    else config.enabled = 0;
964    return NULL;
965}
966
967/* Handler for the "examplePath" directive */
968const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg)
969{
970    config.path = arg;
971    return NULL;
972}
973
974/* Handler for the "exampleAction" directive */
975/* Let's pretend this one takes one argument (file or db), and a second (deny or allow), */
976/* and we store it in a bit-wise manner. */
977const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char* arg2)
978{
979    if(!strcasecmp(arg1, "file")) config.typeOfAction = 0x01;
980    else config.typeOfAction = 0x02;
981    
982    if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10;
983    else config.typeOfAction += 0x20;
984    return NULL;
985}
986
987/*
988 ==============================================================================
989 The directive structure for our name tag:
990 ==============================================================================
991 */
992static const command_rec        example_directives[] =
993{
994    AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"),
995    AP_INIT_TAKE1("examplePath", example_set_path, NULL, RSRC_CONF, "The path to whatever"),
996    AP_INIT_TAKE2("exampleAction", example_set_action, NULL, RSRC_CONF, "Special action value!"),
997    { NULL }
998};
999/*
1000 ==============================================================================
1001 Our module handler:
1002 ==============================================================================
1003 */
1004static int example_handler(request_rec *r)
1005{
1006    if(!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return(DECLINED);
1007    ap_set_content_type(r, "text/plain");
1008    ap_rprintf(r, "Enabled: %u\n", config.enabled);
1009    ap_rprintf(r, "Path: %s\n", config.path);
1010    ap_rprintf(r, "TypeOfAction: %x\n", config.typeOfAction);
1011    return OK;
1012}
1013
1014/*
1015 ==============================================================================
1016 The hook registration function (also initializes the default config values):
1017 ==============================================================================
1018 */
1019static void register_hooks(apr_pool_t *pool) 
1020{
1021    config.enabled = 1;
1022    config.path = "/foo/bar";
1023    config.typeOfAction = 3;
1024    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
1025}
1026/*
1027 ==============================================================================
1028 Our module name tag:
1029 ==============================================================================
1030 */
1031module AP_MODULE_DECLARE_DATA   example_module =
1032{
1033    STANDARD20_MODULE_STUFF,
1034    NULL,               /* Per-directory configuration handler */
1035    NULL,               /* Merge handler for per-directory configurations */
1036    NULL,               /* Per-server configuration handler */
1037    NULL,               /* Merge handler for per-server configurations */
1038    example_directives, /* Any directives we may have for httpd */
1039    register_hooks      /* Our hook registering function */
1040};</pre>
1041
1042
1043
1044
1045<p>
1046In our httpd.conf file, we can now change the hard-coded configuration by 
1047adding a few lines:
1048</p>
1049<pre class="prettyprint lang-config">ExampleEnabled On
1050ExamplePath "/usr/bin/foo"
1051ExampleAction file allow</pre>
1052
1053<p>
1054And thus we apply the configuration, visit <code>/example</code> on our 
1055web site, and we see the configuration has adapted to what we wrote in our 
1056configuration file.
1057</p>
1058
1059
1060
1061</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
1062<div class="section">
1063<h2><a name="context" id="context">Context aware configurations</a></h2>
1064<h3><a name="context_intro" id="context_intro">Introduction to context aware configurations</a></h3>
1065<p>
1066In Apache HTTP Server 2.4, different URLs, virtual hosts, directories etc can have very 
1067different meanings to the user of the server, and thus different contexts 
1068within which modules must operate. For example, let's assume you have this 
1069configuration set up for mod_rewrite:
1070</p>
1071<pre class="prettyprint lang-config">&lt;Directory "/var/www"&gt;
1072    RewriteCond %{HTTP_HOST} ^example.com$
1073    RewriteRule (.*) http://www.example.com/$1
1074&lt;/Directory&gt;
1075&lt;Directory "/var/www/sub"&gt;
1076    RewriteRule ^foobar$ index.php?foobar=true
1077&lt;/Directory&gt;</pre>
1078
1079<p>
1080In this example, you will have set up two different contexts for 
1081mod_rewrite:</p>
1082<ol>
1083<li>Inside <code>/var/www</code>, all requests for <code>http://example.com</code> must go to <code>http://www.example.com</code></li>
1084<li>Inside <code>/var/www/sub</code>, all requests for <code>foobar</code> must go to <code>index.php?foobar=true</code></li>
1085</ol>
1086<p>
1087If mod_rewrite (or the entire server for that matter) wasn't context aware, then 
1088these rewrite rules would just apply to every and any request made, 
1089regardless of where and how they were made, but since the module can pull 
1090the context specific configuration straight from the server, it does not need 
1091to know itself, which of the directives are valid in this context, since 
1092the server takes care of this.</p>
1093
1094<p>
1095So how does a module get the specific configuration for the server, 
1096directory or location in question? It does so by making one simple call:
1097</p>
1098
1099
1100<pre class="prettyprint lang-c">example_config *config = (example_config*) <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__CONFIG.html#ga1093a5908a384eacc929b028c79f2a02">ap_get_module_config</a>(r-&gt;per_dir_config, &amp;example_module);</pre>
1101
1102
1103
1104<p>
1105That's it! Of course, a whole lot goes on behind the scenes, which we will 
1106discuss in this chapter, starting with how the server came to know what our 
1107configuration looks like, and how it came to be set up as it is in the 
1108specific context.
1109</p>
1110
1111
1112<h3><a name="context_base" id="context_base">Our basic configuration setup</a></h3>
1113<p>In this chapter, we will be working with a slightly modified version of 
1114our previous context structure. We will set a <code>context</code> 
1115variable that we can use to track which context configuration is being 
1116used by the server in various places:
1117</p>
1118
1119<pre class="prettyprint lang-c">typedef struct {
1120    char        context[256];
1121    char        path[256];
1122    int         typeOfAction;
1123    int         enabled;
1124} example_config;</pre>
1125
1126
1127
1128<p>Our handler for requests will also be modified, yet still very simple:</p>
1129
1130
1131
1132<pre class="prettyprint lang-c">static int example_handler(request_rec *r)
1133{
1134    if(!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return(DECLINED);
1135    example_config *config = (example_config*) ap_get_module_config(r-&gt;per_dir_config, &amp;example_module);
1136    ap_set_content_type(r, "text/plain");
1137    ap_rprintf("Enabled: %u\n", config-&gt;enabled);
1138    ap_rprintf("Path: %s\n", config-&gt;path);
1139    ap_rprintf("TypeOfAction: %x\n", config-&gt;typeOfAction);
1140    ap_rprintf("Context: %s\n", config-&gt;context);
1141    return OK;
1142}</pre>
1143
1144
1145
1146
1147
1148<h3><a name="context_which" id="context_which">Choosing a context</a></h3>
1149<p>
1150Before we can start making our module context aware, we must first define, 
1151which contexts we will accept. As we saw in the previous chapter, defining 
1152a directive required five elements be set:</p>
1153
1154
1155
1156<pre class="prettyprint lang-c">AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"),</pre>
1157
1158
1159
1160
1161<p>The <code>RSRC_CONF</code> definition told the server that we would only allow 
1162this directive in a global server context, but since we are now trying out 
1163a context aware version of our module, we should set this to something 
1164more lenient, namely the value <code>ACCESS_CONF</code>, which lets us use 
1165the directive inside &lt;Directory&gt; and &lt;Location&gt; blocks. For more 
1166control over the placement of your directives, you can combine the following 
1167restrictions together to form a specific rule:
1168</p>
1169<ul>
1170<li><code>RSRC_CONF</code>: Allow in .conf files (not .htaccess) outside &lt;Directory&gt; or &lt;Location&gt;</li>
1171<li><code>ACCESS_CONF</code>: Allow in .conf files (not .htaccess) inside &lt;Directory&gt; or &lt;Location&gt;</li>
1172<li><code>OR_OPTIONS</code>: Allow in .conf files and .htaccess when <code>AllowOverride Options</code> is set</li>
1173<li><code>OR_FILEINFO</code>: Allow in .conf files and .htaccess when <code>AllowOverride FileInfo</code> is set</li>
1174<li><code>OR_AUTHCFG</code>: Allow in .conf files and .htaccess when <code>AllowOverride AuthConfig</code> is set</li>
1175<li><code>OR_INDEXES</code>: Allow in .conf files and .htaccess when <code>AllowOverride Indexes</code> is set</li>
1176<li><code>OR_ALL</code>: Allow anywhere in .conf files and .htaccess</li>
1177</ul>
1178
1179
1180<h3><a name="context_pool" id="context_pool">Using the server to allocate configuration slots</a></h3>
1181<p> A much smarter way to manage your configurations is by letting the server 
1182help you create them. To do so, we must first start off by changing our 
1183<em>name tag</em> to let the server know, that it should assist us in creating 
1184and managing our configurations. Since we have chosen the per-directory 
1185(or per-location) context for our module configurations, we'll add a 
1186per-directory creator and merger function reference in our tag:</p>
1187
1188
1189<pre class="prettyprint lang-c">module AP_MODULE_DECLARE_DATA   example_module =
1190{
1191    STANDARD20_MODULE_STUFF,
1192    create_dir_conf, /* Per-directory configuration handler */
1193    merge_dir_conf,  /* Merge handler for per-directory configurations */
1194    NULL,            /* Per-server configuration handler */
1195    NULL,            /* Merge handler for per-server configurations */
1196    directives,      /* Any directives we may have for httpd */
1197    register_hooks   /* Our hook registering function */
1198};</pre>
1199
1200
1201
1202
1203
1204
1205
1206<h3><a name="context_new" id="context_new">Creating new context configurations</a></h3>
1207<p>
1208Now that we have told the server to help us create and manage configurations, 
1209our first step is to make a function for creating new, blank 
1210configurations. We do so by creating the function we just referenced in 
1211our name tag as the Per-directory configuration handler:</p>
1212
1213<pre class="prettyprint lang-c">void* example_create_dir_conf(apr_pool_t* pool, char* context) {
1214    context = context ? context : "(undefined context)";
1215    example_config *cfg = apr_pcalloc(pool, sizeof(example_config));
1216    if(cfg) {
1217        /* Set some default values */
1218        strcpy(cfg-&gt;context, x);
1219        cfg-&gt;enabled = 0;
1220        cfg-&gt;path = "/foo/bar";
1221        cfg-&gt;typeOfAction = 0x11;
1222    }
1223    return cfg;
1224}</pre>
1225
1226
1227
1228
1229
1230
1231<h3><a name="context_merge" id="context_merge">Merging configurations</a></h3>
1232<p>
1233Our next step in creating a context aware configuration is merging 
1234configurations. This part of the process particularly applies to scenarios 
1235where you have a parent configuration and a child, such as the following: 
1236</p>
1237<pre class="prettyprint lang-config">&lt;Directory "/var/www"&gt;
1238    ExampleEnabled On
1239    ExamplePath /foo/bar
1240    ExampleAction file allow
1241&lt;/Directory&gt;
1242&lt;Directory "/var/www/subdir"&gt;
1243    ExampleAction file deny
1244&lt;/Directory&gt;</pre>
1245
1246<p>
1247In this example, it is natural to assume that the directory <code>
1248/var/www/subdir</code> should inherit the values set for the <code>/var/www
1249</code> directory, as we did not specify an <code>ExampleEnabled</code> nor 
1250an <code>ExamplePath</code> for this directory. The server does not presume to 
1251know if this is true, but cleverly does the following:
1252</p>
1253<ol>
1254<li>Creates a new configuration for <code>/var/www</code></li>
1255<li>Sets the configuration values according to the directives given for <code>/var/www</code></li>
1256<li>Creates a new configuration for <code>/var/www/subdir</code></li>
1257<li>Sets the configuration values according to the directives given for <code>/var/www/subdir</code></li>
1258<li><strong>Proposes a merge</strong> of the two configurations into a new configuration for <code>/var/www/subdir</code></li>
1259</ol>
1260<p>
1261This proposal is handled by the <code>merge_dir_conf</code> function we 
1262referenced in our name tag. The purpose of this function is to assess the 
1263two configurations and decide how they are to be merged:</p>
1264
1265
1266
1267<pre class="prettyprint lang-c">void* merge_dir_conf(apr_pool_t* pool, void* BASE, void* ADD) {
1268    example_config* base = (example_config *) BASE ; /* This is what was set in the parent context */
1269    example_config* add = (example_config *) ADD ;   /* This is what is set in the new context */
1270    example_config* conf = (example_config *) create_dir_conf(pool, "Merged configuration"); /* This will be the merged configuration */
1271    
1272    /* Merge configurations */
1273    conf-&gt;enabled = ( add-&gt;enabled == 0 ) ? base-&gt;enabled : add-&gt;enabled ;
1274    conf-&gt;typeOfAction = add-&gt;typeOfAction ? add-&gt;typeOfAction : base-&gt;typeOfAction;
1275    strcpy(conf-&gt;path, strlen(add-&gt;path) ? add-&gt;path : base-&gt;path);
1276    
1277    return conf ;
1278}</pre>
1279
1280
1281
1282
1283
1284
1285<h3><a name="context_example" id="context_example">Trying out our new context aware configurations</a></h3>
1286<p>
1287Now, let's try putting it all together to create a new module that is 
1288context aware. First off, we'll create a configuration that lets us test 
1289how the module works:
1290</p>
1291<pre class="prettyprint lang-config">&lt;Location "/a"&gt;
1292    SetHandler example-handler
1293    ExampleEnabled on
1294    ExamplePath "/foo/bar"
1295    ExampleAction file allow
1296&lt;/Location&gt;
1297
1298&lt;Location "/a/b"&gt;
1299    ExampleAction file deny
1300    ExampleEnabled off
1301&lt;/Location&gt;
1302
1303&lt;Location "/a/b/c"&gt;
1304    ExampleAction db deny
1305    ExamplePath "/foo/bar/baz"
1306    ExampleEnabled on
1307&lt;/Location&gt;</pre>
1308
1309<p>
1310Then we'll assemble our module code. Note, that since we are now using our 
1311name tag as reference when fetching configurations in our handler, I have 
1312added some prototypes to keep the compiler happy:
1313</p>
1314
1315
1316<pre class="prettyprint lang-c">/*$6
1317 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1318 * mod_example_config.c
1319 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1320 */
1321
1322
1323#include &lt;stdio.h&gt;
1324#include "apr_hash.h"
1325#include "ap_config.h"
1326#include "ap_provider.h"
1327#include "httpd.h"
1328#include "http_core.h"
1329#include "http_config.h"
1330#include "http_log.h"
1331#include "http_protocol.h"
1332#include "http_request.h"
1333
1334/*$1
1335 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1336    Configuration structure
1337 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1338 */
1339
1340typedef struct
1341{
1342    char    context[256];
1343    char    path[256];
1344    int     typeOfAction;
1345    int     enabled;
1346} example_config;
1347
1348/*$1
1349 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1350    Prototypes
1351 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1352 */
1353
1354static int    example_handler(request_rec *r);
1355const char    *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg);
1356const char    *example_set_path(cmd_parms *cmd, void *cfg, const char *arg);
1357const char    *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char *arg2);
1358void          *create_dir_conf(apr_pool_t *pool, char *context);
1359void          *merge_dir_conf(apr_pool_t *pool, void *BASE, void *ADD);
1360static void   register_hooks(apr_pool_t *pool);
1361
1362/*$1
1363 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1364    Configuration directives
1365 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1366 */
1367
1368static const command_rec    directives[] =
1369{
1370    AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, ACCESS_CONF, "Enable or disable mod_example"),
1371    AP_INIT_TAKE1("examplePath", example_set_path, NULL, ACCESS_CONF, "The path to whatever"),
1372    AP_INIT_TAKE2("exampleAction", example_set_action, NULL, ACCESS_CONF, "Special action value!"),
1373    { NULL }
1374};
1375
1376/*$1
1377 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1378    Our name tag
1379 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1380 */
1381
1382module AP_MODULE_DECLARE_DATA    example_module =
1383{
1384    STANDARD20_MODULE_STUFF,
1385    create_dir_conf,    /* Per-directory configuration handler */
1386    merge_dir_conf,     /* Merge handler for per-directory configurations */
1387    NULL,               /* Per-server configuration handler */
1388    NULL,               /* Merge handler for per-server configurations */
1389    directives,         /* Any directives we may have for httpd */
1390    register_hooks      /* Our hook registering function */
1391};
1392
1393/*
1394 =======================================================================================================================
1395    Hook registration function
1396 =======================================================================================================================
1397 */
1398static void register_hooks(apr_pool_t *pool)
1399{
1400    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
1401}
1402
1403/*
1404 =======================================================================================================================
1405    Our example web service handler
1406 =======================================================================================================================
1407 */
1408static int example_handler(request_rec *r)
1409{
1410    if(!r-&gt;handler || strcmp(r-&gt;handler, "example-handler")) return(DECLINED);
1411
1412    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1413    example_config    *config = (example_config *) ap_get_module_config(r-&gt;per_dir_config, &amp;example_module);
1414    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1415
1416    ap_set_content_type(r, "text/plain");
1417    ap_rprintf(r, "Enabled: %u\n", config-&gt;enabled);
1418    ap_rprintf(r, "Path: %s\n", config-&gt;path);
1419    ap_rprintf(r, "TypeOfAction: %x\n", config-&gt;typeOfAction);
1420    ap_rprintf(r, "Context: %s\n", config-&gt;context);
1421    return OK;
1422}
1423
1424/*
1425 =======================================================================================================================
1426    Handler for the "exampleEnabled" directive
1427 =======================================================================================================================
1428 */
1429const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg)
1430{
1431    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1432    example_config    *conf = (example_config *) cfg;
1433    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1434
1435    if(conf)
1436    {
1437        if(!strcasecmp(arg, "on"))
1438            conf-&gt;enabled = 1;
1439        else
1440            conf-&gt;enabled = 0;
1441    }
1442
1443    return NULL;
1444}
1445
1446/*
1447 =======================================================================================================================
1448    Handler for the "examplePath" directive
1449 =======================================================================================================================
1450 */
1451const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg)
1452{
1453    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1454    example_config    *conf = (example_config *) cfg;
1455    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1456
1457    if(conf)
1458    {
1459        strcpy(conf-&gt;path, arg);
1460    }
1461
1462    return NULL;
1463}
1464
1465/*
1466 =======================================================================================================================
1467    Handler for the "exampleAction" directive ;
1468    Let's pretend this one takes one argument (file or db), and a second (deny or allow), ;
1469    and we store it in a bit-wise manner.
1470 =======================================================================================================================
1471 */
1472const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char *arg2)
1473{
1474    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1475    example_config    *conf = (example_config *) cfg;
1476    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1477
1478    if(conf)
1479    {
1480        {
1481            if(!strcasecmp(arg1, "file"))
1482                conf-&gt;typeOfAction = 0x01;
1483            else
1484                conf-&gt;typeOfAction = 0x02;
1485            if(!strcasecmp(arg2, "deny"))
1486                conf-&gt;typeOfAction += 0x10;
1487            else
1488                conf-&gt;typeOfAction += 0x20;
1489        }
1490    }
1491
1492    return NULL;
1493}
1494
1495/*
1496 =======================================================================================================================
1497    Function for creating new configurations for per-directory contexts
1498 =======================================================================================================================
1499 */
1500void *create_dir_conf(apr_pool_t *pool, char *context)
1501{
1502    context = context ? context : "Newly created configuration";
1503
1504    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1505    example_config    *cfg = apr_pcalloc(pool, sizeof(example_config));
1506    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1507
1508    if(cfg)
1509    {
1510        {
1511            /* Set some default values */
1512            strcpy(cfg-&gt;context, context);
1513            cfg-&gt;enabled = 0;
1514            memset(cfg-&gt;path, 0, 256);
1515            cfg-&gt;typeOfAction = 0x00;
1516        }
1517    }
1518
1519    return cfg;
1520}
1521
1522/*
1523 =======================================================================================================================
1524    Merging function for configurations
1525 =======================================================================================================================
1526 */
1527void *merge_dir_conf(apr_pool_t *pool, void *BASE, void *ADD)
1528{
1529    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1530    example_config    *base = (example_config *) BASE;
1531    example_config    *add = (example_config *) ADD;
1532    example_config    *conf = (example_config *) create_dir_conf(pool, "Merged configuration");
1533    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1534
1535    conf-&gt;enabled = (add-&gt;enabled == 0) ? base-&gt;enabled : add-&gt;enabled;
1536    conf-&gt;typeOfAction = add-&gt;typeOfAction ? add-&gt;typeOfAction : base-&gt;typeOfAction;
1537    strcpy(conf-&gt;path, strlen(add-&gt;path) ? add-&gt;path : base-&gt;path);
1538    return conf;
1539}</pre>
1540
1541
1542
1543
1544
1545
1546
1547</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
1548<div class="section">
1549<h2><a name="summary" id="summary">Summing up</a></h2>
1550<p>
1551We have now looked at how to create simple modules for Apache HTTP Server 2.4 and 
1552configuring them. What you do next is entirely up to you, but it is my 
1553hope that something valuable has come out of reading this documentation. 
1554If you have questions on how to further develop modules, you are welcome 
1555to join our <a href="http://httpd.apache.org/lists.html">mailing lists</a> 
1556or check out the rest of our documentation for further tips.
1557</p>
1558</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
1559<div class="section">
1560<h2><a name="snippets" id="snippets">Some useful snippets of code</a></h2>
1561
1562<h3><a name="get_post" id="get_post">Retrieve variables from POST form data</a></h3>
1563
1564
1565
1566<pre class="prettyprint lang-c">typedef struct {
1567    const char* key;
1568    const char* value;
1569} keyValuePair;
1570
1571keyValuePair* readPost(request_rec* r) {
1572    apr_array_header_t *pairs = NULL;
1573    apr_off_t len;
1574    apr_size_t size;
1575    int res;
1576    int i = 0;
1577    char *buffer;
1578    keyValuePair* kvp;
1579
1580    res = ap_parse_form_data(r, NULL, &amp;pairs, -1, HUGE_STRING_LEN);
1581    if (res != OK || !pairs) return NULL; /* Return NULL if we failed or if there are is no POST data */
1582    kvp = apr_pcalloc(r-&gt;pool, sizeof(keyValuePair) * (pairs-&gt;nelts + 1));
1583    while (pairs &amp;&amp; !apr_is_empty_array(pairs)) {
1584        ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
1585        apr_brigade_length(pair-&gt;value, 1, &amp;len);
1586        size = (apr_size_t) len;
1587        buffer = apr_palloc(r-&gt;pool, size + 1);
1588        apr_brigade_flatten(pair-&gt;value, buffer, &amp;size);
1589        buffer[len] = 0;
1590        kvp[i].key = apr_pstrdup(r-&gt;pool, pair-&gt;name);
1591        kvp[i].value = buffer;
1592        i++;
1593    }
1594    return kvp;
1595}
1596
1597static int example_handler(request_rec *r)
1598{
1599    /*~~~~~~~~~~~~~~~~~~~~~~*/
1600    keyValuePair* formData;
1601    /*~~~~~~~~~~~~~~~~~~~~~~*/
1602
1603    formData = readPost(r);
1604    if (formData) {
1605        int i;
1606        for (i = 0; &amp;formData[i]; i++) {
1607            if (formData[i].key &amp;&amp; formData[i].value) {
1608                ap_rprintf(r, "%s = %s\n", formData[i].key, formData[i].value);
1609            } else if (formData[i].key) {
1610                ap_rprintf(r, "%s\n", formData[i].key);
1611            } else if (formData[i].value) {
1612                ap_rprintf(r, "= %s\n", formData[i].value);
1613            } else {
1614                break;
1615            }
1616        }
1617    }
1618    return OK;
1619}</pre>
1620
1621
1622
1623
1624    
1625
1626    <h3><a name="headers_out" id="headers_out">Printing out every HTTP header received</a></h3>
1627
1628
1629
1630<pre class="prettyprint lang-c">static int example_handler(request_rec *r)
1631{
1632    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1633    const apr_array_header_t    *fields;
1634    int                         i;
1635    apr_table_entry_t           *e = 0;
1636    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1637
1638    fields = apr_table_elts(r-&gt;headers_in);
1639    e = (apr_table_entry_t *) fields-&gt;elts;
1640    for(i = 0; i &lt; fields-&gt;nelts; i++) {
1641        ap_rprintf(r, "%s: %s\n", e[i].key, e[i].val);
1642    }
1643    return OK;
1644}</pre>
1645
1646
1647
1648
1649    
1650
1651    <h3><a name="request_body" id="request_body">Reading the request body into memory</a></h3>
1652
1653
1654
1655<pre class="prettyprint lang-c">static int util_read(request_rec *r, const char **rbuf, apr_off_t *size)
1656{
1657    /*~~~~~~~~*/
1658    int rc = OK;
1659    /*~~~~~~~~*/
1660
1661    if((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
1662        return(rc);
1663    }
1664
1665    if(ap_should_client_block(r)) {
1666
1667        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1668        char         argsbuffer[HUGE_STRING_LEN];
1669        apr_off_t    rsize, len_read, rpos = 0;
1670        apr_off_t length = r-&gt;remaining;
1671        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1672
1673        *rbuf = (const char *) apr_pcalloc(r-&gt;pool, (apr_size_t) (length + 1));
1674        *size = length;
1675        while((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) &gt; 0) {
1676            if((rpos + len_read) &gt; length) {
1677                rsize = length - rpos;
1678            }
1679            else {
1680                rsize = len_read;
1681            }
1682
1683            memcpy((char *) *rbuf + rpos, argsbuffer, (size_t) rsize);
1684            rpos += rsize;
1685        }
1686    }
1687    return(rc);
1688}
1689
1690static int example_handler(request_rec* r) 
1691{
1692    /*~~~~~~~~~~~~~~~~*/
1693    apr_off_t   size;
1694    const char  *buffer;
1695    /*~~~~~~~~~~~~~~~~*/
1696
1697    if(util_read(r, &amp;buffer, &amp;size) == OK) {
1698        ap_rprintf(r, "We read a request body that was %" APR_OFF_T_FMT " bytes long", size);
1699    }
1700    return OK;
1701}</pre>
1702
1703
1704
1705
1706
1707    
1708
1709</div></div>
1710<div class="bottomlang">
1711<p><span>Available Languages: </span><a href="/en/developer/modguide.html" title="English">&nbsp;en&nbsp;</a></p>
1712</div><div class="top"><a href="#page-header"><img src="/images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our <a href="http://httpd.apache.org/lists.html">mailing lists</a>.</div>
1713<script type="text/javascript"><!--//--><![CDATA[//><!--
1714var comments_shortname = 'httpd';
1715var comments_identifier = 'http://httpd.apache.org/docs/2.4/developer/modguide.html';
1716(function(w, d) {
1717    if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
1718        d.write('<div id="comments_thread"><\/div>');
1719        var s = d.createElement('script');
1720        s.type = 'text/javascript';
1721        s.async = true;
1722        s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
1723        (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
1724    }
1725    else { 
1726        d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
1727    }
1728})(window, document);
1729//--><!]]></script></div><div id="footer">
1730<p class="apache">Copyright 2014 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
1731<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
1732if (typeof(prettyPrint) !== 'undefined') {
1733    prettyPrint();
1734}
1735//--><!]]></script>
1736</body></html>