From: Daniel Gruno Date: Tue, 24 Apr 2012 14:58:57 +0000 (+0000) Subject: Removed all manual styling, prepping for dynamic SH instead X-Git-Tag: 2.5.0-alpha~7069 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=30888cbd1d7896066bf090cac80b8c05e0ea327d;p=apache Removed all manual styling, prepping for dynamic SH instead git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1329774 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/developer/modguide.xml b/docs/manual/developer/modguide.xml index 5600f770b4..eaa9748126 100644 --- a/docs/manual/developer/modguide.xml +++ b/docs/manual/developer/modguide.xml @@ -1,6 +1,7 @@ + -

-module AP_MODULE_DECLARE_DATA example_module = -{ - STANDARD20_MODULE_STUFF, - create_dir_conf, /* Per-directory configuration handler */ - merge_dir_conf, /* Merge handler for per-directory configurations */ - create_svr_conf, /* Per-server configuration handler */ - merge_svr_conf, /* Merge handler for per-server configurations */ - directives, /* Any directives we may have for httpd */ - register_hooks /* Our hook registering function */ -}; -

+
+module AP_MODULE_DECLARE_DATA   example_module =
+{ 
+    STANDARD20_MODULE_STUFF,
+    create_dir_conf, /* Per-directory configuration handler */
+    merge_dir_conf,  /* Merge handler for per-directory configurations */
+    create_svr_conf, /* Per-server configuration handler */
+    merge_svr_conf,  /* Merge handler for per-server configurations */
+    directives,      /* Any directives we may have for httpd */
+    register_hooks   /* Our hook registering function */
+};
+

@@ -184,18 +185,18 @@ definition will look like this:

-

+

 module AP_MODULE_DECLARE_DATA   example_module =
 {
     STANDARD20_MODULE_STUFF,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    register_hooks   /* Our hook registering function */
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    register_hooks   /* Our hook registering function */
 };
-

+
@@ -211,13 +212,13 @@ to hook into its process as one of the last modules:

-

-static void register_hooks(apr_pool_t *pool) -{ - /* Create a hook in the request handler, so we get called when a request arrives */ - ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST); -} -

+
+static void register_hooks(apr_pool_t *pool)
+{
+    /* Create a hook in the request handler, so we get called when a request arrives */
+    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
+}
+

@@ -264,27 +265,27 @@ In C code, our example handler will now look like this:

-

-static int example_handler(request_rec *r) -{ - /* First off, we need to check if this is a call for the "example-handler" handler. -     * If it is, we accept it and do our things, if not, we simply return DECLINED, -     * and the server will try somewhere else. -     */ - if (!r->handler || strcmp(r->handler, "example-handler")) return (DECLINED); +

+static int example_handler(request_rec *r)
+{
+    /* First off, we need to check if this is a call for the "example-handler" handler.
+     * If it is, we accept it and do our things, if not, we simply return DECLINED,
+     * and the server will try somewhere else.
+     */
+    if (!r->handler || strcmp(r->handler, "example-handler")) return (DECLINED);
     
-    /* Now that we are handling this request, we'll write out "Hello, world!" to the client.
-     * To do so, we must first set the appropriate content type, followed by our output.
-     */
-    ap_set_content_type(r, "text/html");
-    ap_rprintf(r, "Hello, world!");
+    /* Now that we are handling this request, we'll write out "Hello, world!" to the client.
+     * To do so, we must first set the appropriate content type, followed by our output.
+     */
+    ap_set_content_type(r, "text/html");
+    ap_rprintf(r, "Hello, world!");
     
-    /* Lastly, we must tell the server that we took care of this request and everything went fine.
-     * We do so by simply returning the value OK to the server.
-     */
-    return OK;
-}
-

+ /* Lastly, we must tell the server that we took care of this request and everything went fine. + * We do so by simply returning the value OK to the server. + */ + return OK; +} +

@@ -305,14 +306,14 @@ HTTP request and respond accordingly.

Some key elements of the request_req structure are:

@@ -327,30 +328,30 @@ Let's try out some of these variables in another example handler:

-

-static int example_handler(request_rec *r) -{ - /* Set the appropriate content type */ - ap_set_content_type(r, "text/html"); - - /* Print out the IP address of the client connecting to us: */ - ap_rprintf(r, "<h2>Hello, %s!</h2>", r->useragent_ip); +

+static int example_handler(request_rec *r)
+{
+    /* Set the appropriate content type */
+    ap_set_content_type(r, "text/html");
+
+    /* Print out the IP address of the client connecting to us: */
+    ap_rprintf(r, "<h2>Hello, %s!</h2>", r->useragent_ip);
     
-    /* If we were reached through a GET or a POST request, be happy, else sad. */
-    if ( !strcmp(r->method, "POST") || !strcmp(r->method, "GET") ) {
-        ap_rputs("You used a GET or a POST method, that makes us happy!<br>", r);
-    }
-    else {
-        ap_rputs("You did not use POST or GET, that makes us sad :(<br>", r);
-    }
-
-    /* Lastly, if there was a query string, let's print that too! */
-    if (r->args) {
-        ap_rprintf(r, "Your query string was: %s", r->args);
-    }
-    return OK;
-}
-

+ /* If we were reached through a GET or a POST request, be happy, else sad. */ + if ( !strcmp(r->method, "POST") || !strcmp(r->method, "GET") ) { + ap_rputs("You used a GET or a POST method, that makes us happy!<br/>", r); + } + else { + ap_rputs("You did not use POST or GET, that makes us sad :(<br/>", r); + } + + /* Lastly, if there was a query string, let's print that too! */ + if (r->args) { + ap_rprintf(r, "Your query string was: %s", r->args); + } + return OK; +} +
@@ -366,13 +367,13 @@ status code, for example:

-

-static int example_handler(request_rec *r) -{ - /* Return 404: Not found */ - return HTTP_NOT_FOUND; -} -

+
+static int example_handler(request_rec *r)
+{
+    /* Return 404: Not found */
+    return HTTP_NOT_FOUND;
+}
+

@@ -416,7 +417,7 @@ the next, without informing other handlers. -

ap_rputs("Hello, world!", r);

