]> granicus.if.org Git - apache/blobdiff - docs/manual/developer/modguide.html.en
xforms
[apache] / docs / manual / developer / modguide.html.en
index 8035ff0de06b2a143f38c1b9b700bc7de3cab0dd..91fffe1cb9b36846c8f4bf0a8c02935ff57f6865 100644 (file)
@@ -41,7 +41,7 @@ Server 2.4</p>
 <h2><a name="introduction" id="introduction">Introduction</a></h2>
 <h3><a name="what" id="what">What we will be discussing in this document</a></h3>
 <p>
-This document will discuss how you can easily create modules for the Apache 
+This document will discuss how you can create modules for the Apache 
 HTTP Server 2.4, by exploring an example module called 
 <code>mod_example</code>. In the first part of this document, the purpose 
 of this module will be to calculate and print out various digest values for 
@@ -248,6 +248,8 @@ can create. Some other ways of hooking are:
 <li><code>ap_hook_pre_config</code>: Place a hook that executes before any configuration data has been read (very early hook)</li>
 <li><code>ap_hook_post_config</code>: Place a hook that executes after configuration has been parsed, but before the server has forked</li>
 <li><code>ap_hook_translate_name</code>: Place a hook that executes when a URI needs to be translated into a filename on the server (think <code>mod_rewrite</code>)</li>
+<li><code>ap_hook_quick_handler</code>: Similar to <code>ap_hook_handler</code>, except it is run before any other request hooks (translation, auth, fixups etc)</li>
+<li><code>ap_hook_log_transaction</code>: Place a hook that executes when the server is about to add a log entry of the current request</li>
 </ul>
 
 
@@ -325,9 +327,10 @@ request_req </code> structure are:
 <li><code>r-&gt;args (char*):</code> Contains the query string of the request, if any</li>
 <li><code>r-&gt;headers_in (apr_table_t*):</code> Contains all the headers sent by the client</li>
 <li><code>r-&gt;connection (conn_rec*):</code> A record containing information about the current connection</li>
+<li><code>r-&gt;user (char*):</code> If the URI requires authentication, this is set to the username provided</li>
 <li><code>r-&gt;useragent_ip (char*):</code> The IP address of the client connecting to us</li>
-<li><code>r-&gt;pool (apr_pool_t*)</code>: The memory pool of this request. We'll discuss this in the "
-<a href="#memory">Memory management</a>" chapter.</li>
+<li><code>r-&gt;pool (apr_pool_t*)</code>: The memory pool of this request. We'll discuss this in the 
+"<a href="#memory">Memory management</a>" chapter.</li>
 </ul>
 <p>
 A complete list of all the values contained with in the <code>request_req</code> structure can be found in 
@@ -565,11 +568,14 @@ POST data is four simple lines:
 
 
 <pre class="prettyprint lang-c">
-<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__apr__tables.html#gad7ea82d6608a4a633fc3775694ab71e4">apr_table_t</a> *GET;
-<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/structapr__array__header__t.html">apr_array_header_t</a> *POST;
-
-<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__SCRIPT.html#gaed25877b529623a4d8f99f819ba1b7bd">ap_args_to_table</a>(r, &amp;GET);
-<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__DAEMON.html#ga9d426b6382b49754d4f87c55f65af202">ap_parse_form_data</a>(r, NULL, &amp;POST, -1, 8192);
+<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__apr__tables.html#gad7ea82d6608a4a633fc3775694ab71e4">apr_table_t</a> *GET; <em>
+</em><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/structapr__array__header__t.html">apr_array_header_t</a>*POST; 
+<em>
+</em>
+<a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__SCRIPT.html#gaed25877b529623a4d8f99f819ba1b7bd">
+ap_args_to_table</a>(r, &amp;GET); <em>
+</em><a href="http://ci.apache.org/projects/httpd/trunk/doxygen/group__APACHE__CORE__DAEMON.html#ga9d426b6382b49754d4f87c55f65af202">
+ap_parse_form_data</a>(r, NULL, &amp;POST, -1, 8192); 
 </pre>
 
 
@@ -1310,10 +1316,11 @@ two configurations and decide how they are to be merged:</p>
 
 <pre class="prettyprint lang-c">
 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");
+    example_config* base = (example_config *) BASE ; /* This is what was set in the parent context */
+    example_config* add = (example_config *) ADD ;   /* This is what is set in the new context */
+    example_config* conf = (example_config *) create_dir_conf(pool, "Merged configuration"); /* This will be the merged configuration */
     
