modguide.xml revision 6c03aacaafb5d5b05c264dc5d1232bd66cb0e5fa
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd<?xml-stylesheet type="text/xsl" href="/style/manual.en.xsl"?>
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd<!-- $LastChangedRevision$ -->
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd Licensed to the Apache Software Foundation (ASF) under one or more
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd contributor license agreements. See the NOTICE file distributed with
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd this work for additional information regarding copyright ownership.
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd The ASF licenses this file to You under the Apache License, Version 2.0
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd (the "License"); you may not use this file except in compliance with
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd the License. You may obtain a copy of the License at
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd Unless required by applicable law or agreed to in writing, software
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd distributed under the License is distributed on an "AS IS" BASIS,
4b5981e276e93df97c34e4da05ca5cf8bbd937dand WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd See the License for the specific language governing permissions and
ad74a0524a06bfe11b7de9e3b4ce7233ab3bd3f7nd limitations under the License.
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd <title>Developing modules for the Apache HTTP Server 2.4</title>
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd<p>This document explains how you can develop modules for the Apache HTTP
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndServer 2.4</p>
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd<seealso><a href="request.html">Request Processing in Apache 2.4</a></seealso>
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd<seealso><a href="hooks.html">Apache 2.x Hook Functions</a></seealso>
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd<section id="what"><title>What we will be discussing in this document</title>
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndThis document will discuss how you can create modules for the Apache
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndHTTP Server 2.4, by exploring an example module called
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd<code>mod_example</code>. In the first part of this document, the purpose
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndof this module will be to calculate and print out various digest values for
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndexisting files on your web server, whenever we access the URL <code>
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndhttp://hostname/filename.sum</code>. For instance, if we want to know the
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndMD5 digest value of the file located at <code>
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndhttp://www.example.com/index.html</code>, we would visit <code>
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndIn the second part of this document, which deals with configuration
0853e1e2522c1ac17f697221758bcbd4781a7ff9nddirective and context awareness, we will be looking at a module that simply
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndwrite out its own configuration to the client.
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndFirst and foremost, you are expected to have a basic knowledge of how the C
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndprogramming language works. In most cases, we will try to be as pedagogical
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndas possible and link to documents describing the functions used in the
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndexamples, but there are also many cases where it is necessary to either
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndjust assume that "it works" or do some digging yourself into what the hows
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndand whys of various function calls.
08cf4a15275e4cb65a424b3a1db5410bfb51085cjimLastly, you will need to have a basic understanding of how modules are
22d5d84393d960a2027f472036f3fee15d7dbce9ndloaded and configured in the Apache HTTP Server, as well as how to get the headers for
22d5d84393d960a2027f472036f3fee15d7dbce9ndApache if you do not have them already, as these are needed for compiling
22d5d84393d960a2027f472036f3fee15d7dbce9ndnew modules.
a78048ccbdb6256da15e6b0e7e95355e480c2301nd<section id="compiling"><title>Compiling your module</title>
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndTo compile the source code we are building in this document, we will be
a78048ccbdb6256da15e6b0e7e95355e480c2301ndusing <a href="/programs/apxs.html">APXS</a>. Assuming your source file
623eebe956d9c2d6d073ed3eae855b56030b40e9noodlis called mod_example.c, compiling, installing and activating the module is
a78048ccbdb6256da15e6b0e7e95355e480c2301ndas simple as:
909ce17e2bd0faef7b1c294f2307f009793fd493ndapxs -i -a -c mod_example.c
a78048ccbdb6256da15e6b0e7e95355e480c2301nd<img src="/images/build_a_mod_3.png" alt="Module name tags"/><br/>
9649d29bb7801e0698e6a845e1a8a61534df58b3noodlEvery module starts with the same declaration, or name tag if you will,
9649d29bb7801e0698e6a845e1a8a61534df58b3noodlthat defines a module as <em>a separate entity within Apache</em>:</p>
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd<!-- BEGIN EXAMPLE CODE -->
08cf4a15275e4cb65a424b3a1db5410bfb51085cjimmodule AP_MODULE_DECLARE_DATA example_module =
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd STANDARD20_MODULE_STUFF,
8574d86b9ec3be36b7f54ed0547a0ee5d60dbd6bnd create_dir_conf, /* Per-directory configuration handler */
8574d86b9ec3be36b7f54ed0547a0ee5d60dbd6bnd merge_dir_conf, /* Merge handler for per-directory configurations */
8574d86b9ec3be36b7f54ed0547a0ee5d60dbd6bnd create_svr_conf, /* Per-server configuration handler */
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd merge_svr_conf, /* Merge handler for per-server configurations */
8574d86b9ec3be36b7f54ed0547a0ee5d60dbd6bnd directives, /* Any directives we may have for httpd */
8574d86b9ec3be36b7f54ed0547a0ee5d60dbd6bnd register_hooks /* Our hook registering function */
e8b603fa9ccf7b17b11b42df6d8916fd97c2331dnd</highlight>
8574d86b9ec3be36b7f54ed0547a0ee5d60dbd6bnd<!-- END EXAMPLE CODE -->
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndThis bit of code lets the server know that we have now registered a new module
611049e38bfbaeb173d2d7fab2e44a48753436a1ndin the system, and that its name is <code>example_module</code>. The name
8574d86b9ec3be36b7f54ed0547a0ee5d60dbd6bndof the module is used primarily for two things:<br/>
a78048ccbdb6256da15e6b0e7e95355e480c2301nd<li>Letting the server know how to load the module using the LoadModule</li>
6aadbc6fd703e73d1d419e9f06b84a4338c898f1maczniak<li>Setting up a namespace for the module to use in configurations</li>
a78048ccbdb6256da15e6b0e7e95355e480c2301ndFor now, we're only concerned with the first purpose of the module name,
a78048ccbdb6256da15e6b0e7e95355e480c2301ndwhich comes into play when we need to load the module:
4b5981e276e93df97c34e4da05ca5cf8bbd937dand</highlight>
f21bea4c0f58e17aa1d9a0fac2c219852f89944amaczniakIn essence, this tells the server to open up <code>mod_example.so</code> and look for a module
6aadbc6fd703e73d1d419e9f06b84a4338c898f1maczniakWithin this name tag of ours is also a bunch of references to how we would
d2b809e5d72658bff23819d8b77f20e4939af541ndlike to handle things: Which directives do we respond to in a configuration
a78048ccbdb6256da15e6b0e7e95355e480c2301ndfile or .htaccess, how do we operate within specific contexts, and what
cd6c8de3bedcc401ee230159b0439fa20f44488etakashihandlers are we interested in registering with the Apache HTTP service. We'll
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndreturn to all these elements later in this document.
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd<section id="hooking"><title>Getting started: Hooking into the server</title>
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd<section id="hook_intro"><title>An introduction to hooks</title>
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndWhen handling requests in Apache HTTP Server 2.4, the first thing you will need to do is
27d778df0b517e1578f907d2e51eb961cd8ee5fbjimcreate a hook into the request handling process. A hook is essentially a
27d778df0b517e1578f907d2e51eb961cd8ee5fbjimmessage telling the server that you are willing to either serve or at least
27d778df0b517e1578f907d2e51eb961cd8ee5fbjimtake a glance at certain requests given by clients. All handlers, whether
a43bfa789f4e52dde53ae8e53fa0427b5c1cf977ndit's mod_rewrite, mod_authn_*, mod_proxy and so on, are hooked into
a43bfa789f4e52dde53ae8e53fa0427b5c1cf977ndspecific parts of the request process. As you are probably aware, modules
28c9d384aa958b321280b4ac886941dcad25396bndserve different purposes; Some are authentication/authorization handlers,
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndothers are file or script handlers while some third modules rewrite URIs or
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndproxies content. Furthermore, in the end, it is up to the user of the server
1d980e5489836e977ba59b419e27b0ec875c4bd3takashihow and when each module will come into place. Thus, the server itself does not
e5ce3ac0e9b720c0fa23782e29168a0810697fdetakashipresume to know which module is responsible for handling a specific
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndrequest, and will ask each module whether they have an interest in a given
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndrequest or not. It is then up to each module to either gently decline
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndserving a request, accept serving it or flat out deny the request from
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndbeing served, as authentication/authorization modules do: <br/>
ecc5150d35c0dc5ee5119c2717e6660fa331abbftakashi<img src="/images/build_a_mod_2.png" alt="Hook handling in httpd"/><br/>
ecc5150d35c0dc5ee5119c2717e6660fa331abbftakashiTo make it a bit easier for handlers such as our mod_example to know
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndwhether the client is requesting content we should handle or not, the server
79b024b81f6bb3c44dce77a7552191daf8b522d2jimhas directives for hinting to modules whether their assistance is needed or
79b024b81f6bb3c44dce77a7552191daf8b522d2jimnot. Two of these are <directive module="mod_mime">AddHandler</directive>
f772e8f448c223e5ea306f1bf92d97d968f972d5jimand <directive module="core">SetHandler</directive>. Let's take a look at
f772e8f448c223e5ea306f1bf92d97d968f972d5jiman example using <directive module="mod_mime">AddHandler</directive>. In
fac8c35bfb158112226ab43ddf84d59daca5dc30ndour example case, we want every request ending with .sum to be served by
f772e8f448c223e5ea306f1bf92d97d968f972d5jim<code>mod_example</code>, so we'll add a configuration directive that tells
a78048ccbdb6256da15e6b0e7e95355e480c2301ndthe server to do just that:
a78048ccbdb6256da15e6b0e7e95355e480c2301ndAddHandler example-handler .sum
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd</highlight>
a78048ccbdb6256da15e6b0e7e95355e480c2301ndWhat this tells the server is the following: <em>Whenever we receive a request
898711b68797304101de0882fa576c8908acfae6ndfor a URI ending in .sum, we are to let all modules know that we are
a78048ccbdb6256da15e6b0e7e95355e480c2301ndlooking for whoever goes by the name of "example-handler" </em>.
a78048ccbdb6256da15e6b0e7e95355e480c2301ndThus, when a request is being served that ends in .sum, the server will let all
a78048ccbdb6256da15e6b0e7e95355e480c2301ndmodules know, that this request should be served by "example-handler
a78048ccbdb6256da15e6b0e7e95355e480c2301nd". As you will see later, when we start building mod_example, we will
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndcheck for this handler tag relayed by <code>AddHandler</code> and reply to
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndthe server based on the value of this tag.
03c25fb6f628ac81f2ecb637d1e7502dcee783f3nd<section id="hook_declaration"><title>Hooking into httpd</title>
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndTo begin with, we only want to create a simple handler, that replies to the
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndclient browser when a specific URL is requested, so we won't bother setting
ad74a0524a06bfe11b7de9e3b4ce7233ab3bd3f7ndup configuration handlers and directives just yet. Our initial module
ad74a0524a06bfe11b7de9e3b4ce7233ab3bd3f7nddefinition will look like this:</p>
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end<!-- BEGIN EXAMPLE CODE -->
0853e1e2522c1ac17f697221758bcbd4781a7ff9ndmodule AP_MODULE_DECLARE_DATA example_module =
0853e1e2522c1ac17f697221758bcbd4781a7ff9nd STANDARD20_MODULE_STUFF,
<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>
<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 the server 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>
<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>
<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>
<li><code>r->handler (char*):</code> Contains the name of the handler the server is currently asking to do the handling of this request</li>
<li><code>r->filename (char*):</code> Contains the translated filename the client is requesting</li>
<li><code>r->connection (conn_rec*):</code> A record containing information about the current connection</li>
<li><code>r->user (char*):</code> If the URI requires authentication, this is set to the username provided</li>
<li><code>r->pool (apr_pool_t*)</code>: The memory pool of this request. We'll discuss this in the
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 <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>.
<li><code>DONE</code>: We handled this request and the server should just close this thread without further processing</li>
href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#gac827cd0537d2b6213a7c06d7c26cc36e">
<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__PROTO.html#ga5e91eb6ca777c9a427b2e82bf1eeb81d">ap_rprintf</a></code>: <br/>
<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/>
<highlight language="c">ap_set_content_type(r, "text/plain"); /* force a raw text output */</highlight>
memory pool that gets cleaned up when its scope ends, e.g. when a request
<li><code>void* <a href="http://apr.apache.org/docs/apr/1.4/group__apr__pools.html#ga85f1e193c31d109affda72f9a92c6915">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/1.4/group__apr__pools.html#gaf61c098ad258069d64cdf8c0a9369f9e">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/1.4/group__apr__strings.html#gabc79e99ff19abbd7cfd18308c5f85d47">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>
<li><code>char* <a href="http://apr.apache.org/docs/apr/1.4/group__apr__strings.html#ga3eca76b8d293c5c3f8021e45eda813d8">apr_psprintf</a>(
apr_pool_t *p, const char *fmt, ...)</code>: Similar to <code>sprintf</code>, except the server supplies you with an appropriately allocated target variable</li>
<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__apr__tables.html#gad7ea82d6608a4a633fc3775694ab71e4">apr_table_t</a> *GET; <em>
</em><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">
</em><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__DAEMON.html#ga9d426b6382b49754d4f87c55f65af202">
(finfo.filetype != APR_NOFILE)
&& !(finfo.filetype & APR_DIR)
ap_rprintf(r, "<b>Size:</b> %u bytes<br/>", finfo.size);
apr_md5_final(digest.chr, &md5);
ap_rprintf(r, "%08x", digest.num[n]);
ap_rputs("<br/><a href='?digest=sha1'>View the SHA1 hash instead</a>", r);
apr_sha1_final(digest.chr, &sha1);
ap_rprintf(r, "%08x", digest.num[n]);
ap_rputs("<br/><a href='?digest=md5'>View the MD5 hash instead</a>", r);
const char *path; /* Some path to...something */
const char *path; /* Some path to...something */
ap_rprintf(r, "Enabled: %u\n", config.enabled);
ap_rprintf(r, "Path: %s\n", config.path);
ap_rprintf(r, "TypeOfAction: %x\n", config.typeOfAction);
config.enabled = 1;
config.typeOfAction = 0x00;
into the module, but by using either the httpd.conf file or possibly a
AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"),
<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.
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
<li><code>exampleEnabled</code>: This is the name of our directive. More precisely, it is what the user must put in his/her
<li><code>example_set_enabled</code>: This is a reference to a C function that parses the directive and sets the configuration
<li><code>RSRC_CONF</code>: This tells the server where the directive is permitted. We'll go into details on this value in the
later chapters, but for now, <code>RSRC_CONF</code> means that the server 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>
if(!strcasecmp(arg, "on")) config.enabled = 1;
else config.enabled = 0;
config.path = arg;
if(!strcasecmp(arg1, "file")) config.typeOfAction = 0x01;
else config.typeOfAction = 0x02;
if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10;
else config.typeOfAction += 0x20;
/* mod_example_config_simple.c: */
#include <stdio.h>
#include "apr_hash.h"
#include "ap_config.h"
#include "ap_provider.h"
#include "httpd.h"
#include "http_core.h"
#include "http_config.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
const char *path; /* Some path to...something */
if(!strcasecmp(arg, "on")) config.enabled = 1;
else config.enabled = 0;
config.path = arg;
if(!strcasecmp(arg1, "file")) config.typeOfAction = 0x01;
else config.typeOfAction = 0x02;
if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10;
else config.typeOfAction += 0x20;
AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"),
AP_INIT_TAKE1("examplePath", example_set_path, NULL, RSRC_CONF, "The path to whatever"),
AP_INIT_TAKE2("exampleAction", example_set_action, NULL, RSRC_CONF, "Special action value!"),
ap_rprintf(r, "Enabled: %u\n", config.enabled);
ap_rprintf(r, "Path: %s\n", config.path);
ap_rprintf(r, "TypeOfAction: %x\n", config.typeOfAction);
config.enabled = 1;
config.typeOfAction = 3;
In our httpd.conf file, we can now change the hard-coded configuration by
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule (.*) http://www.example.com/$1
RewriteRule ^foobar$ index.php?foobar=true
<li>Inside <code>/var/www</code>, all requests for <code>http://example.com</code> must go to <code>http://www.example.com</code></li>
<li>Inside <code>/var/www/sub</code>, all requests for <code>foobar</code> must go to <code>index.php?foobar=true</code></li>
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->per_dir_config, &example_module);
example_config *config = (example_config*) ap_get_module_config(r->per_dir_config, &example_module);
AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"),
<li>Sets the configuration values according to the directives given for <code>/var/www/subdir</code></li>
<li><strong>Proposes a merge</strong> of the two configurations into a new configuration for <code>/var/www/subdir</code></li>
example_config* conf = (example_config *) create_dir_conf(pool, "Merged configuration"); /* This will be the merged configuration */
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <stdio.h>
#include "apr_hash.h"
#include "ap_config.h"
#include "ap_provider.h"
#include "httpd.h"
#include "http_core.h"
#include "http_config.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, ACCESS_CONF, "Enable or disable mod_example"),
AP_INIT_TAKE1("examplePath", example_set_path, NULL, ACCESS_CONF, "The path to whatever"),
AP_INIT_TAKE2("exampleAction", example_set_action, NULL, ACCESS_CONF, "Special action value!"),
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=======================================================================================================================
=======================================================================================================================
=======================================================================================================================
=======================================================================================================================
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
example_config *config = (example_config *) ap_get_module_config(r->per_dir_config, &example_module);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
=======================================================================================================================
=======================================================================================================================
=======================================================================================================================
=======================================================================================================================
=======================================================================================================================
=======================================================================================================================
=======================================================================================================================
=======================================================================================================================
=======================================================================================================================
=======================================================================================================================