+
ap_rputs("Hello, world!", r);
@@ -428,7 +429,7 @@ the next, without informing other handlers. -

ap_rprintf(r, "Hello, %s!", r->useragent_ip);

+
ap_rprintf(r, "Hello, %s!", r->useragent_ip);
@@ -439,7 +440,7 @@ the next, without informing other handlers. -

ap_set_content_type(r, "text/plain"); /* force a raw text output */

+
ap_set_content_type(r, "text/plain"); /* force a raw text output */
@@ -460,7 +461,7 @@ clean up after yourself - pretty neat, huh?

In our module, we will primarily be allocating memory for each request, so -it's appropriate to use the r->pool +it's appropriate to use the r->pool reference when creating new objects. A few of the functions for allocating memory within a pool are:

@@ -479,21 +480,21 @@ apr_pool_t *p, const char *fmt, ...): Similar to sprintf, ex -

-static int example_handler(request_rec *r) -{ - const char* original = "You can't edit this!"; - char* copy; - int* integers; +

+static int example_handler(request_rec *r)
+{
+    const char* original = "You can't edit this!";
+    char* copy;
+    int* integers;
     
-    /* Allocate space for 10 integer values and set them all to zero. */
-    integers = apr_pcalloc(r->pool, sizeof(int)*10); 
+    /* Allocate space for 10 integer values and set them all to zero. */
+    integers = apr_pcalloc(r->pool, sizeof(int)*10); 
     
-    /* Create a copy of the 'original' variable that we can edit. */
-    copy = apr_pstrdup(r->pool, original);
-    return OK;
-}
-

+ /* Create a copy of the 'original' variable that we can edit. */ + copy = apr_pstrdup(r->pool, original); + return OK; +} +

@@ -505,15 +506,15 @@ function to sort it out:

-

-static void register_hooks(apr_pool_t *pool) -{ - /* Call a function that initializes some stuff */ - example_init_function(pool); - /* Create a hook in the request handler, so we get called when a request arrives */ - ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST); -} -

+
+static void register_hooks(apr_pool_t *pool)
+{
+    /* Call a function that initializes some stuff */
+    example_init_function(pool);
+    /* Create a hook in the request handler, so we get called when a request arrives */
+    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
+}
+

@@ -544,13 +545,13 @@ POST data is four simple lines: -

+

 apr_table_t *GET;
 apr_array_header_t *POST;
 
 ap_args_to_table(r, &GET);
-ap_parse_form_data(r, NULL, &POST, -1, 8192);
-

+ap_parse_form_data(r, NULL, &POST, -1, 8192); +

@@ -561,14 +562,13 @@ GET. To extract this value, we need only perform a simple operation: -

-/* Get the "digest" key from the query string, if any. */ -const char *digestType = apr_table_get(GET, "digest"); - -/* If no key was returned, we will set a default value instead. */ -if (!digestType) digestType = "sha1"; +

+/* Get the "digest" key from the query string, if any. */
+const char *digestType = apr_table_get(GET, "digest");
 
-

+/* If no key was returned, we will set a default value instead. */ +if (!digestType) digestType = "sha1"; +

@@ -588,119 +588,116 @@ out the MD5 or SHA1 digest of files: -

