Return-Path: X-Original-To: apmail-httpd-cvs-archive@www.apache.org Delivered-To: apmail-httpd-cvs-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B81D49139 for ; Tue, 24 Apr 2012 14:59:34 +0000 (UTC) Received: (qmail 83513 invoked by uid 500); 24 Apr 2012 14:59:34 -0000 Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 83460 invoked by uid 500); 24 Apr 2012 14:59:34 -0000 Mailing-List: contact cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 83451 invoked by uid 99); 24 Apr 2012 14:59:34 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 24 Apr 2012 14:59:34 +0000 X-ASF-Spam-Status: No, hits=-1998.1 required=5.0 tests=ALL_TRUSTED,FUZZY_AMBIEN X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 24 Apr 2012 14:59:20 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id E06652388865; Tue, 24 Apr 2012 14:58:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1329774 - /httpd/httpd/trunk/docs/manual/developer/modguide.xml Date: Tue, 24 Apr 2012 14:58:57 -0000 To: cvs@httpd.apache.org From: humbedooh@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120424145857.E06652388865@eris.apache.org> Author: humbedooh Date: Tue Apr 24 14:58:57 2012 New Revision: 1329774 URL: http://svn.apache.org/viewvc?rev=1329774&view=rev Log: Removed all manual styling, prepping for dynamic SH instead Modified: httpd/httpd/trunk/docs/manual/developer/modguide.xml Modified: httpd/httpd/trunk/docs/manual/developer/modguide.xml URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/developer/modguide.xml?rev=1329774&r1=1329773&r2=1329774&view=diff ============================================================================== --- httpd/httpd/trunk/docs/manual/developer/modguide.xml (original) +++ httpd/httpd/trunk/docs/manual/developer/modguide.xml Tue Apr 24 14:58:57 2012 @@ -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 l

-

-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

-

-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!"); - - /* 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; -} -

+
+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!");
+    
+    /* 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.

structure are:

    -
  • r->handler (char*): Contains the name of the handler the server is currently asking to do the handling of this request
  • -
  • r->method (char*): Contains the HTTP method being used, f.x. GET or POST
  • -
  • r->filename (char*): Contains the translated filename the client is requesting
  • -
  • r->args (char*): Contains the query string of the request, if any
  • -
  • r->headers_in (apr_table_t*): Contains all the headers sent by the client
  • -
  • r->connection (conn_rec*): A record containing information about the current connection
  • -
  • r->useragent_ip (char*): The IP address of the client connecting to us
  • -
  • r->pool (apr_pool_t*): The memory pool of this request. We'll discuss this in the " +
  • r->handler (char*): Contains the name of the handler the server is currently asking to do the handling of this request
  • +
  • r->method (char*): Contains the HTTP method being used, f.x. GET or POST
  • +
  • r->filename (char*): Contains the translated filename the client is requesting
  • +
  • r->args (char*): Contains the query string of the request, if any
  • +
  • r->headers_in (apr_table_t*): Contains all the headers sent by the client
  • +
  • r->connection (conn_rec*): A record containing information about the current connection
  • +
  • r->useragent_ip (char*): The IP address of the client connecting to us
  • +
  • r->pool (apr_pool_t*): The memory pool of this request. We'll discuss this in the " Memory management" chapter.

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

-

-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; -} -

+
+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;
+}
+
@@ -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 handle -

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

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

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 handle -

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, h

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, ...) -

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

+
+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); 
+    
+    /* 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 ne -

-/* 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; - - - /* 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 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 */ - - 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"); - - /* 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"; +

+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);
+    
+    /* 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;
+    
+    /* 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);
+    
+    /* 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);
+    
+    /* 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 set -

-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 directive

-

+

 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 directiv

-

+

 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 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; - - if(!strcasecmp(arg2, "deny")) config.typeOfAction += 0x10; - else config.typeOfAction += 0x20; - return NULL; -} -

+
+/* 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;
+}
+
@@ -936,120 +933,120 @@ we can assemble our module into one big

-

-/* 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 */ -}; -

+
+/* 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 */
+};
+
@@ -1110,10 +1107,11 @@ directory or location in question? It do

-

+

+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 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); [... 799 lines stripped ...]