+    /* Merge configurations */
     conf-&gt;enabled = ( add-&gt;enabled == 0 ) ? base-&gt;enabled : add-&gt;enabled ;
     conf-&gt;typeOfAction = add-&gt;typeOfAction ? add-&gt;typeOfAction : base-&gt;typeOfAction;
     strcpy(conf-&gt;path, strlen(add-&gt;path) ? add-&gt;path : base-&gt;path);
@@ -1608,34 +1615,56 @@ or check out the rest of our documentation for further tips.
 <div class="section">
 <h2><a name="snippets" id="snippets">Some useful snippets of code</a></h2>
 
-<h3><a name="get_post" id="get_post">Retrieve a variable from POST form data</a></h3>
+<h3><a name="get_post" id="get_post">Retrieve variables from POST form data</a></h3>
 
 
 
 <pre class="prettyprint lang-c">
-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-&gt;elts;
-    for(i = 0; i &lt; fields-&gt;nelts; i++) {
-        if(!strcmp(e[i].key, key)) return e[i].val;
+typedef struct {
+    const char* key;
+    const char* value;
+} keyValuePair;
+
+keyValuePair* readPost(request_req* r) {
+    apr_array_header_t *pairs = NULL;
+    apr_off_t len;
+    apr_size_t size;
+    int res;
+    int i = 0;
+    char *buffer;
+    keyValuePair* kvp;
+
+    res = ap_parse_form_data(r, NULL, &amp;pairs, -1, HUGE_STRING_LEN);
+    if (res != OK || !pairs) return NULL; /* Return NULL if we failed or if there are is no POST data */
+    kvp = apr_pcalloc(r-&gt;pool, sizeof(keyValuePair) * (pairs-&gt;nelts + 1));
+    while (pairs &amp;&amp; !apr_is_empty_array(pairs)) {
+        i++;
+        ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
+        apr_brigade_length(pair-&gt;value, 1, &amp;len);
+        size = (apr_size_t) len;
+        buffer = apr_palloc(r-&gt;pool, size + 1);
+        apr_brigade_flatten(pair-&gt;value, buffer, &amp;size);
+        buffer[len] = 0;
+        kvp[i]-&gt;key = apr_pstrdup(r-&gt;pool, pair-&gt;name);
+        kvp[i]-&gt;value = buffer;
     }
-    return 0;
+    return kvp;    
 }
+
 static int example_handler(request_req *r) 
 {
     /*~~~~~~~~~~~~~~~~~~~~~~*/
-    apr_array_header_t *POST;
-    const char         *value;
-    /*~~~~~~~~~~~~~~~~~~~~~~*/
-    ap_parse_form_data(r, NULL, &amp;POST, -1, 8192);
     
-    value = read_post_value(POST, "valueA");
-    if (!value) value = "(undefined)";
-    ap_rprintf(r, "The value of valueA is: %s", value);
+    keyValuePair* formData;
+    /*~~~~~~~~~~~~~~~~~~~~~~*/
+
+    formData = readPost();
+    if (formData) {
+        int i;
+        for (i = 0; formData[i]; i++) {
+            ap_rprintf(r, "%s = %s\n", formData[i]-&gt;key, formData[i]-&gt;value);
+        }
+    }
     return OK;
 }
 </pre>
@@ -1735,22 +1764,21 @@ static int example_handler(request_req* r)
 </div></div>
 <div class="bottomlang">
 <p><span>Available Languages: </span><a href="../en/developer/modguide.html" title="English">&nbsp;en&nbsp;</a></p>
-</div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>This section is experimental!</strong><br />Comments placed here should not be expected 
-to last beyond the testing phase of this system, nor do we in any way guarantee that we'll read them.</div>
+</div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our <a href="http://httpd.apache.org/lists.html">mailing lists</a>.</div>
 <script type="text/javascript"><!--//--><![CDATA[//><!--
-var disqus_shortname = 'httpd';
-var disqus_identifier = 'http://httpd.apache.org/docs/2.4/developer/modguide.html.en';
+var comments_shortname = 'httpd';
+var comments_identifier = 'http://httpd.apache.org/docs/trunk/developer/modguide.html';
 (function(w, d) {
     if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
-        d.write('<div id="disqus_thread"><\/div>');
+        d.write('<div id="comments_thread"><\/div>');
         var s = d.createElement('script');
         s.type = 'text/javascript';
         s.async = true;
-        s.src = 'http' + '://' + disqus_shortname + '.disqus.com/embed.js';
+        s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
         (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
     }
     else {
-        d.write('<div id="disqus_thread">Comments have been disabled for offline viewing.<\/div>');
+        d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
     }
 })(window, document);
 //--><!]]></script></div><div id="footer">