-static int example_handler(request_rec *r) -{ - int rc, exists; - apr_finfo_t finfo; - apr_file_t *file; - char *filename; - char buffer[256]; - apr_size_t readBytes; - int n; - apr_table_t *GET; - apr_array_header_t *POST; - const char *digestType; +

+static int example_handler(request_rec *r)
+{
+    int rc, exists;
+    apr_finfo_t finfo;
+    apr_file_t *file;
+    char *filename;
+    char buffer[256];
+    apr_size_t readBytes;
+    int n;
+    apr_table_t *GET;
+    apr_array_header_t *POST;
+    const char *digestType;
     
     
-    /* Check that the "example-handler" handler is being called. */
-    if (!r->handler || strcmp(r->handler, "example-handler")) return (DECLINED);
+    /* Check that the "example-handler" handler is being called. */
+    if (!r->handler || strcmp(r->handler, "example-handler")) return (DECLINED);
     
-    /* Figure out which file is being requested by removing the .sum from it */
-    filename = apr_pstrdup(r->pool, r->filename);
-    filename[strlen(filename)-4] = 0; /* Cut off the last 4 characters. */
+    /* Figure out which file is being requested by removing the .sum from it */
+    filename = apr_pstrdup(r->pool, r->filename);
+    filename[strlen(filename)-4] = 0; /* Cut off the last 4 characters. */
     
-    /* Figure out if the file we request a sum on exists and isn't a directory */
-    rc = apr_stat(&finfo, filename, APR_FINFO_MIN, r->pool);
-    if (rc == APR_SUCCESS) {
-        exists =
-        (
-            (finfo.filetype != APR_NOFILE)
-        &&  !(finfo.filetype & APR_DIR)
-        );
-        if (!exists) return HTTP_NOT_FOUND; /* Return a 404 if not found. */
-    }
-    /* If apr_stat failed, we're probably not allowed to check this file. */
-    else return HTTP_FORBIDDEN;
+    /* Figure out if the file we request a sum on exists and isn't a directory */
+    rc = apr_stat(&finfo, filename, APR_FINFO_MIN, r->pool);
+    if (rc == APR_SUCCESS) {
+        exists =
+        (
+            (finfo.filetype != APR_NOFILE)
+        &&  !(finfo.filetype & APR_DIR)
+        );
+        if (!exists) return HTTP_NOT_FOUND; /* Return a 404 if not found. */
+    }
+    /* If apr_stat failed, we're probably not allowed to check this file. */
+    else return HTTP_FORBIDDEN;
     
-    /* Parse the GET and, optionally, the POST data sent to us */
+    /* Parse the GET and, optionally, the POST data sent to us */
     
-    ap_args_to_table(r, &GET);
-    ap_parse_form_data(r, NULL, &POST, -1, 8192);
+    ap_args_to_table(r, &GET);
+    ap_parse_form_data(r, NULL, &POST, -1, 8192);
     
-    /* Set the appropriate content type */
-    ap_set_content_type(r, "text/html");
+    /* Set the appropriate content type */
+    ap_set_content_type(r, "text/html");
     
-    /* Print a title and some general information */
-    ap_rprintf(r, "<h2>Information on %s:</h2>", filename);
-    ap_rprintf(r, "<b>Size:</b> %u bytes<br/>", finfo.size);
+    /* Print a title and some general information */
+    ap_rprintf(r, "<h2>Information on %s:</h2>", filename);
+    ap_rprintf(r, "<b>Size:</b> %u bytes<br/>", finfo.size);
     
-    /* Get the digest type the client wants to see */
-    digestType = apr_table_get(GET, "digest");
-    if (!digestType) digestType = "MD5";
+    /* Get the digest type the client wants to see */
+    digestType = apr_table_get(GET, "digest");
+    if (!digestType) digestType = "MD5";
     
     
-    rc = apr_file_open(&file, filename, APR_READ, APR_OS_DEFAULT, r->pool);
-    if (rc == APR_SUCCESS) {
+    rc = apr_file_open(&file, filename, APR_READ, APR_OS_DEFAULT, r->pool);
+    if (rc == APR_SUCCESS) {
         
-        /* Are we trying to calculate the MD5 or the SHA1 digest? */
-        if (!strcasecmp(digestType, "md5")) {
-            /* Calculate the MD5 sum of the file */
-            union {
-                char      chr[16];
-                uint32_t  num[4];
-            } digest;
-            apr_md5_ctx_t md5;
-            apr_md5_init(&md5);
-            readBytes = 256;
-            while ( apr_file_read(file, buffer, &readBytes) == APR_SUCCESS ) {
-                apr_md5_update(&md5, buffer, readBytes);
-            }
-            apr_md5_final(digest.chr, &md5);
+        /* Are we trying to calculate the MD5 or the SHA1 digest? */
+        if (!strcasecmp(digestType, "md5")) {
+            /* Calculate the MD5 sum of the file */
+            union {
+                char      chr[16];
+                uint32_t  num[4];
+            } digest;
+            apr_md5_ctx_t md5;
+            apr_md5_init(&md5);
+            readBytes = 256;
+            while ( apr_file_read(file, buffer, &readBytes) == APR_SUCCESS ) {
+                apr_md5_update(&md5, buffer, readBytes);
+            }
+            apr_md5_final(digest.chr, &md5);
             
-            /* Print out the MD5 digest */
-            ap_rputs("<b>MD5: </b><code>", r);
-            for (n = 0; n < APR_MD5_DIGESTSIZE/4; n++) {
-                ap_rprintf(r, "%08x", digest.num[n]);
-            }
-            ap_rputs("</code>", r);
-            /* Print a link to the SHA1 version */
-            ap_rputs("<br/><a href='?digest=sha1'>View the SHA1 hash instead</a>", r);
-        }
-        else {
-            /* Calculate the SHA1 sum of the file */
-            union {
-                char      chr[20];
-                uint32_t  num[5];
-            } digest;
-            apr_sha1_ctx_t sha1;
-            apr_sha1_init(&sha1);
-            readBytes = 256;
-            while ( apr_file_read(file, buffer, &readBytes) == APR_SUCCESS ) {
-                apr_sha1_update(&sha1, buffer, readBytes);
-            }
-            apr_sha1_final(digest.chr, &sha1);
+            /* Print out the MD5 digest */
+            ap_rputs("<b>MD5: </b><code>", r);
+            for (n = 0; n < APR_MD5_DIGESTSIZE/4; n++) {
+                ap_rprintf(r, "%08x", digest.num[n]);
+            }
+            ap_rputs("</code>", r);
+            /* Print a link to the SHA1 version */
+            ap_rputs("<br/><a href='?digest=sha1'>View the SHA1 hash instead</a>", r);
+        }
+        else {
+            /* Calculate the SHA1 sum of the file */
+            union {
+                char      chr[20];
+                uint32_t  num[5];
+            } digest;
+            apr_sha1_ctx_t sha1;
+            apr_sha1_init(&sha1);
+            readBytes = 256;
+            while ( apr_file_read(file, buffer, &readBytes) == APR_SUCCESS ) {
+                apr_sha1_update(&sha1, buffer, readBytes);
+            }
+            apr_sha1_final(digest.chr, &sha1);
             
-            /* Print out the SHA1 digest */
-            ap_rputs("<b>SHA1: </b><code>", r);
-            for (n = 0; n < APR_SHA1_DIGESTSIZE/4; n++) {
-                ap_rprintf(r, "%08x", digest.num[n]);
-            }
-            ap_rputs("</code>", r);
+            /* Print out the SHA1 digest */
+            ap_rputs("<b>SHA1: </b><code>", r);
+            for (n = 0; n < APR_SHA1_DIGESTSIZE/4; n++) {
+                ap_rprintf(r, "%08x", digest.num[n]);
+            }
+            ap_rputs("</code>", r);
             
-            /* Print a link to the MD5 version */
-            ap_rputs("<br/><a href='?digest=md5'>View the MD5 hash instead</a>", r);
-        }
-        apr_file_close(file);
+            /* Print a link to the MD5 version */
+            ap_rputs("<br/><a href='?digest=md5'>View the MD5 hash instead</a>", r);
+        }
+        apr_file_close(file);
         
-    }
-    
-    
-    
-    /* Let the server know that we responded to this request. */
-    return OK;
-}
-

+ } + /* Let the server know that we responded to this request. */ + return OK; +} +

@@ -743,13 +740,13 @@ that parses the parameters given and sets up a configuration accordingly. -

-typedef struct { - int enabled; /* Enable or disable our module */ - const char *path; /* Some path to...something */ - int typeOfAction; /* 1 means action A, 2 means action B and so on */ -} example_config; -

+
+typedef struct {
+    int         enabled;      /* Enable or disable our module */
+    const char *path;         /* Some path to...something */
+    int         typeOfAction; /* 1 means action A, 2 means action B and so on */
+} example_config;
+

@@ -760,46 +757,46 @@ values to their defaults:

-

