From 8a25bd19af45808ce9af9328ef6acd096536ee41 Mon Sep 17 00:00:00 2001
From: Daniel Gruno This document explains how you can develop modules for the Apache HTTP Server 2.4 This document explains how you can develop modules for the Apache HTTP
+Server 2.4
-This document will discuss how you can easily create modules for the Apache HTTP Server 2.4 ("Apache"),
-by exploring an example module called
-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.
+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.
-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.
+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.
-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.
+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.
-To compile the source code we are building in this document, we will be using APXS.
-Assuming your source file is called mod_example.c, compiling, installing and activating the module is as simple as:
+To compile the source code we are building in this document, we will be
+using APXS. Assuming your source file
+is called mod_example.c, compiling, installing and activating the module is
+as simple as:
Every module starts with the same declaration, or name tag if you will, that defines a module as a separate entity within Apache:
+ Every module starts with the same declaration, or name tag if you will,
+that defines a module as a separate entity within Apache:
@@ -90,9 +103,9 @@ module AP_MODULE_DECLARE_DATA example_module
-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.
+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.
-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:
-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:
-The reference in our example declaration, The reference in our example declaration,
-Hooking into the request handling phase is but one of many hooks that you can create. Some other ways of hooking are:
+Hooking into the request handling phase is but one of many hooks that you
+can create. Some other ways of hooking are:
-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.
+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.
The most essential part of any request is the request record. In a call to a handler function, this
-is represented by the Some key elements of the The most essential part of any request is the request record
+. In a call to a handler function, this is represented by the Some key elements of the
-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
-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?
-In our module, we will primarilly be allocating memory for each request, so it's appropriate to
-use the mod_example
. 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 http://hostname/filename.sum
. For instance, if we want to know the MD5 digest value of the file
-located at http://www.example.com/index.html
, we would visit http://www.example.com/index.html.sum
.
+This document will discuss how you can easily create modules for the Apache
+HTTP Server 2.4 ("Apache"), by exploring an example module called
+mod_example
. 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
+http://hostname/filename.sum
. For instance, if we want to know the
+MD5 digest value of the file located at
+http://www.example.com/index.html
, we would visit
+http://www.example.com/index.html.sum
.
apxs -i -a -c mod_example.c
-=
-This bit of code lets Apache know that we have now registered a new module in the system,
-and that its name is
example_module
. The name of the module is used primarilly
-for two things:
+This bit of code lets Apache know that we have now registered a new module
+in the system, and that its name is example_module
. The name
+of the module is used primarilly for two things:
mod_example.so
and look fo
called example_module
.
+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:
-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 mod_example
,
-so we'll add a configuration directive that tells Apache to do just that:
+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 mod_example
, so we'll add a configuration directive that tells
+Apache to do just that:
AddHandler example-handler .sum
AddHandler
and
-reply to Apache based on the value of this tag.
+What this tells Apache is the following: 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 "example-handler" .
+Thus, when a request is being served that ends in .sum, Apache will let all
+modules know, that this request should be served by "example-handler
+". As you will see later, when we start building mod_example, we will
+check for this handler tag relayed by AddHandler
and reply to
+Apache based on the value of this tag.
+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:
@@ -167,15 +189,14 @@ module AP_MODULE_DECLARE_DATA example_module =
-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.
-register_hooks
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:
+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. register_hooks
+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:
@@ -189,13 +210,14 @@ as one of the last modules:
-The example_handler
reference is the function that will handle the request. We will
-discuss how to create a handler in the next chapter.
+The example_handler
reference is the function that will handle
+the request. We will discuss how to create a handler in the next chapter.
ap_hook_child_init
: Place a hook that executes when a child process is spawned (commonly used for initializing modules after Apache has forked)ap_hook_pre_config
: Place a hook that executes before any configuration data has been read (very early hook)
+
text/html
-Now, we put all we have learned together and end up with a program that looks like
-mod_example_1.c. The functions used in this example will be explained later in the section
-"Some useful functions you should know".
-request_req*
structure passed along with every call that is made. This
-struct, typically just refered to as r
in modules, contains all the information you need for
-your module to fully process any HTTP request and respond accordingly.request_req
structure are:
+Now, we put all we have learned together and end up with a program that
+looks like
+mod_example_1.c
+. The functions used in this example will be explained later in the section
+"Some useful functions you should know"
+.
+request_req*
structure passed along with every call that is made.
+This struct, typically just refered to as r
in modules,
+contains all the information you need for your module to fully process any
+HTTP request and respond accordingly.
+request_req
structure are:
: Contains the name of the handler Apache is currently asking to do the handling of this requestr->handler
(char*)
: Contains the HTTP method being used, f.x. GET or POSTr->method
(char*)
DECLINED
. If it is handling
-a request, it should either return the generic value OK
, or a specific HTTP status
-code, for example:
+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 DECLINED
. If it is handling a request, it
+should either return the generic value OK
, or a specific HTTP
+status code, for example:
@@ -329,12 +357,14 @@ code, for example:
-Returning OK
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 DONE
to let Apache know that it should cease all activity on this request and
-carry on with the next, without informing other handlers.
+Returning OK
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 DONE
to let Apache
+know that it should cease all activity on this request and carry on with
+the next, without informing other handlers.
General response codes:
@@ -399,16 +429,19 @@ carry on with the next, without informing other handlers.
reference when creating new objects. A few of the functions for
-allocating memory within a pool are:
+In our module, we will primarilly be allocating memory for each request, so
+it's appropriate to use the r->pool
r->pool
+reference when creating new objects. A few of the functions for allocating
+memory within a pool are:
void* apr_palloc(
apr_pool_t *p, apr_size_t size)
: Allocates size
number of bytes in the pool for you
-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 register_hooks
function to sort it out:
+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 register_hooks
+function to sort it out:
@@ -454,25 +489,30 @@ simply add a call to a function in our
-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.
+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.
register_hooks
function to s
-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
-valueA=yes&valueB=no&valueC=maybe
. 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 digest
,
-and if set to md5
, we'll produce an MD5 digest, otherwise we'll produce a SHA1 digest.
+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
+valueA=yes&valueB=no&valueC=maybe
. 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 digest
, and if set to
+md5
, we'll produce an MD5 digest, otherwise we'll produce a SHA1
+digest.
-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:
+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:
@@ -486,9 +526,10 @@ been easier. All we require to parse both GET and POST data is four simple lines
-In our specific example module, we're looking for the digest
value from the query string,
-which now resides inside a table called GET
. To extract this value, we need only perform
-a simple operation:
+In our specific example module, we're looking for the digest
+value from the query string, which now resides inside a table called
+GET
. To extract this value, we need only perform a simple operation:
+
@@ -503,15 +544,17 @@ a simple operation:
-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
-this example in the last chapter of this document.
+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 this example in the last chapter of this document.
-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 +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.
-mod_rewrite
works:
+mod_rewrite
works:
RewriteEngine On RewriteCond %{REQUEST_URI} ^/foo/bar RewriteRule ^/foo/bar/(.*)$ /foobar?page=$1
register_hooks
function for initializing the
-configuration values to their defaults:
+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
+register_hooks
function for initializing the configuration
+values to their defaults:
@@ -719,20 +767,23 @@ module AP_MODULE_DECLARE_DATA example_module =
-So far so good. To access our new handler, we could add the following to our configuration:
+So far so good. To access our new handler, we could add the following to
+our configuration:
<Location /example>
SetHandler example-handler
</Location>
-When we visit, we'll see our current configuration being spit out by our module.
+When we visit, we'll see our current configuration being spit out by our
+module.
example_directives
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:
+This will tell Apache that we are now accepting directives from the
+configuration files, and that the structure called example_directives
+
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:
@@ -785,18 +837,22 @@ accordingly. We will discuss how to make this in the following paragraph.
later chapters, but for now, RSRC_CONF
means that Apache will only accept these directives in a server context.
"Enable or disable...."
: This is simply a brief description of what the directive does.NULL
, 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.)
+(The "missing" parameter in our definition, which is usually set to
+NULL
, 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.)
-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 exampleAction
-directive to accept two arguments, its C function also has an additional parameter defined:
-
+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
+exampleAction
directive to accept two arguments, its C function also
+has an additional parameter defined:
@@ -835,8 +891,8 @@ directive to accept two arguments, its C function also has an additional paramet
-Now that we have our directives set up, and handlers configured for them, we can assemble our module
-into one big file:
+Now that we have our directives set up, and handlers configured for them,
+we can assemble our module into one big file:
@@ -959,14 +1015,16 @@ module AP_MODULE_DECLARE_DATA example_module =
-In our httpd.conf file, we can now change the hard-coded configuration by adding a few lines:
+In our httpd.conf file, we can now change the hard-coded configuration by
+adding a few lines:
ExampleEnabled On
ExamplePath "/usr/bin/foo"
ExampleAction file allow
/example
on our web site, and we see the configuration has
-adapted to what we wrote in our configuration file.
+And thus we apply the configuration, visit /example
on our
+web site, and we see the configuration has adapted to what we wrote in our
+configuration file.
-In Apache, different URLs, virtual hosts, directories etc can have very different meanings
-to the user of Apache, and thus different contexts within which modules must operate. For example,
-let's assume you have this configuration set up for mod_rewrite:
+In Apache, different URLs, virtual hosts, directories etc can have very
+different meanings to the user of Apache, and thus different contexts
+within which modules must operate. For example, let's assume you have this
+configuration set up for mod_rewrite:
<Directory "/var/www">
RewriteCond %{HTTP_HOST} ^example.com$
@@ -988,17 +1047,22 @@ let's assume you have this configuration set up for mod_rewrite:
RewriteRule ^foobar$ index.php?foobar=true
</Directory>
/var/www
, all requests for http://example.com
must go to http://www.example.com
/var/www/sub
, all requests for foobar
must go to index.php?foobar=true
-So how does a module get the specific configuration for the server, directory or location in question? It does so by making one simple call:
+So how does a module get the specific configuration for the server,
+directory or location in question? It does so by making one simple call:
@@ -1008,15 +1072,18 @@ So how does a module get the specific configuration for the server, directory or
example_config *config = (example_config*) ap_get_module_config(r->per_dir_config
, &example_module);
-That's it! Of course, a whole lot goes on behind the scenes, which we will discuss in this chapter, starting with how
-Apache came to know what our configuration looks like, and how it came to be set up as it is in the specific context.
+That's it! Of course, a whole lot goes on behind the scenes, which we will
+discuss in this chapter, starting with how Apache came to know what our
+configuration looks like, and how it came to be set up as it is in the
+specific context.
In this chapter, we will be working with a slightly modified version of our previous
-context structure. We will set a context
variable that we can use to track
-which context configuration is being used by Apache in various places:
+
In this chapter, we will be working with a slightly modified version of
+our previous context structure. We will set a
-Before we can start making our module context aware, we must first define, which contexts we will accept.
-As we saw in the previous chapter, defining a directive required five elements be set:
+Before we can start making our module context aware, we must first define,
+which contexts we will accept. As we saw in the previous chapter, defining
+a directive required five elements be set:
@@ -1070,18 +1138,21 @@ As we saw in the previous chapter, defining a directive required five elements b
-The A much smarter way to manage your configurations is by letting Apache help you create them.
-To do so, we must first start off by chancing our name tag to let Apache know, that
-it should assist us in creating and managing our configurations. Since we have chosen the per-directory
-(or per-location) context for our module configurations, we'll add a per-directory creator and merger
-function reference in our tag:
+ A much smarter way to manage your configurations is by letting Apache
+help you create them. To do so, we must first start off by chancing our
+name tag to let Apache know, that it should assist us in creating
+and managing our configurations. Since we have chosen the per-directory
+(or per-location) context for our module configurations, we'll add a
+per-directory creator and merger function reference in our tag:
-Now that we have told Apache to help us create and manage configurations, our first step is to
-make a function for creating new, blank configurations. We do so by creating the function we just
-referenced in our name tag as the Per-directory configuration handler:
+Now that we have told Apache to help us create and manage configurations,
+our first step is to make a function for creating new, blank
+configurations. We do so by creating the function we just referenced in
+our name tag as the Per-directory configuration handler:
-Our next step in creating a context aware configuration is merging configurations. This part of the process
-particularly apply to scenarios where you have a parent configuration and a child, such as the following:
+Our next step in creating a context aware configuration is merging
+configurations. This part of the process particularly apply to scenarios
+where you have a parent configuration and a child, such as the following:
-Now, let's try putting it all together to create a new module that it context aware. First off, we'll
-create a configuration that lets us test how the module works:
+Now, let's try putting it all together to create a new module that it
+context aware. First off, we'll create a configuration that lets us test
+how the module works:
-We have now looked at how to create simple modules for Apache and configuring them. What you do next is entirely up
-to you, but it is my hope that something valuable has come out of reading this documentation. If you have questions
-on how to further develop modules, you are welcome to join our mailing lists
+We have now looked at how to create simple modules for Apache and
+configuring them. What you do next is entirely up to you, but it is my
+hope that something valuable has come out of reading this documentation.
+If you have questions on how to further develop modules, you are welcome
+to join our mailing lists
or check out the rest of our documentation for further tips.
context
+variable that we can use to track which context configuration is being
+used by Apache in various places:
@@ -1059,8 +1126,9 @@ which context configuration is being used by Apache in various places:
RSRC_CONF
definition told Apache that we would only allow this directive in a global server context, but
-since we are now trying out a context aware version of our module, we should set this to something more lenient, namely
-the value ACCESS_CONF
, which lets us use the directive inside <Directory> and <Location> blocks.
+The RSRC_CONF
definition told Apache that we would only allow
+this directive in a global server context, but since we are now trying out
+a context aware version of our module, we should set this to something
+more lenient, namely the value ACCESS_CONF
, which lets us use
+the directive inside <Directory> and <Location> blocks.
@@ -1107,9 +1178,10 @@ module AP_MODULE_DECLARE_DATA example_module
=
void
*
example_create_dir_conf(
apr_pool_t*
pool,
char
*
context)
{
@@ -1133,8 +1205,9 @@ referenced in our name tag as the Per-directory configuration handler:
<Directory "/var/www">
ExampleEnable On
@@ -1145,10 +1218,11 @@ particularly apply to scenarios where you have a parent configuration and a chil
ExampleAction file deny
</Directory>
/var/www/subdir
should inherit the
-value set for the /var/www
directory, as we did not specify a ExampleEnable
nor an
-ExamplePath
for this directory. Apache does not presume to know if this is true, but cleverly
-does the following:
+In this example, it is natural to assume that the directory
+/var/www/subdir
should inherit the value set for the /var/www
+
directory, as we did not specify a ExampleEnable
nor
+an ExamplePath
for this directory. Apache does not presume to
+know if this is true, but cleverly does the following:
-This proposal is handled by the /var/www
/var/www
/var/www/subdir
/var/www/subdir
merge_dir_conf
function we referenced in our name tag. The purpose of
-this function is to assess the two configurations and decide how they are to be merged:
+This proposal is handled by the merge_dir_conf
function we
+referenced in our name tag. The purpose of this function is to assess the
+two configurations and decide how they are to be merged:
@@ -1181,8 +1256,9 @@ this function is to assess the two configurations and decide how they are to be
<Location "/a">
SetHandler example-handler
@@ -1202,8 +1278,9 @@ create a configuration that lets us test how the module works:
ExampleEnabled on
</Location>
=<