httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From humbed...@apache.org
Subject svn commit: r1311422 [3/4] - in /httpd/httpd/trunk/docs/manual/developer: modguide.html modguide.html.en modguide.xml modguide.xml.meta
Date Mon, 09 Apr 2012 20:32:20 GMT
Added: httpd/httpd/trunk/docs/manual/developer/modguide.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/developer/modguide.xml?rev=1311422&view=auto
==============================================================================
--- httpd/httpd/trunk/docs/manual/developer/modguide.xml (added)
+++ httpd/httpd/trunk/docs/manual/developer/modguide.xml Mon Apr  9 20:32:20 2012
@@ -0,0 +1,1575 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
+<?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
+<!-- $LastChangedRevision: 1307798 $ -->
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manualpage metafile="modguide.xml.meta">
+<parentdocument href="./">Developer</parentdocument>
+
+  <title>Developing modules for the Apache HTTP Server 2.4</title>
+
+<summary>
+<p>This document explains how you can develop modules for the Apache HTTP Server 2.4</p>
+</summary>
+
+<seealso><a href="request.html">Request Processing in Apache 2.4</a></seealso>
+<seealso><a href="hooks.html">Apache 2.x Hook Functions</a></seealso>
+
+<section id="introduction"><title>Introduction</title>
+<section id="what"><title>What we will be discussing in this document</title>
+<p>
+This document will discuss how you can easily create modules for the Apache HTTP Server 2.4 (&quot;Apache&quot;), 
+by exploring an example module called <code>mod_example</code>. In the first part of this document, the purpose of this 
+module will be to calculate and print out various digest values for existing files on your web server, whenever we 
+access the URL <code>http://hostname/filename.sum</code>. For instance, if we want to know the MD5 digest value of the file 
+located at <code>http://www.example.com/index.html</code>, we would visit <code>http://www.example.com/index.html.sum</code>. 
+</p>
+<p>
+In the second part of this document, which deals with configuration directive and context awareness, we will be looking at 
+a module that simply write out its own configuration to the client.
+</p>
+</section>
+<section id="prerequisites"><title>Prerequisites</title>
+<p>
+First and foremost, you are expected to have a basic knowledge of how the C programming language works. In most cases, 
+we will try to be as pedagogical as possible and link to documents describing the functions used in the examples, 
+but there are also many cases where it is necessary to either just assume that "it works" or do some digging youself 
+into what the hows and whys of various function calls. 
+</p>
+<p>
+Lastly, you will need to have a basic understanding of how modules are loaded and configured in Apache, as well as 
+how to get the headers for Apache if you do not have them already, as these are needed for compiling new modules.
+</p>
+</section>
+<section id="compiling"><title>Compiling your module</title>
+<p>
+To compile the source code we are building in this document, we will be using <a href="../programs/apxs.html">APXS</a>. 
+Assuming your source file is called mod_example.c, compiling, installing and activating the module is as simple as: 
+<example><pre>
+apxs -i -a -c mod_example.c
+</pre></example>
+</p>
+</section>
+</section>
+
+<section id="basics"><title>Defining a module</title>
+<img src="../images/build_a_mod_3.png"/><br/>
+<p>Every module starts with the same declaration, or name tag if you will, that defines a module as <em>a separate entity within Apache</em>:
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+module AP_MODULE_DECLARE_DATA   example_module <code style='color:#806030; '>=</code>
+<code style='color:#806030; '>{</code>
+    STANDARD20_MODULE_STUFF<code style='color:#806030; '>,</code>
+    create_dir_conf<code style='color:#806030; '>,</code> <code style='color:#c34e00; '>/* Per-directory configuration handler */</code>
+    merge_dir_conf<code style='color:#806030; '>,</code>  <code style='color:#c34e00; '>/* Merge handler for per-directory configurations */</code>
+    create_svr_conf<code style='color:#806030; '>,</code> <code style='color:#c34e00; '>/* Per-server configuration handler */</code>
+    merge_svr_conf<code style='color:#806030; '>,</code>  <code style='color:#c34e00; '>/* Merge handler for per-server configurations */</code>
+    directives<code style='color:#806030; '>,</code>      <code style='color:#c34e00; '>/* Any directives we may have for httpd */</code>
+    register_hooks   <code style='color:#c34e00; '>/* Our hook registering function */</code>
+<code style='color:#806030; '>}</code><code style='color:#806030; '>;</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+This bit of code lets Apache know that we have now registered a new module in the system, 
+and that its name is <code>example_module</code>. The name of the module is used primarilly
+for two things:<br/>
+<ul>
+<li>Letting Apache know how to load the module using the LoadModule</li>
+<li>Setting up a namespace for the module to use in configurations</li>
+</ul>
+For now, we're only concerned with the first purpose of the module name, 
+which comes into play when we need to load the module:<br/>
+<example><pre><a href="../mod/mod_so.html#LoadModule">LoadModule</a> example_module modules/mod_example.so</pre></example>
+In essence, this tells Apache to open up <code>mod_example.so</code> and look for a module 
+called <code>example_module</code>.
+</p>
+<p>
+Within this name tag of ours is also a bunch of references to how we would like to handle things: 
+Which directives do we respond to in a configuration file or .htaccess, how do we operate 
+within specific contexts, and what handlers are we interested in registering with the Apache 
+service. We'll return to all these elements later in this document.
+</p>
+</section>
+<section id="hooking"><title>Getting started: Hooking into Apache</title>
+<section id="hook_intro"><title>An introduction to hooks</title>
+<p>
+When handling requests in Apache, the first thing you will need to do is create a hook into 
+the request handling process. A hook is essentially a message telling Apache that you are 
+willing to either serve or at least take a glance at certain requests given by clients. All 
+handlers, whether it's mod_rewrite, mod_authn_*, mod_proxy and so on, are hooked into specific 
+parts of the request process. As you are probably aware, modules serve different purposes; Some 
+are authentication/authorization handlers, others are file or script handlers while some third 
+modules rewrite URIs or proxies content. Furthermore, in the end, it is up to the user of Apache 
+how and when each module will come into place. Thus, Apache itself does not presume to know 
+which module is responsible for handling a specific request, and will ask each module whether 
+they have an interest in a given request or not. It is then up to each module to either gently 
+decline serving a request, accept serving it or flat out deny the request from being served, 
+as authentication/authorization modules do: <br/>
+<img src="../images/build_a_mod_2.png" /><br/>
+To make it a bit easier for handlers such as our mod_example to know whether the client is 
+requesting content we should handle or not, Apache has directives for hinting to modules whether 
+their assistance is needed or not. Two of these are <directive
+module="mod_mime">AddHandler</directive> and <directive module="core">SetHandler</directive>. 
+Let's take a look at an example using <directive module="mod_mime">AddHandler</directive>. 
+In our example case, we want every request ending with .sum to be served by <code>mod_example</code>, 
+so we'll add a configuration directive that tells Apache to do just that:
+<example><pre>
+AddHandler example-handler .sum
+</pre></example>
+What this tells Apache is the following: <em>Whenever we receive a request for a URI ending in .sum, 
+we are to let all modules know that we are looking for whoever goes by the name of &quot;example-handler&quot;
+</em>. Thus, when a request is being served that ends in .sum, Apache will let all modules know, that 
+this request should be served by &quot;example-handler&quot;. As you will see later, when we start 
+building mod_example, we will check for this handler tag relayed by <code>AddHandler</code> and 
+reply to Apache based on the value of this tag.
+</p>
+</section>
+<section id="hook_declaration"><title>Hooking into httpd</title>
+<p>
+To begin with, we only want to create a simple handler, that replies to the client browser 
+when a specific URL is requested, so we won't bother setting up configuration handlers and 
+directives just yet. Our initial module definition will look like this:<br/>
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+module AP_MODULE_DECLARE_DATA   example_module =
+{
+    STANDARD20_MODULE_STUFF,
+    <code style='color:#7f0055; font-weight:bold; '>NULL</code>,
+    <code style='color:#7f0055; font-weight:bold; '>NULL</code>,
+    <code style='color:#7f0055; font-weight:bold; '>NULL</code>,
+    <code style='color:#7f0055; font-weight:bold; '>NULL</code>,
+    <code style='color:#7f0055; font-weight:bold; '>NULL</code>,
+    <code style='color:#800040; '>register_hooks</code>   <code style='color:#c34e00; '><code style='color:#c34e00; '>/* Our hook registering function */</code></code>
+};
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+This lets Apache know that we are not interesting in anything fancy, we just want to hook onto 
+the requests and possibly handle some of them.
+</p>
+<p>
+The reference in our example declaration, <code>register_hooks</code> is the name of a function 
+we will create to manage how we hook onto the request process. In this example module, the function 
+has just one purpose; To create a simple hook that gets called after all the rewrites, access 
+control etc has been handled. Thus, we will let Apache know, that we want to hook into its process 
+as one of the last modules: 
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#400000; font-weight:bold; '>static</code> <code style='color:#400000; font-weight:bold; '>void</code> register_hooks<code style='color:#806030; '>(</code>apr_pool_t <code style='color:#806030; '>*</code>pool<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#c34e00; '>/* Create a hook in the request handler, so we get called when a request arrives */</code>
+    <code style='color:#800040; '>ap_hook_handler</code><code style='color:#806030; '>(</code>example_handler<code style='color:#806030; '>,</code> <code style='color:#7f0055; font-weight:bold; '>NULL</code><code style='color:#806030; '>,</code> <code style='color:#7f0055; font-weight:bold; '>NULL</code><code style='color:#806030; '>,</code> APR_HOOK_LAST<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+The <code>example_handler</code> reference is the function that will handle the request. We will 
+discuss how to create a handler in the next chapter.
+</p>
+</section>
+<section id="hook_others"><title>Other useful hooks</title>
+<p>
+Hooking into the request handling phase is but one of many hooks that you can create. Some other ways of hooking are:
+<ul>
+<li><code>ap_hook_child_init</code>: Place a hook that executes when a child process is spawned (commonly used for initializing modules after Apache has forked)</li>
+<li><code>ap_hook_pre_config</code>: Place a hook that executes before any configuration data has been read (very early hook)</li>
+<li><code>ap_hook_post_config</code>: Place a hook that executes after configuration has been parsed, but before Apache has forked</li>
+<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>
+</ul>
+</p>
+</section>
+</section>
+
+<section id="handling"><title>Building a handler</title>
+<p>
+A handler is essentially a function that receives a callback when a request to Apache is made. 
+It is passed a record of the current request (how it was made, which headers and requests were 
+passed along, who's giving the request and so on), and is put in charge of either telling 
+Apache that it's not interested in the request or handle the request with the tools provided.
+</p>
+<section id="simple_handler"><title>A simple &quot;Hello, world!&quot; handler</title>
+Let's start off by making a very simple request handler that does the following: <br/>
+<ol>
+<li>Check that this is a request that should be served by &quot;example-handler&quot;</li>
+<li>Set the content type of our output to <code>text/html</code></li>
+<li>Write &quot;Hello, world!&quot; back to the client browser</li>
+<li>Let Apache know that we took care of this request and everything went fine</li>
+</ol>
+In C code, our example handler will now look like this:<br/>
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#400000; font-weight:bold; '>static</code> <code style='color:#400000; font-weight:bold; '>int</code> example_handler<code style='color:#806030; '>(</code>request_rec <code style='color:#806030; '>*</code>r<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#c34e00; '>/* First off, we need to check if this is a call for the "example-handler" handler.</code>
+<code style='color:#c34e00; '>&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;* If it is, we accept it and do our things, it not, we simply return DECLINED,</code>
+<code style='color:#c34e00; '>&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;* and Apache will try somewhere else.</code>
+<code style='color:#c34e00; '>&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;*/</code>
+    <code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>handler</code> <code style='color:#806030; '>|</code><code style='color:#806030; '>|</code> <code style='color:#800040; '>strcmp</code><code style='color:#806030; '>(</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>handler</code><code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>example-handler</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>)</code> <code style='color:#400000; font-weight:bold; '>return</code> <code style='color:#806030; '>(</code>DECLINED<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    
+    <code style='color:#c34e00; '>/* Now that we are handling this request, we'll write out "Hello, world!" to the client.</code>
+<code style='color:#c34e00; '>&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;* To do so, we must first set the appropriate content type, followed by our output.</code>
+<code style='color:#c34e00; '>&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;*/</code>
+    <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#gaa2f8412c400197338ec509f4a45e4579">ap_set_content_type</a><code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>text/html</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga5e91eb6ca777c9a427b2e82bf1eeb81d">ap_rprintf</a><code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>Hello, world!</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    
+    <code style='color:#c34e00; '>/* Lastly, we must tell Apache that we took care of this request and everything went fine.</code>
+<code style='color:#c34e00; '>&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;* We do so by simply returning the value OK to Apache.</code>
+<code style='color:#c34e00; '>&#xa0;&#xa0;&#xa0;&#xa0;&#xa0;*/</code>
+    <code style='color:#400000; font-weight:bold; '>return</code> OK<code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+Now, we put all we have learned together and end up with a program that looks like <a href="mod_example_1.c">
+mod_example_1.c</a>. The functions used in this example will be explained later in the section 
+<a href="#functions">&quot;Some useful functions you should know&quot;</a>.
+</section>
+<section id="request_rec"><title>The request_rec structure</title>
+<p>The most essential part of any request is the <em>request record</em>. In a call to a handler function, this 
+is represented by the <code>request_req*</code> structure passed along with every call that is made. This 
+struct, typically just refered to as <code>r</code> in modules, contains all the information you need for 
+your module to fully process any HTTP request and respond accordingly.</p>
+<p>Some key elements of the <code>request_req</code> structure are:
+<ul>
+<li><code><code style='color:#008833'>r-&gt;handler</code> (char*)</code>: Contains the name of the handler, Apache is currently asking to do the handling of this request</li>
+<li><code><code style='color:#008833'>r-&gt;method</code> (char*)</code>: Contains the HTTP method being used, f.x. GET or POST</li>
+<li><code><code style='color:#008833'>r-&gt;filename</code> (char*)</code>: Contains the translated filename the client is requesting</li>
+<li><code><code style='color:#008833'>r-&gt;args</code> (char*)</code>: Contains the query string of the request, if any</li>
+<li><code><code style='color:#008833'>r-&gt;headers_in</code> (apr_table_t*)</code>: Contains all the headers sent by the client</li>
+<li><code><code style='color:#008833'>r-&gt;connection</code> (conn_rec*)</code>: A record containing information about the current connection</li>
+<li><code><code style='color:#008833'>r-&gt;useragent_ip</code> (char*)</code>: The IP address of the client connecting to us</li>
+<li><code><code style='color:#008833'>r-&gt;pool</code> (apr_pool_t*)</code>: The memory pool of this request. We'll discuss this in the &quot;
+<a href="#memory">Memory management</a>&quot; chapter.</li>
+</ul>
+A complete list of all the values contained with in the <code>request_req</code> structure can be found in 
+the <a href="http://svn.apache.org/repos/asf/httpd/httpd/trunk/include/httpd.h"><code>httpd.h</code></a> header 
+file or at [insert link here].
+</p>
+<p>
+Let's try out some of these variables in another example handler:<br/>
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#400000; font-weight:bold; '>static</code> <code style='color:#400000; font-weight:bold; '>int</code> example_handler<code style='color:#806030; '>(</code>request_rec <code style='color:#806030; '>*</code>r<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#c34e00; '>/* Set the appropriate content type */</code>
+    <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#gaa2f8412c400197338ec509f4a45e4579">ap_set_content_type</a><code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>text/html</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+
+    <code style='color:#c34e00; '>/* Print out the IP address of the client connecting to us: */</code>
+    <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga5e91eb6ca777c9a427b2e82bf1eeb81d">ap_rprintf</a><code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>&lt;h2>Hello, </code><code style='color:#0f6900; '>%s</code><code style='color:#e60000; '>!&lt;/h2></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>useragent_ip</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    
+    <code style='color:#c34e00; '>/* If we were reached through a GET or a POST request, be happy, else sad. */</code>
+    <code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code> <code style='color:#806030; '>!</code><code style='color:#800040; '>strcmp</code><code style='color:#806030; '>(</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>method</code><code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>POST</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code> <code style='color:#806030; '>|</code><code style='color:#806030; '>|</code> <code style='color:#806030; '>!</code><code style='color:#800040; '>strcmp</code><code style='color:#806030; '>(</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>method</code><code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>GET</code><code style='color:#80000
 0; '>"</code><code style='color:#806030; '>)</code> <code style='color:#806030; '>)</code> <code style='color:#806030; '>{</code>
+        ap_rputs<code style='color:#806030; '>(</code><code style='color:#800000; '>"</code><code style='color:#e60000; '>You used a GET or a POST method, that makes us happy!&lt;br></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    <code style='color:#806030; '>}</code>
+    <code style='color:#400000; font-weight:bold; '>else</code> <code style='color:#806030; '>{</code>
+        ap_rputs<code style='color:#806030; '>(</code><code style='color:#800000; '>"</code><code style='color:#e60000; '>You did not use POST or GET, that makes us sad :(&lt;br></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    <code style='color:#806030; '>}</code>
+
+    <code style='color:#c34e00; '>/* Lastly, if there was a query string, let's print that too! */</code>
+    <code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>args</code><code style='color:#806030; '>)</code> <code style='color:#806030; '>{</code>
+        <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga5e91eb6ca777c9a427b2e82bf1eeb81d">ap_rprintf</a><code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>Your query string was: </code><code style='color:#0f6900; '>%s</code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>args</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    <code style='color:#806030; '>}</code>
+    <code style='color:#400000; font-weight:bold; '>return</code> OK<code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+</p>
+</section>
+
+<section id="return_value"><title>Return values</title>
+<p>
+Apache relies on return values from handlers to signify whether a request was handled or not, 
+and if so, whether the request went well or not. If a module is not interested in handling 
+a specific request, it should always return the value <code>DECLINED</code>. If it is handling 
+a request, it should either return the generic value <code>OK</code>, or a specific HTTP status 
+code, for example:
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#400000; font-weight:bold; '>static</code> <code style='color:#400000; font-weight:bold; '>int</code> example_handler<code style='color:#806030; '>(</code>request_rec <code style='color:#806030; '>*</code>r<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#c34e00; '>/* Return 404: Not found */</code>
+    <code style='color:#400000; font-weight:bold; '>return</code> HTTP_NOT_FOUND<code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+Returning <code>OK</code> or a HTTP status code does not necessarilly mean that the request will end. Apache 
+may still have other handlers that are interested in this request, for instance the logging modules 
+which, upon a successful request, will write down a summary of what was requested and how it went. 
+To do a full stop and prevent any further processing after your module is done, you can return the 
+value <code>DONE</code> to let Apache know that it should cease all activity on this request and 
+carry on with the next, without informing other handlers.
+<br/>
+<strong>General response codes:</strong>
+<ul>
+<li><code>DECLINED</code>: We are not handling this request</li>
+<li><code>OK</code>: We handled this request and it went well</li>
+<li><code>DONE</code>: We handled this request and Apache should just close this thread without further processing</li>
+</ul><br/>
+<strong>HTTP specific return codes (excerpt):</strong>
+<ul>
+<li><code>HTTP_OK (200)</code>: Request was okay</li>
+<li><code>HTTP_MOVED_PERMANENTLY (301)</code>: The resource has moved to a new URL</li>
+<li><code>HTTP_UNAUTHORIZED (401)</code>: Client is not authorized to visit this page</li>
+<li><code>HTTP_FORBIDDEN (403)</code>: Permission denied</li>
+<li><code>HTTP_NOT_FOUND (404)</code>: File not found</li>
+<li><code>HTTP_INTERNAL_SERVER_ERROR (500)</code>: Internal server error (self explanatory)</li>
+</ul>
+</p>
+</section>
+
+<section id="functions"><title>Some useful functions you should know</title>
+
+<ul>
+<li>
+    <code>ap_rputs(const char *string, request_req *r)</code>: <br/>
+    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">
+    ap_rwrite</a>.
+    
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>ap_rputs<code style='color:#806030; '>(</code><code style='color:#800000; '>"</code><code style='color:#e60000; '>Hello, world!</code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code></pre>
+<!-- END EXAMPLE CODE -->
+
+
+</li>
+<li>
+    <code>
+    <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga5e91eb6ca777c9a427b2e82bf1eeb81d">ap_rprintf</a></code>: <br/>
+    This function works just like <code>printf</code>, except it sends the result to the client. 
+    
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'><code style='color:#2e8800; '><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga5e91eb6ca777c9a427b2e82bf1eeb81d">ap_rprintf</a></code><code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>Hello, </code><code style='color:#0f6900; '>%s</code><code style='color:#e60000; '>!</code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>useragent_ip</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code></pre>
+<!-- END EXAMPLE CODE -->
+
+</li>
+<li>
+    <code>
+    <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#gaa2f8412c400197338ec509f4a45e4579">ap_set_content_type</a>(request_req *r, const char *type)</code>: <br/>
+    Sets the content type of the output you are sending.
+    
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'><code style='color:#2e8800; '><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#gaa2f8412c400197338ec509f4a45e4579">ap_set_content_type</a></code><code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>text/plain</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code> <code style='color:#c34e00; '>/* force a raw text output */</code></pre>
+<!-- END EXAMPLE CODE -->
+
+</li>
+
+
+</ul>
+</section>
+
+<section id="memory"><title>Memory management</title>
+<p>
+Managing your resources in Apache is quite easy, thanks to the memory pool system. In essence, 
+each server, connection and request have their own memory pool that gets cleaned up when its 
+scope ends, e.g. when a request is done or when a server process shuts down. All your module 
+needs to do is latch onto this memory pool, and you won't have to worry about having to clean 
+up after yourself - pretty neat, huh?</p>
+
+<p>
+In our module, we will primarilly be allocating memory for each request, so it's appropriate to 
+use the <code><code style='color:#008833'>r-&gt;pool</code></code> reference when creating new objects. A few of the functions for 
+allocating memory within a pool are:
+<ul>
+<li><code>void* <a href="http://apr.apache.org/docs/apr/0.9/group__apr__pools.html#g85f1e193c31d109affda72f9a92c6915">apr_palloc</a>(
+apr_pool_t *p, apr_size_t size)</code>: Allocates <code>size</code> number of bytes in the pool for you</li>
+<li><code>void* <a href="http://apr.apache.org/docs/apr/0.9/group__apr__pools.html#gf61c098ad258069d64cdf8c0a9369f9e">apr_pcalloc</a>(
+apr_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>
+<li><code>char* <a href="http://apr.apache.org/docs/apr/0.9/group__apr__strings.html#gbc79e99ff19abbd7cfd18308c5f85d47">apr_pstrdup</a>(
+apr_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>
+</ul>
+Let's put these functions into an example handler:<br/>
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#400000; font-weight:bold; '>static</code> <code style='color:#400000; font-weight:bold; '>int</code> example_handler<code style='color:#806030; '>(</code>request_rec <code style='color:#806030; '>*</code>r<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code><code style='color:#806030; '>*</code> original <code style='color:#806030; '>=</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>You can't edit this!</code><code style='color:#800000; '>"</code><code style='color:#806030; '>;</code>
+    <code style='color:#c34e00; '>/* Allocate space for 10 integer values and set them all to zero. */</code>
+    <code style='color:#400000; font-weight:bold; '>int</code><code style='color:#806030; '>*</code> integers <code style='color:#806030; '>=</code> apr_pcalloc<code style='color:#806030; '>(</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>pool</code><code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>sizeof</code><code style='color:#806030; '>(</code><code style='color:#400000; font-weight:bold; '>int</code><code style='color:#806030; '>)</code><code style='color:#806030; '>*</code><code style='color:#c00000; '>10</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code> 
+    
+    <code style='color:#c34e00; '>/* Create a copy of the 'original' variable that we can edit. */</code>
+    <code style='color:#400000; font-weight:bold; '>char</code><code style='color:#806030; '>*</code> copy <code style='color:#806030; '>=</code> apr_pstrdup<code style='color:#806030; '>(</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>pool</code><code style='color:#806030; '>,</code> original<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>return</code> OK<code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+This is all well and good for our module, which won't need any pre-initialized variables or structures. 
+However, if we wanted to initialize something early on, before the requests come rolling in, we could 
+simply add a call to a function in our <code>register_hooks</code> function to sort it out:
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#400000; font-weight:bold; '>static</code> <code style='color:#400000; font-weight:bold; '>void</code> register_hooks<code style='color:#806030; '>(</code>apr_pool_t <code style='color:#806030; '>*</code>pool<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#c34e00; '>/* Call a function that initializes some stuff */</code>
+    <code style='color:#800040; '>example_init_function</code><code style='color:#806030; '>(</code>pool<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    <code style='color:#c34e00; '>/* Create a hook in the request handler, so we get called when a request arrives */</code>
+    <code style='color:#800040; '>ap_hook_handler</code><code style='color:#806030; '>(</code>example_handler<code style='color:#806030; '>,</code> <code style='color:#7f0055; font-weight:bold; '>NULL</code><code style='color:#806030; '>,</code> <code style='color:#7f0055; font-weight:bold; '>NULL</code><code style='color:#806030; '>,</code> APR_HOOK_LAST<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+In this, pre-request initialization function, we would not be using the same pool as we did when 
+allocating resources for request-based functions. Instead, we would use the pool given to us by 
+Apache for allocating memory on a per-process based level.
+
+</p>
+</section>
+
+<section id="parsing"><title>Parsing request data</title>
+<p>
+In our example module, we would like to add a feature, that checks which type of digest, MD5 or SHA1 
+the client would like to see. This could be solved by adding a query string to the request. A query 
+string is typically comprised of several keys and values put together in a string, for instance 
+<code>valueA=yes&amp;valueB=no&amp;valueC=maybe</code>. It is up to the module itself to parse these 
+and get the data it requires. In our example, we'll be looking for a key called <code>digest</code>, 
+and if set to <code>md5</code>, we'll produce an MD5 digest, otherwise we'll produce a SHA1 digest.
+</p>
+<p>
+Since the introduction of Apache 2.4, parsing request data from GET and POST requests have never 
+been easier. All we require to parse both GET and POST data is four simple lines: 
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__apr__tables.html#gad7ea82d6608a4a633fc3775694ab71e4">apr_table_t</a> *GET;
+<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/structapr__array__header__t.html">apr_array_header_t</a> *POST;
+
+<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__SCRIPT.html#gaed25877b529623a4d8f99f819ba1b7bd">ap_args_to_table</a>(r, &amp;GET);
+<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__DAEMON.html#ga9d426b6382b49754d4f87c55f65af202">ap_parse_form_data</a>(r, <code style='color:#7f0055; font-weight:bold; '>NULL</code>, &amp;POST, -1, 8192);
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+In our specific example module, we're looking for the <code>digest</code> value from the query string, 
+which now resides inside a table called <code>GET</code>. To extract this value, we need only perform 
+a simple operation:<br/>
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#c34e00; '>/* Get the "digest" key from the query string, if any. */</code>
+<code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code><code style='color:#806030; '> *</code>digestType <code style='color:#806030; '>=</code> <a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__apr__tables.html#ga4db13e3915c6b9a3142b175d4c15d915">apr_table_get</a><code style='color:#806030; '>(</code>GET<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>digest</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+
+<code style='color:#c34e00; '>/* If no key was returned, we will set a default value instead. */</code>
+<code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>digestType<code style='color:#806030; '>)</code> digestType <code style='color:#806030; '>=</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>sha1</code><code style='color:#800000; '>"</code><code style='color:#806030; '>;</code>
+
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+The structures used for the POST and GET data are not exactly the same, so if we were to fetch a value from 
+POST data instead of the query string, we would 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.
+</p>
+</section>
+
+<section id="advanced_handler"><title>Making an advanced handler</title>
+Now that we have learned how to parse form data and manage our resources, we can move on to creating an advanced 
+version of our module, that spits out the MD5 or SHA1 digest of files:<br/>
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#400000; font-weight:bold; '>static</code> <code style='color:#400000; font-weight:bold; '>int</code> example_handler<code style='color:#806030; '>(</code>request_rec <code style='color:#806030; '>*</code>r<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#400000; font-weight:bold; '>int</code> rc<code style='color:#806030; '>,</code> exists<code style='color:#806030; '>;</code>
+    apr_finfo_t finfo<code style='color:#806030; '>;</code>
+    apr_file_t<code style='color:#806030; '> *</code>file<code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>char</code> <code style='color:#806030; '>*</code>filename<code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>char</code> buffer<code style='color:#806030; '>[</code><code style='color:#c00000; '>256</code><code style='color:#806030; '>]</code><code style='color:#806030; '>;</code>
+    apr_size_t readBytes<code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>int</code> n<code style='color:#806030; '>;</code>
+    apr_table_t<code style='color:#806030; '> *</code>GET<code style='color:#806030; '>;</code>
+    apr_array_header_t<code style='color:#806030; '> *</code>POST<code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code><code style='color:#806030; '> *</code>digestType<code style='color:#806030; '>;</code>
+    
+    
+    <code style='color:#c34e00; '>/* Check that the "example-handler" handler is being called. */</code>
+    <code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>handler</code> <code style='color:#806030; '>|</code><code style='color:#806030; '>|</code> <code style='color:#800040; '>strcmp</code><code style='color:#806030; '>(</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>handler</code><code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>example-handler</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>)</code> <code style='color:#400000; font-weight:bold; '>return</code> <code style='color:#806030; '>(</code>DECLINED<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    
+    <code style='color:#c34e00; '>/* Figure out which file is being requested by removing the .sum from it */</code>
+    filename <code style='color:#806030; '>=</code> apr_pstrdup<code style='color:#806030; '>(</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>pool</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>filename</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    filename<code style='color:#806030; '>[</code><code style='color:#800040; '>strlen</code><code style='color:#806030; '>(</code>filename<code style='color:#806030; '>)</code><code style='color:#806030; '>-</code><code style='color:#c00000; '>4</code><code style='color:#806030; '>]</code> <code style='color:#806030; '>=</code> <code style='color:#c00000; '>0</code><code style='color:#806030; '>;</code> <code style='color:#c34e00; '>/* Cut off the last 4 characters. */</code>
+    
+    <code style='color:#c34e00; '>/* Figure out if the file we request a sum on exists and isn't a directory */</code>
+    rc <code style='color:#806030; '>=</code> apr_stat<code style='color:#806030; '>(</code><code style='color:#806030; '>&amp;</code>finfo<code style='color:#806030; '>,</code> filename<code style='color:#806030; '>,</code> APR_FINFO_MIN<code style='color:#806030; '>,</code> r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>pool</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code>rc <code style='color:#806030; '>=</code><code style='color:#806030; '>=</code> APR_SUCCESS<code style='color:#806030; '>)</code> <code style='color:#806030; '>{</code>
+        exists <code style='color:#806030; '>=</code>
+        <code style='color:#806030; '>(</code>
+            <code style='color:#806030; '>(</code>finfo<code style='color:#806030; '>.</code>filetype <code style='color:#806030; '>!</code><code style='color:#806030; '>=</code> APR_NOFILE<code style='color:#806030; '>)</code>
+        <code style='color:#806030; '>&amp;</code><code style='color:#806030; '>&amp;</code>  <code style='color:#806030; '>!</code><code style='color:#806030; '>(</code>finfo<code style='color:#806030; '>.</code>filetype <code style='color:#806030; '>&amp;</code> APR_DIR<code style='color:#806030; '>)</code>
+        <code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+        <code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>exists<code style='color:#806030; '>)</code> <code style='color:#400000; font-weight:bold; '>return</code> HTTP_NOT_FOUND<code style='color:#806030; '>;</code> <code style='color:#c34e00; '>/* Return a 404 if not found. */</code>
+    <code style='color:#806030; '>}</code>
+    <code style='color:#c34e00; '>/* If apr_stat failed, we're probably not allowed to check this file. */</code>
+    <code style='color:#400000; font-weight:bold; '>else</code> <code style='color:#400000; font-weight:bold; '>return</code> HTTP_FORBIDDEN<code style='color:#806030; '>;</code>
+    
+    <code style='color:#c34e00; '>/* Parse the GET and, optionally, the POST data sent to us */</code>
+    
+    ap_args_to_table<code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#806030; '>&amp;</code>GET<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    ap_parse_form_data<code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>,</code> <code style='color:#806030; '>&amp;</code>POST<code style='color:#806030; '>,</code> <code style='color:#806030; '>-</code><code style='color:#c00000; '>1</code><code style='color:#806030; '>,</code> <code style='color:#c00000; '>8192</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    
+    <code style='color:#c34e00; '>/* Set the appropriate content type */</code>
+    ap_set_content_type<code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>text/html</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    
+    <code style='color:#c34e00; '>/* Print a title and some general information */</code>
+    ap_rprintf<code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>&lt;h2>Information on </code><code style='color:#0f6900; '>%s</code><code style='color:#e60000; '>:&lt;/h2></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> filename<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    ap_rprintf<code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>&lt;b>Size:&lt;/b> </code><code style='color:#0f6900; '>%u</code><code style='color:#e60000; '> bytes&lt;br/></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> finfo<code style='color:#806030; '>.</code>size<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    
+    <code style='color:#c34e00; '>/* Get the digest type the client wants to see */</code>
+    digestType <code style='color:#806030; '>=</code> apr_table_get<code style='color:#806030; '>(</code>GET<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>digest</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>digestType<code style='color:#806030; '>)</code> digestType <code style='color:#806030; '>=</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>MD5</code><code style='color:#800000; '>"</code><code style='color:#806030; '>;</code>
+    
+    
+    rc <code style='color:#806030; '>=</code> apr_file_open<code style='color:#806030; '>(</code><code style='color:#806030; '>&amp;</code>file<code style='color:#806030; '>,</code> filename<code style='color:#806030; '>,</code> APR_READ<code style='color:#806030; '>,</code> APR_OS_DEFAULT<code style='color:#806030; '>,</code> r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>pool</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code>rc <code style='color:#806030; '>=</code><code style='color:#806030; '>=</code> APR_SUCCESS<code style='color:#806030; '>)</code> <code style='color:#806030; '>{</code>
+        
+        <code style='color:#c34e00; '>/* Are we trying to calculate the MD5 or the SHA1 digest? */</code>
+        <code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>strcasecmp<code style='color:#806030; '>(</code>digestType<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>md5</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>)</code> <code style='color:#806030; '>{</code>
+            <code style='color:#c34e00; '>/* Calculate the MD5 sum of the file */</code>
+            <code style='color:#400000; font-weight:bold; '>union</code> <code style='color:#806030; '>{</code>
+                <code style='color:#400000; font-weight:bold; '>char</code>      chr<code style='color:#806030; '>[</code><code style='color:#c00000; '>16</code><code style='color:#806030; '>]</code><code style='color:#806030; '>;</code>
+                uint32_t  num<code style='color:#806030; '>[</code><code style='color:#c00000; '>4</code><code style='color:#806030; '>]</code><code style='color:#806030; '>;</code>
+            <code style='color:#806030; '>}</code> digest<code style='color:#806030; '>;</code>
+            apr_md5_ctx_t md5<code style='color:#806030; '>;</code>
+            apr_md5_init<code style='color:#806030; '>(</code><code style='color:#806030; '>&amp;</code>md5<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            readBytes <code style='color:#806030; '>=</code> <code style='color:#c00000; '>256</code><code style='color:#806030; '>;</code>
+            <code style='color:#400000; font-weight:bold; '>while</code> <code style='color:#806030; '>(</code> apr_file_read<code style='color:#806030; '>(</code>file<code style='color:#806030; '>,</code> buffer<code style='color:#806030; '>,</code> <code style='color:#806030; '>&amp;</code>readBytes<code style='color:#806030; '>)</code> <code style='color:#806030; '>=</code><code style='color:#806030; '>=</code> APR_SUCCESS <code style='color:#806030; '>)</code> <code style='color:#806030; '>{</code>
+                apr_md5_update<code style='color:#806030; '>(</code><code style='color:#806030; '>&amp;</code>md5<code style='color:#806030; '>,</code> buffer<code style='color:#806030; '>,</code> readBytes<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            <code style='color:#806030; '>}</code>
+            apr_md5_final<code style='color:#806030; '>(</code>digest<code style='color:#806030; '>.</code>chr<code style='color:#806030; '>,</code> <code style='color:#806030; '>&amp;</code>md5<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            
+            <code style='color:#c34e00; '>/* Print out the MD5 digest */</code>
+            ap_rputs<code style='color:#806030; '>(</code><code style='color:#800000; '>"</code><code style='color:#e60000; '>&lt;b>MD5: &lt;/b>&lt;code></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            <code style='color:#400000; font-weight:bold; '>for</code> <code style='color:#806030; '>(</code>n <code style='color:#806030; '>=</code> <code style='color:#c00000; '>0</code><code style='color:#806030; '>;</code> n <code style='color:#806030; '>&lt;</code> APR_MD5_DIGESTSIZE<code style='color:#806030; '>/</code><code style='color:#c00000; '>4</code><code style='color:#806030; '>;</code> n<code style='color:#806030; '>+</code><code style='color:#806030; '>+</code><code style='color:#806030; '>)</code> <code style='color:#806030; '>{</code>
+                ap_rprintf<code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#0f6900; '>%08x</code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> digest<code style='color:#806030; '>.</code>num<code style='color:#806030; '>[</code>n<code style='color:#806030; '>]</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            <code style='color:#806030; '>}</code>
+            ap_rputs<code style='color:#806030; '>(</code><code style='color:#800000; '>"</code><code style='color:#e60000; '>&lt;/code></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            <code style='color:#c34e00; '>/* Print a link to the SHA1 version */</code>
+            ap_rputs<code style='color:#806030; '>(</code><code style='color:#800000; '>"</code><code style='color:#e60000; '>&lt;br/>&lt;a href='?digest=sha1'>View the SHA1 hash instead&lt;/a></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+        <code style='color:#806030; '>}</code>
+        <code style='color:#400000; font-weight:bold; '>else</code> <code style='color:#806030; '>{</code>
+            <code style='color:#c34e00; '>/* Calculate the SHA1 sum of the file */</code>
+            <code style='color:#400000; font-weight:bold; '>union</code> <code style='color:#806030; '>{</code>
+                <code style='color:#400000; font-weight:bold; '>char</code>      chr<code style='color:#806030; '>[</code><code style='color:#c00000; '>20</code><code style='color:#806030; '>]</code><code style='color:#806030; '>;</code>
+                uint32_t  num<code style='color:#806030; '>[</code><code style='color:#c00000; '>5</code><code style='color:#806030; '>]</code><code style='color:#806030; '>;</code>
+            <code style='color:#806030; '>}</code> digest<code style='color:#806030; '>;</code>
+            apr_sha1_ctx_t sha1<code style='color:#806030; '>;</code>
+            apr_sha1_init<code style='color:#806030; '>(</code><code style='color:#806030; '>&amp;</code>sha1<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            readBytes <code style='color:#806030; '>=</code> <code style='color:#c00000; '>256</code><code style='color:#806030; '>;</code>
+            <code style='color:#400000; font-weight:bold; '>while</code> <code style='color:#806030; '>(</code> apr_file_read<code style='color:#806030; '>(</code>file<code style='color:#806030; '>,</code> buffer<code style='color:#806030; '>,</code> <code style='color:#806030; '>&amp;</code>readBytes<code style='color:#806030; '>)</code> <code style='color:#806030; '>=</code><code style='color:#806030; '>=</code> APR_SUCCESS <code style='color:#806030; '>)</code> <code style='color:#806030; '>{</code>
+                apr_sha1_update<code style='color:#806030; '>(</code><code style='color:#806030; '>&amp;</code>sha1<code style='color:#806030; '>,</code> buffer<code style='color:#806030; '>,</code> readBytes<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            <code style='color:#806030; '>}</code>
+            apr_sha1_final<code style='color:#806030; '>(</code>digest<code style='color:#806030; '>.</code>chr<code style='color:#806030; '>,</code> <code style='color:#806030; '>&amp;</code>sha1<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            
+            <code style='color:#c34e00; '>/* Print out the SHA1 digest */</code>
+            ap_rputs<code style='color:#806030; '>(</code><code style='color:#800000; '>"</code><code style='color:#e60000; '>&lt;b>SHA1: &lt;/b>&lt;code></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            <code style='color:#400000; font-weight:bold; '>for</code> <code style='color:#806030; '>(</code>n <code style='color:#806030; '>=</code> <code style='color:#c00000; '>0</code><code style='color:#806030; '>;</code> n <code style='color:#806030; '>&lt;</code> APR_SHA1_DIGESTSIZE<code style='color:#806030; '>/</code><code style='color:#c00000; '>4</code><code style='color:#806030; '>;</code> n<code style='color:#806030; '>+</code><code style='color:#806030; '>+</code><code style='color:#806030; '>)</code> <code style='color:#806030; '>{</code>
+                ap_rprintf<code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#0f6900; '>%08x</code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> digest<code style='color:#806030; '>.</code>num<code style='color:#806030; '>[</code>n<code style='color:#806030; '>]</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            <code style='color:#806030; '>}</code>
+            ap_rputs<code style='color:#806030; '>(</code><code style='color:#800000; '>"</code><code style='color:#e60000; '>&lt;/code></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+            
+            <code style='color:#c34e00; '>/* Print a link to the MD5 version */</code>
+            ap_rputs<code style='color:#806030; '>(</code><code style='color:#800000; '>"</code><code style='color:#e60000; '>&lt;br/>&lt;a href='?digest=md5'>View the MD5 hash instead&lt;/a></code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> r<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+        <code style='color:#806030; '>}</code>
+        apr_file_close<code style='color:#806030; '>(</code>file<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+        
+    <code style='color:#806030; '>}</code>
+    
+    
+    
+    <code style='color:#c34e00; '>/* Let Apache know that we responded to this request. */</code>
+    <code style='color:#400000; font-weight:bold; '>return</code> OK<code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+This version in its entirity can be found here: <a href="mod_example_2.c">mod_example_2.c</a>.
+</section>
+
+</section>
+
+<section id="configuration"><title>Adding configuration options</title>
+<p>
+In this next segment of this document, we will turn our eyes away from the digest module and create a new 
+example module, whose only function is to write out its own configuration. The purpose of this is to 
+examine how Apache works with configuration, and what happens when you start writing advanced configurations 
+for your modules.
+</p>
+<section id="config_intro"><title>An introduction to configuration directives</title>
+If you are reading this, then you probably already know what a configuration directive is. Simply put, 
+a directive is a way of telling an individual module (or a set of modules) how to behave, such as these 
+directives control how <code>mod_rewrite</code> works:
+<example><pre>
+RewriteEngine On
+RewriteCond %{REQUEST_URI} ^/foo/bar
+RewriteRule ^/foo/bar/(.*)$ /foobar?page=$1
+</pre></example>
+Each of these configuration directives are handled by a separate function, that parses the parameters given 
+and sets up a configuration accordingly.
+</section>
+<section id="config_simple"><title>Making an example configuration</title>
+To begin with, we'll create a basic configuration in C-space:
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#400000; font-weight:bold; '>typedef</code> <code style='color:#400000; font-weight:bold; '>struct</code> <code style='color:#806030; '>{</code>
+    <code style='color:#400000; font-weight:bold; '>int</code>         enabled<code style='color:#806030; '>;</code>      <code style='color:#c34e00; '>/* Enable or disable our module */</code>
+    <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code> <code style='color:#806030; '>*</code>path<code style='color:#806030; '>;</code>         <code style='color:#c34e00; '>/* Some path to...something */</code>
+    <code style='color:#400000; font-weight:bold; '>int</code>         typeOfAction<code style='color:#806030; '>;</code> <code style='color:#c34e00; '>/* 1 means action A, 2 means action B and so on */</code>
+<code style='color:#806030; '>}</code> example_config<code style='color:#806030; '>;</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+Now, let's put this into perspective by creating a very small module that just prints out a hard-coded 
+configuration. You'll notice that we use the <code>register_hooks</code> function for initializing the 
+configuration values to their defaults:
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#400000; font-weight:bold; '>typedef</code> <code style='color:#400000; font-weight:bold; '>struct</code> <code style='color:#806030; '>{</code>
+    <code style='color:#400000; font-weight:bold; '>int</code>         enabled<code style='color:#806030; '>;</code>      <code style='color:#c34e00; '>/* Enable or disable our module */</code>
+    <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code> <code style='color:#806030; '>*</code>path<code style='color:#806030; '>;</code>         <code style='color:#c34e00; '>/* Some path to...something */</code>
+    <code style='color:#400000; font-weight:bold; '>int</code>         typeOfAction<code style='color:#806030; '>;</code> <code style='color:#c34e00; '>/* 1 means action A, 2 means action B and so on */</code>
+<code style='color:#806030; '>}</code> example_config<code style='color:#806030; '>;</code>
+
+<code style='color:#400000; font-weight:bold; '>static</code> example_config config<code style='color:#806030; '>;</code>
+
+<code style='color:#400000; font-weight:bold; '>static</code> <code style='color:#400000; font-weight:bold; '>int</code> example_handler<code style='color:#806030; '>(</code>request_rec <code style='color:#806030; '>*</code>r<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#400000; font-weight:bold; '>if</code> <code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>handler</code> <code style='color:#806030; '>|</code><code style='color:#806030; '>|</code> <code style='color:#800040; '>strcmp</code><code style='color:#806030; '>(</code>r<code style='color:#806030; '>-</code><code style='color:#806030; '>></code><code style='color:#008833'>handler</code><code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>example-handler</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>)</code> <code style='color:#400000; font-weight:bold; '>return</code><code style='color:#806030; '>(</code>DECLINED<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    ap_set_content_type<code style='color:#806030; '>(</code>r<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>text/plain</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    ap_rprintf<code style='color:#806030; '>(r, </code><code style='color:#800000; '>"</code><code style='color:#e60000; '>Enabled: </code><code style='color:#0f6900; '>%u</code><code style='color:#0f6900; '>\n</code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> config<code style='color:#806030; '>.</code>enabled<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    ap_rprintf<code style='color:#806030; '>(r, </code><code style='color:#800000; '>"</code><code style='color:#e60000; '>Path: </code><code style='color:#0f6900; '>%s</code><code style='color:#0f6900; '>\n</code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> config<code style='color:#806030; '>.</code>path<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    ap_rprintf<code style='color:#806030; '>(r, </code><code style='color:#800000; '>"</code><code style='color:#e60000; '>TypeOfAction: </code><code style='color:#0f6900; '>%x</code><code style='color:#0f6900; '>\n</code><code style='color:#800000; '>"</code><code style='color:#806030; '>,</code> config<code style='color:#806030; '>.</code>typeOfAction<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>return</code> OK<code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+
+<code style='color:#400000; font-weight:bold; '>static</code> <code style='color:#400000; font-weight:bold; '>void</code> register_hooks<code style='color:#806030; '>(</code>apr_pool_t <code style='color:#806030; '>*</code>pool<code style='color:#806030; '>)</code> 
+<code style='color:#806030; '>{</code>
+    config<code style='color:#806030; '>.</code>enabled <code style='color:#806030; '>=</code> <code style='color:#c00000; '>1</code><code style='color:#806030; '>;</code>
+    config<code style='color:#806030; '>.</code>path <code style='color:#806030; '>=</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>/foo/bar</code><code style='color:#800000; '>"</code><code style='color:#806030; '>;</code>
+    config<code style='color:#806030; '>.</code>typeOfAction <code style='color:#806030; '>=</code> <code style='color:#c00000; '>0x00</code><code style='color:#806030; '>;</code>
+    ap_hook_handler<code style='color:#806030; '>(</code>example_handler<code style='color:#806030; '>,</code> <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>,</code> <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>,</code> APR_HOOK_LAST<code style='color:#806030; '>)</code><code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+
+<code style='color:#c34e00; '>/* Define our module as an entity and assign a function for registering hooks  */</code>
+
+module AP_MODULE_DECLARE_DATA   example_module <code style='color:#806030; '>=</code>
+<code style='color:#806030; '>{</code>
+    STANDARD20_MODULE_STUFF<code style='color:#806030; '>,</code>
+    <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>,</code>            <code style='color:#c34e00; '>/* Per-directory configuration handler */</code>
+    <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>,</code>            <code style='color:#c34e00; '>/* Merge handler for per-directory configurations */</code>
+    <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>,</code>            <code style='color:#c34e00; '>/* Per-server configuration handler */</code>
+    <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>,</code>            <code style='color:#c34e00; '>/* Merge handler for per-server configurations */</code>
+    <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>,</code>            <code style='color:#c34e00; '>/* Any directives we may have for httpd */</code>
+    register_hooks   <code style='color:#c34e00; '>/* Our hook registering function */</code>
+<code style='color:#806030; '>}</code><code style='color:#806030; '>;</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+So far so good. To access our new handler, we could add the following to our configuration:
+<example><pre>
+&lt;Location /example&gt;
+    SetHandler example-handler
+&lt;/Location&gt;
+</pre></example>
+When we visit, we'll see our current configuration being spit out by our module. 
+</section>
+
+<section id="register_directive"><title>Registering directives with Apache</title>
+What if we want to change our configuration, not by hard-coding new values into the module, 
+but by using either the httpd.conf file or possibly a .htaccess file? It's time to let Apache 
+know that we want this to be possible. To do so, we must first change our <em>name tag</em> 
+to include a reference to the configuration directives we want to register with Apache:
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+module AP_MODULE_DECLARE_DATA   example_module =
+{
+    STANDARD20_MODULE_STUFF,
+    <code style='color:#7f0055; font-weight:bold; '>NULL</code>,               <code style='color:#c34e00; '>/* Per-directory configuration handler */</code>
+    <code style='color:#7f0055; font-weight:bold; '>NULL</code>,               <code style='color:#c34e00; '>/* Merge handler for per-directory configurations */</code>
+    <code style='color:#7f0055; font-weight:bold; '>NULL</code>,               <code style='color:#c34e00; '>/* Per-server configuration handler */</code>
+    <code style='color:#7f0055; font-weight:bold; '>NULL</code>,               <code style='color:#c34e00; '>/* Merge handler for per-server configurations */</code>
+    example_directives, <code style='color:#c34e00; '>/* Any directives we may have for httpd */</code>
+    register_hooks      <code style='color:#c34e00; '>/* Our hook registering function */</code>
+};
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+This will tell Apache that we are now accepting directives from the configuration files, and that the 
+structure called <code>example_directives</code> holds information on what our directives are and how 
+they work. Since we have three different variables in our module configuration, we will add a structure 
+with three directives and a NULL at the end:
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+static const command_rec        example_directives[] =
+{
+    <code style='color:#2e8800; '><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__CONFIG.html#ga07c7d22ae17805e61204463326cf9c34">AP_INIT_TAKE1</a></code>("exampleEnabled", example_set_enabled, <code style='color:#7f0055; font-weight:bold; '>NULL</code>, RSRC_CONF, "Enable or disable mod_example"),
+    <code style='color:#2e8800; '><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__CONFIG.html#ga07c7d22ae17805e61204463326cf9c34">AP_INIT_TAKE1</a></code>("examplePath", example_set_path, <code style='color:#7f0055; font-weight:bold; '>NULL</code>, RSRC_CONF, "The path to whatever"),
+    <code style='color:#2e8800; '><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__CONFIG.html#gafaec43534fcf200f37d9fecbf9247c21">AP_INIT_TAKE2</a></code>("exampleAction", example_set_action, <code style='color:#7f0055; font-weight:bold; '>NULL</code>, RSRC_CONF, "Special action value!"),
+    { <code style='color:#7f0055; font-weight:bold; '>NULL</code> }
+};
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+<img src="../images/build_a_mod_4.png" border="1"/><br/>
+<p>
+As you can see, each directive needs at least 5 parameters set:
+<ol>
+<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 Apache that this directive takes one and only one argument. 
+If 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 
+for more macros).</li>
+<li><code>exampleEnabled</code>: This is the name of our directive. More precisely, it is what the user must put in his/her 
+configuration in order to invoke a configuration change in our module.</li>
+<li><code>example_set_enabled</code>: This is a reference to a C function that parses the directive and sets the configuration 
+accordingly. We will discuss how to make this in the following paragraph.</li>
+<li><code>RSRC_CONF</code>: This tells Apache where the directive is permissable. We'll go into details on this value in the 
+later chapters, but for now, <code>RSRC_CONF</code> means that Apache will only accept these directives in a server context.</li>
+<li><code>"Enable or disable...."</code>: This is simply a brief description of what the directive does.</li>
+</ol>
+(<em>The "missing" parameter in our definition, which is usually set to <code>NULL</code>, is an optional function that can be 
+run after the initial function to parse the arguments have been run. This is usually omitted, as the function for verifying 
+arguments might as well be used to set them.</em>)
+</p>
+</section>
+<section id="directive_handler"><title>The directive handler function</title>
+<p>
+Now that we've told Apache to expect some directives for our module, it's time to make a few functions for handling these. What 
+Apache reads in the configuration file(s) is text, and so naturally, what it passes along to our directive handler is one or 
+more strings, that we ourselves need to recognize and act upon. You'll notice, that since we set our <code>exampleAction</code> 
+directive to accept two arguments, its C function also has an additional parameter defined:<br/>
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#c34e00; '>/* Handler for the "exambleEnabled" directive */</code>
+<code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code><code style='color:#806030; '> *</code>example_set_enabled<code style='color:#806030; '>(</code>cmd_parms <code style='color:#806030; '>*</code>cmd<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>void</code> <code style='color:#806030; '>*</code>cfg<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code> <code style='color:#806030; '>*</code>arg<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#400000; font-weight:bold; '>if</code><code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>strcasecmp<code style='color:#806030; '>(</code>arg<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>on</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>)</code> config<code style='color:#806030; '>.</code>enabled <code style='color:#806030; '>=</code> <code style='color:#c00000; '>1</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>else</code> config<code style='color:#806030; '>.</code>enabled <code style='color:#806030; '>=</code> <code style='color:#c00000; '>0</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>return</code> <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+
+<code style='color:#c34e00; '>/* Handler for the "examplePath" directive */</code>
+<code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code><code style='color:#806030; '> *</code>example_set_path<code style='color:#806030; '>(</code>cmd_parms <code style='color:#806030; '>*</code>cmd<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>void</code> <code style='color:#806030; '>*</code>cfg<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code> <code style='color:#806030; '>*</code>arg<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    config<code style='color:#806030; '>.</code>path <code style='color:#806030; '>=</code> arg<code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>return</code> <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+
+<code style='color:#c34e00; '>/* Handler for the "exampleAction" directive */</code>
+<code style='color:#c34e00; '>/* Let's pretend this one takes one argument (file or db), and a second (deny or allow), */</code>
+<code style='color:#c34e00; '>/* and we store it in a bit-wise manner. */</code>
+<code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code><code style='color:#806030; '> *</code>example_set_action<code style='color:#806030; '>(</code>cmd_parms <code style='color:#806030; '>*</code>cmd<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>void</code> <code style='color:#806030; '>*</code>cfg<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code> <code style='color:#806030; '>*</code>arg1<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code><code style='color:#806030; '>*</code> arg2<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#400000; font-weight:bold; '>if</code><code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>strcasecmp<code style='color:#806030; '>(</code>arg1<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>file</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>)</code> config<code style='color:#806030; '>.</code>typeOfAction <code style='color:#806030; '>=</code> <code style='color:#c00000; '>0x01</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>else</code> config<code style='color:#806030; '>.</code>typeOfAction <code style='color:#806030; '>=</code> <code style='color:#c00000; '>0x02</code><code style='color:#806030; '>;</code>
+    
+    <code style='color:#400000; font-weight:bold; '>if</code><code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>strcasecmp<code style='color:#806030; '>(</code>arg2<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>deny</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>)</code> config<code style='color:#806030; '>.</code>typeOfAction <code style='color:#806030; '>+</code><code style='color:#806030; '>=</code> <code style='color:#c00000; '>0x10</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>else</code> config<code style='color:#806030; '>.</code>typeOfAction <code style='color:#806030; '>+</code><code style='color:#806030; '>=</code> <code style='color:#c00000; '>0x20</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>return</code> <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+</pre>
+<!-- END EXAMPLE CODE -->
+
+
+</p>
+</section>
+<section id="directive_complete"><title>Putting it all together</title>
+<p>
+Now that we have our directives set up, and handlers configured for them, we can assemble our module 
+into one big file:
+
+
+<!-- BEGIN EXAMPLE CODE -->
+<pre style='color:#000000;background:#ffffef;border: 1px dashed #333; padding: 0.5em; margin: 1em 2em 1em 1em;'>
+<code style='color:#c34e00; '>/* mod_example_config_simple.c: */</code>
+<code style='color:#004a43; '>#</code><code style='color:#004a43; '>include </code><code style='color:#800000; '>&lt;</code><code style='color:#40015a; '>stdio.h</code><code style='color:#800000; '>></code>
+<code style='color:#004a43; '>#</code><code style='color:#004a43; '>include </code><code style='color:#800000; '>"</code><code style='color:#40015a; '>apr_hash.h</code><code style='color:#800000; '>"</code>
+<code style='color:#004a43; '>#</code><code style='color:#004a43; '>include </code><code style='color:#800000; '>"</code><code style='color:#40015a; '>ap_config.h</code><code style='color:#800000; '>"</code>
+<code style='color:#004a43; '>#</code><code style='color:#004a43; '>include </code><code style='color:#800000; '>"</code><code style='color:#40015a; '>ap_provider.h</code><code style='color:#800000; '>"</code>
+<code style='color:#004a43; '>#</code><code style='color:#004a43; '>include </code><code style='color:#800000; '>"</code><code style='color:#40015a; '>httpd.h</code><code style='color:#800000; '>"</code>
+<code style='color:#004a43; '>#</code><code style='color:#004a43; '>include </code><code style='color:#800000; '>"</code><code style='color:#40015a; '>http_core.h</code><code style='color:#800000; '>"</code>
+<code style='color:#004a43; '>#</code><code style='color:#004a43; '>include </code><code style='color:#800000; '>"</code><code style='color:#40015a; '>http_config.h</code><code style='color:#800000; '>"</code>
+<code style='color:#004a43; '>#</code><code style='color:#004a43; '>include </code><code style='color:#800000; '>"</code><code style='color:#40015a; '>http_log.h</code><code style='color:#800000; '>"</code>
+<code style='color:#004a43; '>#</code><code style='color:#004a43; '>include </code><code style='color:#800000; '>"</code><code style='color:#40015a; '>http_protocol.h</code><code style='color:#800000; '>"</code>
+<code style='color:#004a43; '>#</code><code style='color:#004a43; '>include </code><code style='color:#800000; '>"</code><code style='color:#40015a; '>http_request.h</code><code style='color:#800000; '>"</code>
+
+<code style='color:#c34e00; '>/*</code>
+<code style='color:#c34e00; '>&#xa0;==============================================================================</code>
+<code style='color:#c34e00; '>&#xa0;Our configuration prototype and declaration:</code>
+<code style='color:#c34e00; '>&#xa0;==============================================================================</code>
+<code style='color:#c34e00; '>&#xa0;*/</code>
+<code style='color:#400000; font-weight:bold; '>typedef</code> <code style='color:#400000; font-weight:bold; '>struct</code> <code style='color:#806030; '>{</code>
+    <code style='color:#400000; font-weight:bold; '>int</code>         enabled<code style='color:#806030; '>;</code>      <code style='color:#c34e00; '>/* Enable or disable our module */</code>
+    <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code> <code style='color:#806030; '>*</code>path<code style='color:#806030; '>;</code>         <code style='color:#c34e00; '>/* Some path to...something */</code>
+    <code style='color:#400000; font-weight:bold; '>int</code>         typeOfAction<code style='color:#806030; '>;</code> <code style='color:#c34e00; '>/* 1 means action A, 2 means action B and so on */</code>
+<code style='color:#806030; '>}</code> example_config<code style='color:#806030; '>;</code>
+
+<code style='color:#400000; font-weight:bold; '>static</code> example_config config<code style='color:#806030; '>;</code>
+
+<code style='color:#c34e00; '>/*</code>
+<code style='color:#c34e00; '>&#xa0;==============================================================================</code>
+<code style='color:#c34e00; '>&#xa0;Our directive handlers:</code>
+<code style='color:#c34e00; '>&#xa0;==============================================================================</code>
+<code style='color:#c34e00; '>&#xa0;*/</code>
+<code style='color:#c34e00; '>/* Handler for the "exambleEnabled" directive */</code>
+<code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code><code style='color:#806030; '> *</code>example_set_enabled<code style='color:#806030; '>(</code>cmd_parms <code style='color:#806030; '>*</code>cmd<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>void</code> <code style='color:#806030; '>*</code>cfg<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code> <code style='color:#806030; '>*</code>arg<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    <code style='color:#400000; font-weight:bold; '>if</code><code style='color:#806030; '>(</code><code style='color:#806030; '>!</code>strcasecmp<code style='color:#806030; '>(</code>arg<code style='color:#806030; '>,</code> <code style='color:#800000; '>"</code><code style='color:#e60000; '>on</code><code style='color:#800000; '>"</code><code style='color:#806030; '>)</code><code style='color:#806030; '>)</code> config<code style='color:#806030; '>.</code>enabled <code style='color:#806030; '>=</code> <code style='color:#c00000; '>1</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>else</code> config<code style='color:#806030; '>.</code>enabled <code style='color:#806030; '>=</code> <code style='color:#c00000; '>0</code><code style='color:#806030; '>;</code>
+    <code style='color:#400000; font-weight:bold; '>return</code> <code style='color:#007d45; '>NULL</code><code style='color:#806030; '>;</code>
+<code style='color:#806030; '>}</code>
+
+<code style='color:#c34e00; '>/* Handler for the "examplePath" directive */</code>
+<code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code><code style='color:#806030; '> *</code>example_set_path<code style='color:#806030; '>(</code>cmd_parms <code style='color:#806030; '>*</code>cmd<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>void</code> <code style='color:#806030; '>*</code>cfg<code style='color:#806030; '>,</code> <code style='color:#400000; font-weight:bold; '>const</code> <code style='color:#400000; font-weight:bold; '>char</code> <code style='color:#806030; '>*</code>arg<code style='color:#806030; '>)</code>
+<code style='color:#806030; '>{</code>
+    config<code style='color:#806030; '>.</code>path <code style='color:#806030; '>=</code> arg<code style='color:#806030; '>;</code>

[... 695 lines stripped ...]


Mime
View raw message