-typedef struct { - int enabled; /* Enable or disable our module */ - const char *path; /* Some path to...something */ - int typeOfAction; /* 1 means action A, 2 means action B and so on */ -} example_config; - -static example_config config; - -static int example_handler(request_rec *r) -{ - if (!r->handler || strcmp(r->handler, "example-handler")) return(DECLINED); - ap_set_content_type(r, "text/plain"); - ap_rprintf(r, "Enabled: %u\n", config.enabled); - ap_rprintf(r, "Path: %s\n", config.path); - ap_rprintf(r, "TypeOfAction: %x\n", config.typeOfAction); - return OK; -} - -static void register_hooks(apr_pool_t *pool) -{ - config.enabled = 1; - config.path = "/foo/bar"; - config.typeOfAction = 0x00; - ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST); -} - -/* Define our module as an entity and assign a function for registering hooks */ - -module AP_MODULE_DECLARE_DATA example_module = -{ - STANDARD20_MODULE_STUFF, - NULL, /* Per-directory configuration handler */ - NULL, /* Merge handler for per-directory configurations */ - NULL, /* Per-server configuration handler */ - NULL, /* Merge handler for per-server configurations */ - NULL, /* Any directives we may have for httpd */ - register_hooks /* Our hook registering function */ -}; -

+
+typedef struct {
+    int         enabled;      /* Enable or disable our module */
+    const char *path;         /* Some path to...something */
+    int         typeOfAction; /* 1 means action A, 2 means action B and so on */
+} example_config;
+
+static example_config config;
+
+static int example_handler(request_rec *r)
+{
+    if (!r->handler || strcmp(r->handler, "example-handler")) return(DECLINED);
+    ap_set_content_type(r, "text/plain");
+    ap_rprintf(r, "Enabled: %u\n", config.enabled);
+    ap_rprintf(r, "Path: %s\n", config.path);
+    ap_rprintf(r, "TypeOfAction: %x\n", config.typeOfAction);
+    return OK;
+}
+
+static void register_hooks(apr_pool_t *pool) 
+{
+    config.enabled = 1;
+    config.path = "/foo/bar";
+    config.typeOfAction = 0x00;
+    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
+}
+
+/* Define our module as an entity and assign a function for registering hooks  */
+
+module AP_MODULE_DECLARE_DATA   example_module =
+{
+    STANDARD20_MODULE_STUFF,
+    NULL,            /* Per-directory configuration handler */
+    NULL,            /* Merge handler for per-directory configurations */
+    NULL,            /* Per-server configuration handler */
+    NULL,            /* Merge handler for per-server configurations */
+    NULL,            /* Any directives we may have for httpd */
+    register_hooks   /* Our hook registering function */
+};
+

@@ -827,18 +824,18 @@ reference to the configuration directives we want to register with the server:

-

+

 module AP_MODULE_DECLARE_DATA   example_module =
 {
     STANDARD20_MODULE_STUFF,
-    NULL,               /* Per-directory configuration handler */
-    NULL,               /* Merge handler for per-directory configurations */
-    NULL,               /* Per-server configuration handler */
-    NULL,               /* Merge handler for per-server configurations */
-    example_directives, /* Any directives we may have for httpd */
-    register_hooks      /* Our hook registering function */
+    NULL,               /* Per-directory configuration handler */
+    NULL,               /* Merge handler for per-directory configurations */
+    NULL,               /* Per-server configuration handler */
+    NULL,               /* Merge handler for per-server configurations */
+    example_directives, /* Any directives we may have for httpd */
+    register_hooks      /* Our hook registering function */
 };
-

+

@@ -850,15 +847,15 @@ will add a structure with three directives and a NULL at the end:

-

+

 static const command_rec        example_directives[] =
 {
-    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!"),
-    { NULL }
+    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!"),
+    { NULL }
 };
-

+

@@ -896,35 +893,35 @@ exampleAction directive to accept two arguments, its C function also has an additional parameter defined:

-

-/* Handler for the "exambleEnabled" directive */ -const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg) -{ - if(!strcasecmp(arg, "on")) config.enabled = 1; - else config.enabled = 0; - return NULL; -} - -/* Handler for the "examplePath" directive */ -const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg) -{ - config.path = arg; - return NULL; -} - -/* Handler for the "exampleAction" directive */ -/* Let's pretend this one takes one argument (file or db), and a second (deny or allow), */ -/* and we store it in a bit-wise manner. */ -const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char* arg2) -{ - if(!strcasecmp(arg1, "file")) config.typeOfAction = 0x01; - else config.typeOfAction = 0x02; +

+/* Handler for the "exambleEnabled" directive */
+const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg)
+{
+    if(!strcasecmp(arg, "on")) config.enabled = 1;
+    else config.enabled = 0;
+    return NULL;
+}
+
+/* Handler for the "examplePath" directive */
+const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg)
+{
+    config.path = arg;
+    return NULL;
+}
+
+/* Handler for the "exampleAction" directive */
+/* Let's pretend this one takes one argument (file or db), and a second (deny or allow), */
+/* and we store it in a bit-wise manner. */
+const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char* arg2)
+{
+    if(!strcasecmp(arg1, "file")) config.typeOfAction = 0x01;
+    else config.typeOfAction = 0x02;
     
-    if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10;
-    else config.typeOfAction += 0x20;
-    return NULL;
-}
-

+ if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10; + else config.typeOfAction += 0x20; + return NULL; +} +
@@ -936,120 +933,120 @@ we can assemble our module into one big file:

-

