modules.html.en revision bbbd690dc97941b1496fc940380969d3737f9ca1
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<HTML>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<HEAD>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<TITLE>Converting Modules from Apache 1.3 to Apache 2.0</TITLE>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</HEAD>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<BODY
bbbd690dc97941b1496fc940380969d3737f9ca1dreid BGCOLOR="#FFFFFF"
bbbd690dc97941b1496fc940380969d3737f9ca1dreid TEXT="#000000"
bbbd690dc97941b1496fc940380969d3737f9ca1dreid LINK="#0000FF"
bbbd690dc97941b1496fc940380969d3737f9ca1dreid VLINK="#000080"
bbbd690dc97941b1496fc940380969d3737f9ca1dreid ALINK="#FF0000"
bbbd690dc97941b1496fc940380969d3737f9ca1dreid>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<H1 ALIGN="CENTER">From Apache 1.3 to Apache 2.0<br>Modules</H1>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThis is a first attempt at writing the lessons I learned when trying to convert the mod_mmap_static module to Apache 2.0. It's by no means definitive and probably won't even be correct in some ways, but it's a start.
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<hr>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<h2>The easier changes...
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</h2>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<h3>Cleanup Routines</h3>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThese now need to be of type ap_status_t and return a value of that type. Normally the return value will be APR_SUCCESS unless there is some need to signal an error in the cleanup. Be aware that even though you signal an error not all code yet checks and acts upon the error.
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<h3>Initialisation Routines</h3>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThese should now be renamed to better signify where they sit in the overall process. So the name gets a small change from mmap_init to mmap_post_config. The arguments passed have undergone a radical change and now look like
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<ul style="list-style:none">
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>ap_context_t *p,</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>ap_context_t *plog,</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>ap_context_t *ptemp,</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>server_rec *s</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</ul>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThroughout Apache the old pools have been replced by the ap_context_t, though their use remains remarkably similar.
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<h3>Data Types</h3>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidA lot of the data types have been moved into the APR. This means that some have had a name change, such as the one shown above. The following is a brief list of some of the changes that you are likely to have to make.
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<ul style="list-style:none">
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>pool becomes ap_context_t</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>table becomes ap_table_t</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</ul>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<hr>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<h2>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThe <em>messier</em> changes...
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</h2>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<h3>Register Hooks</h3>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThe new architecture uses a series of hooks to provide for calling your functions. These you'll need to add to your module by way of a new function, static void register_hooks(void). The function is really reasonably straightforward once you understand what needs to be done. Each function that needs calling at some stage in the processing of a request needs to be registered, handlers do not. There are a number of phases where functions can be added, and for each you can specify with a high degree of control the relative order that the function will be called in.
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThis is the code that was added to mod_mmap_static
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<pre>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidstatic void register_hooks(void)
bbbd690dc97941b1496fc940380969d3737f9ca1dreid{
bbbd690dc97941b1496fc940380969d3737f9ca1dreid static const char * const aszPre[]={ "http_core.c",NULL };
bbbd690dc97941b1496fc940380969d3737f9ca1dreid ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE);
bbbd690dc97941b1496fc940380969d3737f9ca1dreid ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST);
bbbd690dc97941b1496fc940380969d3737f9ca1dreid};
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</pre>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThis registers 2 functions that need to be called, one in the post_config stage (virtually every module will need this one) and one for the translate_name phase. note that while there are different function names the format of each is identical. So what is the format?
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p><strong>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidap_hook_[phase_name](function_name, predecessors, successors, position);
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</strong></p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThere are 3 hook positions defined...
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<ul style="list-style:none">
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>HOOK_FIRST</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>HOOK_MIDDLE</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>HOOK_LAST</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</ul>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidTo define the position you use the position and then modify it with the predecessors and successors. each of the modifiers can be a list of functions that should be called, either before the function is run (predecessors) or after the function has run (successors).
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidIn the mod_mmap_static case I didn't care about the post_config stage, but the mmap_static_xlat MUST be called after the core module had done it's name translation, hence the use of the aszPre to define a modifier to the position HOOK_LAST.
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<h3>Module Definition</h3>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThere are now a lot fewer stages to worry about when creating your module definition. The old defintion looked like
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<pre>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidmodule MODULE_VAR_EXPORT [module_name]_module =
bbbd690dc97941b1496fc940380969d3737f9ca1dreid{
bbbd690dc97941b1496fc940380969d3737f9ca1dreid STANDARD_MODULE_STUFF,
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* initializer */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* dir config creater */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* dir merger --- default is to override */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* server config */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* merge server config */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* command handlers */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* handlers */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* filename translation */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* check_user_id */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* check auth */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* check access */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* type_checker */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* fixups */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* logger */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* header parser */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* child_init */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* child_exit */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* post read-request */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid};
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</pre>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThe new structure is a great deal simpler...
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<pre>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidmodule MODULE_VAR_EXPORT [module_name]_module =
bbbd690dc97941b1496fc940380969d3737f9ca1dreid{
bbbd690dc97941b1496fc940380969d3737f9ca1dreid STANDARD20_MODULE_STUFF,
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* create per-directory config structures */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* merge per-directory config structures */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* create per-server config structures */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* merge per-server config structures */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* command handlers */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* handlers */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid /* register hooks */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid };
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</pre>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidSome of these read directly across, some don't. I'll try to summarise what should be done below.
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThe stages that read directly across :
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</p>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<ul style="list-style:none">
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid/* dir config creater */ ==> /* create per-directory config structures */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid/* server config */ ==> /* create per-server config structures */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid/* dir merger */ ==> /* merge per-directory config structures */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid/* merge server config */ ==> /* merge per-server config structures */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid/* command table */ ==> /* command ap_table_t */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid/* handlers */ ==> /* handlers */
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</ul>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<P>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidThe remainder of the old functions should be registered as hooks. There are the following hook stages defined so far...
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</P>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<ul style="list-style:none">
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidap_hook_post_config <em>(this is where the old _init routines get registered)</em>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidap_hook_http_method
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidap_hook_open_logs
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidap_hook_auth_checker
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidap_hook_default_port
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidap_hook_access_checker
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidap_hook_process_connection
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid<li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreidap_hook_child_init_hook
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</li>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</body>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid</html>
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid
bbbd690dc97941b1496fc940380969d3737f9ca1dreid