| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| |
| <html xmlns="http://www.w3.org/1999/xhtml"> |
| <head> |
| <meta name="generator" content="HTML Tidy, see www.w3.org" /> |
| |
| <title>Converting Modules from Apache 1.3 to Apache 2.0</title> |
| </head> |
| <!-- Background white, links blue (unvisited), navy (visited), red (active) --> |
| |
| <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" |
| vlink="#000080" alink="#FF0000"> |
| <!--#include virtual="header.html" --> |
| |
| <h1 align="CENTER">From Apache 1.3 to Apache 2.0<br /> |
| Modules</h1> |
| |
| <p>This 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.</p> |
| <hr /> |
| |
| <h2>The easier changes...</h2> |
| |
| <h3>Cleanup Routines</h3> |
| |
| <p>These now need to be of type apr_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.</p> |
| |
| <h3>Initialisation Routines</h3> |
| |
| <p>These 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</p> |
| |
| <ul style="list-style:none"> |
| <li>apr_pool_t *p,</li> |
| |
| <li>apr_pool_t *plog,</li> |
| |
| <li>apr_pool_t *ptemp,</li> |
| |
| <li>server_rec *s</li> |
| </ul> |
| |
| <h3>Data Types</h3> |
| |
| <p>A 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.</p> |
| |
| <ul style="list-style:none"> |
| <li>pool becomes apr_pool_t</li> |
| |
| <li>table becomes apr_table_t</li> |
| </ul> |
| <hr /> |
| |
| <h2>The <em>messier</em> changes...</h2> |
| |
| <h3>Register Hooks</h3> |
| |
| <p>The 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.</p> |
| |
| <p>This is the code that was added to mod_mmap_static:</p> |
| <pre> |
| static void register_hooks(void) |
| { |
| static const char * const aszPre[]={ "http_core.c",NULL }; |
| ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE); |
| ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST); |
| }; |
| </pre> |
| |
| <p>This 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?</p> |
| |
| <p><strong>ap_hook_[phase_name](function_name, predecessors, |
| successors, position);</strong></p> |
| |
| <p>There are 3 hook positions defined...</p> |
| |
| <ul style="list-style:none"> |
| <li>HOOK_FIRST</li> |
| |
| <li>HOOK_MIDDLE</li> |
| |
| <li>HOOK_LAST</li> |
| </ul> |
| |
| <p>To 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).</p> |
| |
| <p>In 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.</p> |
| |
| <h3>Module Definition</h3> |
| |
| <p>There are now a lot fewer stages to worry about when |
| creating your module definition. The old defintion looked |
| like</p> |
| <pre> |
| module MODULE_VAR_EXPORT [module_name]_module = |
| { |
| STANDARD_MODULE_STUFF, |
| /* initializer */ |
| /* dir config creater */ |
| /* dir merger --- default is to override */ |
| /* server config */ |
| /* merge server config */ |
| /* command handlers */ |
| /* handlers */ |
| /* filename translation */ |
| /* check_user_id */ |
| /* check auth */ |
| /* check access */ |
| /* type_checker */ |
| /* fixups */ |
| /* logger */ |
| /* header parser */ |
| /* child_init */ |
| /* child_exit */ |
| /* post read-request */ |
| }; |
| </pre> |
| |
| <p>The new structure is a great deal simpler...</p> |
| <pre> |
| module MODULE_VAR_EXPORT [module_name]_module = |
| { |
| STANDARD20_MODULE_STUFF, |
| /* create per-directory config structures */ |
| /* merge per-directory config structures */ |
| /* create per-server config structures */ |
| /* merge per-server config structures */ |
| /* command handlers */ |
| /* handlers */ |
| /* register hooks */ |
| }; |
| </pre> |
| |
| <p>Some of these read directly across, some don't. I'll try to |
| summarise what should be done below.</p> |
| |
| <p>The stages that read directly across :</p> |
| |
| <ul style="list-style:none"> |
| <li>/* dir config creater */ ==> /* create per-directory |
| config structures */</li> |
| |
| <li>/* server config */ ==> /* create per-server config |
| structures */</li> |
| |
| <li>/* dir merger */ ==> /* merge per-directory config |
| structures */</li> |
| |
| <li>/* merge server config */ ==> /* merge per-server |
| config structures */</li> |
| |
| <li>/* command table */ ==> /* command apr_table_t */</li> |
| |
| <li>/* handlers */ ==> /* handlers */</li> |
| </ul> |
| |
| <p>The remainder of the old functions should be registered as |
| hooks. There are the following hook stages defined so |
| far...</p> |
| |
| <ul style="list-style:none"> |
| <li>ap_hook_post_config <em>(this is where the old _init |
| routines get registered)</em></li> |
| |
| <li>ap_hook_http_method <em>(retrieve the http method from a |
| request. (legacy))</em></li> |
| |
| <li>ap_hook_open_logs <em>(open any specified logs)</em></li> |
| |
| <li>ap_hook_auth_checker <em>(check if the resource requires |
| authorization)</em></li> |
| |
| <li>ap_hook_access_checker <em>(check for module-specific |
| restrictions)</em></li> |
| |
| <li>ap_hook_check_user_id <em>(check the user-id and |
| password)</em></li> |
| |
| <li>ap_hook_default_port <em>(retrieve the default port for |
| the server)</em></li> |
| |
| <li>ap_hook_pre_connection <em>(do any setup required just |
| before processing, but after accepting)</em></li> |
| |
| <li>ap_hook_process_connection <em>(run the correct |
| protocol)</em></li> |
| |
| <li>ap_hook_child_init <em>(call as soon as the child is |
| started)</em></li> |
| |
| <li>ap_hook_create_request <em>(??)</em></li> |
| |
| <li>ap_hook_fixups <em>(last chance to modify things before |
| generating content)</em></li> |
| |
| <li>ap_hook_handler <em>(generate the content)</em></li> |
| |
| <li>ap_hook_header_parser <em>(let's modules look at the |
| headers, not used by most modules, because they use |
| post_read_request for this.)</em></li> |
| |
| <li>ap_hook_insert_filter <em>(to insert filters into the |
| filter chain)</em></li> |
| |
| <li>ap_hook_log_transaction <em>(log information about the |
| request)</em></li> |
| |
| <li>ap_hook_optional_fn_retrieve <em>(retrieve any functions |
| registered as optional)</em></li> |
| |
| <li>ap_hook_post_read_request <em>(called after reading the |
| request, before any other phase)</em></li> |
| |
| <li>ap_hook_quick_handler <em>(??)</em></li> |
| |
| <li>ap_hook_translate_name <em>(translate the URI into a |
| filename)</em></li> |
| |
| <li>ap_hook_type_checker <em>(determine and/or set the doc |
| type)</em> <!--#include virtual="footer.html" --> |
| </li> |
| </ul> |
| </body> |
| </html> |
| |