-/* 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" - -/* - ============================================================================== - Our configuration prototype and declaration: - ============================================================================== - */ -typedef struct { - int enabled; /* Enable or disable our module */ - const char *path; /* Some path to...something */ - int typeOfAction; /* 1 means action A, 2 means action B and so on */ -} example_config; - -static example_config config; - -/* - ============================================================================== - Our directive handlers: - ============================================================================== - */ -/* Handler for the "exambleEnabled" directive */ -const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg) -{ - if(!strcasecmp(arg, "on")) config.enabled = 1; - else config.enabled = 0; - return NULL; -} - -/* Handler for the "examplePath" directive */ -const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg) -{ - config.path = arg; - return NULL; -} - -/* Handler for the "exampleAction" directive */ -/* Let's pretend this one takes one argument (file or db), and a second (deny or allow), */ -/* and we store it in a bit-wise manner. */ -const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char* arg2) -{ - if(!strcasecmp(arg1, "file")) config.typeOfAction = 0x01; - else config.typeOfAction = 0x02; +

+/* 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"
+
+/*
+ ==============================================================================
+ Our configuration prototype and declaration:
+ ==============================================================================
+ */
+typedef struct {
+    int         enabled;      /* Enable or disable our module */
+    const char *path;         /* Some path to...something */
+    int         typeOfAction; /* 1 means action A, 2 means action B and so on */
+} example_config;
+
+static example_config config;
+
+/*
+ ==============================================================================
+ Our directive handlers:
+ ==============================================================================
+ */
+/* Handler for the "exambleEnabled" directive */
+const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg)
+{
+    if(!strcasecmp(arg, "on")) config.enabled = 1;
+    else config.enabled = 0;
+    return NULL;
+}
+
+/* Handler for the "examplePath" directive */
+const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg)
+{
+    config.path = arg;
+    return NULL;
+}
+
+/* Handler for the "exampleAction" directive */
+/* Let's pretend this one takes one argument (file or db), and a second (deny or allow), */
+/* and we store it in a bit-wise manner. */
+const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char* arg2)
+{
+    if(!strcasecmp(arg1, "file")) config.typeOfAction = 0x01;
+    else config.typeOfAction = 0x02;
     
-    if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10;
-    else config.typeOfAction += 0x20;
-    return NULL;
-}
-
-/*
- ==============================================================================
- The directive structure for our name tag:
- ==============================================================================
- */
-static const command_rec        example_directives[] =
-{
-    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!"),
-    { NULL }
-};
-/*
- ==============================================================================
- Our module handler:
- ==============================================================================
- */
-static int example_handler(request_rec *r)
-{
-    if(!r->handler || strcmp(r->handler, "example-handler")) return(DECLINED);
-    ap_set_content_type(r, "text/plain");
-    ap_rprintf(r, "Enabled: %u\n", config.enabled);
-    ap_rprintf(r, "Path: %s\n", config.path);
-    ap_rprintf(r, "TypeOfAction: %x\n", config.typeOfAction);
-    return OK;
-}
-
-/*
- ==============================================================================
- The hook registration function (also initializes the default config values):
- ==============================================================================
- */
-static void register_hooks(apr_pool_t *pool) 
-{
-    config.enabled = 1;
-    config.path = "/foo/bar";
-    config.typeOfAction = 3;
-    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
-}
-/*
- ==============================================================================
- Our module name tag:
- ==============================================================================
- */
-module AP_MODULE_DECLARE_DATA   example_module =
-{
-    STANDARD20_MODULE_STUFF,
-    NULL,               /* Per-directory configuration handler */
-    NULL,               /* Merge handler for per-directory configurations */
-    NULL,               /* Per-server configuration handler */
-    NULL,               /* Merge handler for per-server configurations */
-    example_directives, /* Any directives we may have for httpd */
-    register_hooks      /* Our hook registering function */
-};
-

+ if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10; + else config.typeOfAction += 0x20; + return NULL; +} + +/* + ============================================================================== + The directive structure for our name tag: + ============================================================================== + */ +static const command_rec example_directives[] = +{ + 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!"), + { NULL } +}; +/* + ============================================================================== + Our module handler: + ============================================================================== + */ +static int example_handler(request_rec *r) +{ + if(!r->handler || strcmp(r->handler, "example-handler")) return(DECLINED); + ap_set_content_type(r, "text/plain"); + ap_rprintf(r, "Enabled: %u\n", config.enabled); + ap_rprintf(r, "Path: %s\n", config.path); + ap_rprintf(r, "TypeOfAction: %x\n", config.typeOfAction); + return OK; +} + +/* + ============================================================================== + The hook registration function (also initializes the default config values): + ============================================================================== + */ +static void register_hooks(apr_pool_t *pool) +{ + config.enabled = 1; + config.path = "/foo/bar"; + config.typeOfAction = 3; + ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST); +} +/* + ============================================================================== + Our module name tag: + ============================================================================== + */ +module AP_MODULE_DECLARE_DATA example_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* Per-directory configuration handler */ + NULL, /* Merge handler for per-directory configurations */ + NULL, /* Per-server configuration handler */ + NULL, /* Merge handler for per-server configurations */ + example_directives, /* Any directives we may have for httpd */ + register_hooks /* Our hook registering function */ +}; +
@@ -1110,10 +1107,11 @@ directory or location in question? It does so by making one simple call:

-

+

+example_config *config = (example_config*) ap_get_module_config(r->per_dir_config, &example_module);
+
-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 the server came to know what our @@ -1129,33 +1127,33 @@ variable that we can use to track which context configuration is being used by the server in various places:

-

-typedef struct { - char context[256]; - char path[256]; - int typeOfAction; - int enabled; -} example_config; -

+
+typedef struct {
+    char        context[256];
+    char        path[256];
+    int         typeOfAction;
+    int         enabled;
+} example_config;
+

Our handler for requests will also be modified, yet still very simple:

-

-static int example_handler(request_rec *r) -{ - if(!r->handler || strcmp(r->handler, "example-handler")) return(DECLINED); - example_config *config = (example_config*) ap_get_module_config(r->per_dir_config, &example_module); - ap_set_content_type(r, "text/plain"); - ap_rprintf("Enabled: %u\n", config->enabled); - ap_rprintf("Path: %s\n", config->path); - ap_rprintf("TypeOfAction: %x\n", config->typeOfAction); - ap_rprintf("Context: %s\n", config->context); - return OK; -} -

+
+static int example_handler(request_rec *r)
+{
+    if(!r->handler || strcmp(r->handler, "example-handler")) return(DECLINED);
+    example_config *config = (example_config*) ap_get_module_config(r->per_dir_config, &example_module);
+    ap_set_content_type(r, "text/plain");
+    ap_rprintf("Enabled: %u\n", config->enabled);
+    ap_rprintf("Path: %s\n", config->path);
+    ap_rprintf("TypeOfAction: %x\n", config->typeOfAction);
+    ap_rprintf("Context: %s\n", config->context);
+    return OK;
+}
+
@@ -1168,9 +1166,9 @@ a directive required five elements be set:

-

-AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"), -

+
+AP_INIT_TAKE1("exampleEnabled", example_set_enabled, NULL, RSRC_CONF, "Enable or disable mod_example"),
+
@@ -1191,18 +1189,18 @@ and managing our configurations. Since we have chosen the per-directory per-directory creator and merger function reference in our tag:

-

-module AP_MODULE_DECLARE_DATA example_module = -{ - STANDARD20_MODULE_STUFF, - create_dir_conf, /* Per-directory configuration handler */ - merge_dir_conf, /* Merge handler for per-directory configurations */ - NULL, /* Per-server configuration handler */ - NULL, /* Merge handler for per-server configurations */ - directives, /* Any directives we may have for httpd */ - register_hooks /* Our hook registering function */ -}; -

+
+module AP_MODULE_DECLARE_DATA   example_module =
+{
+    STANDARD20_MODULE_STUFF,
+    create_dir_conf, /* Per-directory configuration handler */
+    merge_dir_conf,  /* Merge handler for per-directory configurations */
+    NULL,            /* Per-server configuration handler */
+    NULL,            /* Merge handler for per-server configurations */
+    directives,      /* Any directives we may have for httpd */
+    register_hooks   /* Our hook registering function */
+};
+
@@ -1216,20 +1214,20 @@ 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:

-

-void* example_create_dir_conf(apr_pool_t* pool, char* context) { - context = context ? context : "(undefined context)"; - example_config *cfg = apr_pcalloc(pool, sizeof(example_config)); - if(cfg) { - /* Set some default values */ - strcpy(cfg->context, x); - cfg->enabled = 0; - cfg->path = "/foo/bar"; - cfg->typeOfAction = 0x11; - } - return cfg; -} -

+
+void* example_create_dir_conf(apr_pool_t* pool, char* context) {
+    context = context ? context : "(undefined context)";
+    example_config *cfg = apr_pcalloc(pool, sizeof(example_config));
+    if(cfg) {
+        /* Set some default values */
+        strcpy(cfg->context, x);
+        cfg->enabled = 0;
+        cfg->path = "/foo/bar";
+        cfg->typeOfAction = 0x11;
+    }
+    return cfg;
+}
+
@@ -1272,19 +1270,19 @@ two configurations and decide how they are to be merged:

-

-void* merge_dir_conf(apr_pool_t* pool, void* BASE, void* ADD) { - example_config* base = (example_config *) BASE ; - example_config* add = (example_config *) ADD ; - example_config* conf = (example_config *) create_dir_conf(pool, "Merged configuration"); +

+void* merge_dir_conf(apr_pool_t* pool, void* BASE, void* ADD) {
+    example_config* base = (example_config *) BASE ;
+    example_config* add = (example_config *) ADD ;
+    example_config* conf = (example_config *) create_dir_conf(pool, "Merged configuration");
     
-    conf->enabled = ( add->enabled == 0 ) ? base->enabled : add->enabled ;
-    conf->typeOfAction = add->typeOfAction ? add->typeOfAction : base->typeOfAction;
-    strcpy(conf->path, strlen(add->path) ? add->path : base->path);
+    conf->enabled = ( add->enabled == 0 ) ? base->enabled : add->enabled ;
+    conf->typeOfAction = add->typeOfAction ? add->typeOfAction : base->typeOfAction;
+    strcpy(conf->path, strlen(add->path) ? add->path : base->path);
     
-    return conf ;
-}
-

+ return conf ; +} +
@@ -1322,232 +1320,232 @@ added some prototypes to keep the compiler happy:

-

-/*$6 - +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * mod_example_config.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" - -/*$1 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -    Configuration structure - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -typedef struct -{ - char context[256]; - char path[256]; - int typeOfAction; - int enabled; -} example_config; - -/*$1 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -    Prototypes - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -static int example_handler(request_rec *r); -const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg); -const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg); -const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char *arg2); -void *create_dir_conf(apr_pool_t *pool, char *context); -void *merge_dir_conf(apr_pool_t *pool, void *BASE, void *ADD); -static void register_hooks(apr_pool_t *pool); - -/*$1 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -    Configuration directives - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -static const command_rec directives[] = -{ - 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!"), - { NULL } -}; - -/*$1 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -    Our name tag - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -module AP_MODULE_DECLARE_DATA example_module = -{ - STANDARD20_MODULE_STUFF, - create_dir_conf, /* Per-directory configuration handler */ - merge_dir_conf, /* Merge handler for per-directory configurations */ - NULL, /* Per-server configuration handler */ - NULL, /* Merge handler for per-server configurations */ - directives, /* Any directives we may have for httpd */ - register_hooks /* Our hook registering function */ -}; - -/* - ======================================================================================================================= -    Hook registration function - ======================================================================================================================= - */ -static void register_hooks(apr_pool_t *pool) -{ - ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST); -} - -/* - ======================================================================================================================= -    Our example web service handler - ======================================================================================================================= - */ -static int example_handler(request_rec *r) -{ - if(!r->handler || strcmp(r->handler, "example-handler")) return(DECLINED); - - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - example_config *config = (example_config *) ap_get_module_config(r->per_dir_config, &example_module); - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - - ap_set_content_type(r, "text/plain"); - ap_rprintf(r, "Enabled: %u\n", config->enabled); - ap_rprintf(r, "Path: %s\n", config->path); - ap_rprintf(r, "TypeOfAction: %x\n", config->typeOfAction); - ap_rprintf(r, "Context: %s\n", config->context); - return OK; -} - -/* - ======================================================================================================================= -    Handler for the "exambleEnabled" directive - ======================================================================================================================= - */ -const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg) -{ - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - example_config *conf = (example_config *) cfg; - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - - if(conf) - { - if(!strcasecmp(arg, "on")) - conf->enabled = 1; - else - conf->enabled = 0; - } - - return NULL; -} - -/* - ======================================================================================================================= -    Handler for the "examplePath" directive - ======================================================================================================================= - */ -const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg) -{ - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - example_config *conf = (example_config *) cfg; - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - - if(conf) - { - strcpy(conf->path, arg); - } - - return NULL; -} - -/* - ======================================================================================================================= -    Handler for the "exampleAction" directive ; -    Let's pretend this one takes one argument (file or db), and a second (deny or allow), ; -    and we store it in a bit-wise manner. - ======================================================================================================================= - */ -const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char *arg2) -{ - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - example_config *conf = (example_config *) cfg; - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - - if(conf) - { - { - if(!strcasecmp(arg1, "file")) - conf->typeOfAction = 0x01; - else - conf->typeOfAction = 0x02; - if(!strcasecmp(arg2, "deny")) - conf->typeOfAction += 0x10; - else - conf->typeOfAction += 0x20; - } - } - - return NULL; -} - -/* - ======================================================================================================================= -    Function for creating new configurations for per-directory contexts - ======================================================================================================================= - */ -void *create_dir_conf(apr_pool_t *pool, char *context) -{ - context = context ? context : "Newly created configuration"; - - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - example_config *cfg = apr_pcalloc(pool, sizeof(example_config)); - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - - if(cfg) - { - { - /* Set some default values */ - strcpy(cfg->context, context); - cfg->enabled = 0; - memset(cfg->path, 0, 256); - cfg->typeOfAction = 0x00; - } - } - - return cfg; -} - -/* - ======================================================================================================================= -    Merging function for configurations - ======================================================================================================================= - */ -void *merge_dir_conf(apr_pool_t *pool, void *BASE, void *ADD) -{ - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - example_config *base = (example_config *) BASE; - example_config *add = (example_config *) ADD; - example_config *conf = (example_config *) create_dir_conf(pool, "Merged configuration"); - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - - conf->enabled = (add->enabled == 0) ? base->enabled : add->enabled; - conf->typeOfAction = add->typeOfAction ? add->typeOfAction : base->typeOfAction; - strcpy(conf->path, strlen(add->path) ? add->path : base->path); - return conf; -} -

+
+/*$6
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * mod_example_config.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"
+
+/*$1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    Configuration structure
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+typedef struct
+{
+    char    context[256];
+    char    path[256];
+    int     typeOfAction;
+    int     enabled;
+} example_config;
+
+/*$1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    Prototypes
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+static int    example_handler(request_rec *r);
+const char    *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg);
+const char    *example_set_path(cmd_parms *cmd, void *cfg, const char *arg);
+const char    *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char *arg2);
+void          *create_dir_conf(apr_pool_t *pool, char *context);
+void          *merge_dir_conf(apr_pool_t *pool, void *BASE, void *ADD);
+static void   register_hooks(apr_pool_t *pool);
+
+/*$1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    Configuration directives
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+static const command_rec    directives[] =
+{
+    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!"),
+    { NULL }
+};
+
+/*$1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    Our name tag
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+module AP_MODULE_DECLARE_DATA    example_module =
+{
+    STANDARD20_MODULE_STUFF,
+    create_dir_conf,    /* Per-directory configuration handler */
+    merge_dir_conf,     /* Merge handler for per-directory configurations */
+    NULL,               /* Per-server configuration handler */
+    NULL,               /* Merge handler for per-server configurations */
+    directives,         /* Any directives we may have for httpd */
+    register_hooks      /* Our hook registering function */
+};
+
+/*
+ =======================================================================================================================
+    Hook registration function
+ =======================================================================================================================
+ */
+static void register_hooks(apr_pool_t *pool)
+{
+    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
+}
+
+/*
+ =======================================================================================================================
+    Our example web service handler
+ =======================================================================================================================
+ */
+static int example_handler(request_rec *r)
+{
+    if(!r->handler || strcmp(r->handler, "example-handler")) return(DECLINED);
+
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+    example_config    *config = (example_config *) ap_get_module_config(r->per_dir_config, &example_module);
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+    ap_set_content_type(r, "text/plain");
+    ap_rprintf(r, "Enabled: %u\n", config->enabled);
+    ap_rprintf(r, "Path: %s\n", config->path);
+    ap_rprintf(r, "TypeOfAction: %x\n", config->typeOfAction);
+    ap_rprintf(r, "Context: %s\n", config->context);
+    return OK;
+}
+
+/*
+ =======================================================================================================================
+    Handler for the "exambleEnabled" directive
+ =======================================================================================================================
+ */
+const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg)
+{
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+    example_config    *conf = (example_config *) cfg;
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+    if(conf)
+    {
+        if(!strcasecmp(arg, "on"))
+            conf->enabled = 1;
+        else
+            conf->enabled = 0;
+    }
+
+    return NULL;
+}
+
+/*
+ =======================================================================================================================
+    Handler for the "examplePath" directive
+ =======================================================================================================================
+ */
+const char *example_set_path(cmd_parms *cmd, void *cfg, const char *arg)
+{
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+    example_config    *conf = (example_config *) cfg;
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+    if(conf)
+    {
+        strcpy(conf->path, arg);
+    }
+
+    return NULL;
+}
+
+/*
+ =======================================================================================================================
+    Handler for the "exampleAction" directive ;
+    Let's pretend this one takes one argument (file or db), and a second (deny or allow), ;
+    and we store it in a bit-wise manner.
+ =======================================================================================================================
+ */
+const char *example_set_action(cmd_parms *cmd, void *cfg, const char *arg1, const char *arg2)
+{
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+    example_config    *conf = (example_config *) cfg;
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+    if(conf)
+    {
+        {
+            if(!strcasecmp(arg1, "file"))
+                conf->typeOfAction = 0x01;
+            else
+                conf->typeOfAction = 0x02;
+            if(!strcasecmp(arg2, "deny"))
+                conf->typeOfAction += 0x10;
+            else
+                conf->typeOfAction += 0x20;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ =======================================================================================================================
+    Function for creating new configurations for per-directory contexts
+ =======================================================================================================================
+ */
+void *create_dir_conf(apr_pool_t *pool, char *context)
+{
+    context = context ? context : "Newly created configuration";
+
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+    example_config    *cfg = apr_pcalloc(pool, sizeof(example_config));
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+    if(cfg)
+    {
+        {
+            /* Set some default values */
+            strcpy(cfg->context, context);
+            cfg->enabled = 0;
+            memset(cfg->path, 0, 256);
+            cfg->typeOfAction = 0x00;
+        }
+    }
+
+    return cfg;
+}
+
+/*
+ =======================================================================================================================
+    Merging function for configurations
+ =======================================================================================================================
+ */
+void *merge_dir_conf(apr_pool_t *pool, void *BASE, void *ADD)
+{
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+    example_config    *base = (example_config *) BASE;
+    example_config    *add = (example_config *) ADD;
+    example_config    *conf = (example_config *) create_dir_conf(pool, "Merged configuration");
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+    conf->enabled = (add->enabled == 0) ? base->enabled : add->enabled;
+    conf->typeOfAction = add->typeOfAction ? add->typeOfAction : base->typeOfAction;
+    strcpy(conf->path, strlen(add->path) ? add->path : base->path);
+    return conf;
+}
+
@@ -1573,33 +1571,33 @@ or check out the rest of our documentation for further tips. -

-const char *read_post_value(const apr_array_header_t *fields, const char *key) -{ - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - int i; - apr_table_entry_t *e = 0; - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - e = (apr_table_entry_t *) fields->elts; - for(i = 0; i < fields->nelts; i++) { - if(!strcmp(e[i].key, key)) return e[i].val; - } - return 0; -} -static int example_handler(request_req *r) -{ - /*~~~~~~~~~~~~~~~~~~~~~~*/ - apr_array_header_t *POST; - const char *value; - /*~~~~~~~~~~~~~~~~~~~~~~*/ - ap_parse_form_data(r, NULL, &POST, -1, 8192); +

+const char *read_post_value(const apr_array_header_t *fields, const char *key) 
+{
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+    int                         i;
+    apr_table_entry_t           *e = 0;
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+    e = (apr_table_entry_t *) fields->elts;
+    for(i = 0; i < fields->nelts; i++) {
+        if(!strcmp(e[i].key, key)) return e[i].val;
+    }
+    return 0;
+}
+static int example_handler(request_req *r) 
+{
+    /*~~~~~~~~~~~~~~~~~~~~~~*/
+    apr_array_header_t *POST;
+    const char         *value;
+    /*~~~~~~~~~~~~~~~~~~~~~~*/
+    ap_parse_form_data(r, NULL, &POST, -1, 8192);
     
-    value = read_post_value(POST, "valueA");
-    if (!value) value = "(undefined)";
-    ap_rprintf(r, "The value of valueA is: %s", value);
-    return OK;
-}
-

+ value = read_post_value(POST, "valueA"); + if (!value) value = "(undefined)"; + ap_rprintf(r, "The value of valueA is: %s", value); + return OK; +} +
@@ -1609,23 +1607,22 @@ or check out the rest of our documentation for further tips. -

-static int example_handler(request_req *r) -{ - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - const apr_array_header_t *fields; - int i; - apr_table_entry_t *e = 0; - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - - fields = apr_table_elts(r->headers_in); - e = (apr_table_entry_t *) fields->elts; - for(i = 0; i < fields->nelts; i++) { - ap_rprintf(r, "<b>%s</b>: %s<br/>", e[i].key, e[i].val); - } - return OK; -} -

+
+static int example_handler(request_req *r) 
+{
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+    const apr_array_header_t    *fields;
+    int                         i;
+    apr_table_entry_t           *e = 0;
+    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+    fields = apr_table_elts(r->headers_in);
+    e = (apr_table_entry_t *) fields->elts;
+    for(i = 0; i < fields->nelts; i++) {
+        ap_rprintf(r, "<b>%s</b>: %s<br/>", e[i].key, e[i].val);
+    }
+    return OK;
+}
@@ -1635,55 +1632,55 @@ or check out the rest of our documentation for further tips. -

-static int util_read(request_rec *r, const char **rbuf, apr_off_t *size) -{ - /*~~~~~~~~*/ - int rc = OK; - /*~~~~~~~~*/ - - if((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) { - return(rc); - } - - if(ap_should_client_block(r)) { - - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - char argsbuffer[HUGE_STRING_LEN]; - apr_off_t rsize, len_read, rpos = 0; - apr_off_t length = r->remaining; - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - - *rbuf = (const char *) apr_pcalloc(r->pool, (apr_size_t) (length + 1)); - *size = length; - while((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0) { - if((rpos + len_read) > length) { - rsize = length - rpos; - } - else { - rsize = len_read; - } - - memcpy((char *) *rbuf + rpos, argsbuffer, (size_t) rsize); - rpos += rsize; - } - } - return(rc); -} - -static int example_handler(request_req* r) -{ - /*~~~~~~~~~~~~~~~~*/ - apr_off_t size; - const char *buffer; - /*~~~~~~~~~~~~~~~~*/ - - if(util_read(r, &data, &size) == OK) { - ap_rprintf("We read a request body that was %u bytes long", size); - } - return OK; -} -

+
+static int util_read(request_rec *r, const char **rbuf, apr_off_t *size)
+{
+    /*~~~~~~~~*/
+    int rc = OK;
+    /*~~~~~~~~*/
+
+    if((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
+        return(rc);
+    }
+
+    if(ap_should_client_block(r)) {
+
+        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+        char         argsbuffer[HUGE_STRING_LEN];
+        apr_off_t    rsize, len_read, rpos = 0;
+        apr_off_t length = r->remaining;
+        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+        *rbuf = (const char *) apr_pcalloc(r->pool, (apr_size_t) (length + 1));
+        *size = length;
+        while((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0) {
+            if((rpos + len_read) > length) {
+                rsize = length - rpos;
+            }
+            else {
+                rsize = len_read;
+            }
+
+            memcpy((char *) *rbuf + rpos, argsbuffer, (size_t) rsize);
+            rpos += rsize;
+        }
+    }
+    return(rc);
+}
+
+static int example_handler(request_req* r) 
+{
+    /*~~~~~~~~~~~~~~~~*/
+    apr_off_t   size;
+    const char  *buffer;
+    /*~~~~~~~~~~~~~~~~*/
+
+    if(util_read(r, &data, &size) == OK) {
+        ap_rprintf("We read a request body that was %u bytes long", size);
+    }
+    return OK;
+}
+