modules.html revision bf8889c98dd1b7b4daf701cdf96652d5c9afb837
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
f3091cedd4abeda1026d9117c34e8f625754e8aefielding<TITLE>Converting Modules from Apache 1.3 to Apache 2.0</TITLE>
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding BGCOLOR="#FFFFFF"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding TEXT="#000000"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding LINK="#0000FF"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding VLINK="#000080"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ALINK="#FF0000"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding<!--#include virtual="header.html" -->
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding<H1 ALIGN="CENTER">From Apache 1.3 to Apache 2.0<br>Modules</H1>
f3091cedd4abeda1026d9117c34e8f625754e8aefieldingThis 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.
f3091cedd4abeda1026d9117c34e8f625754e8aefielding<h2>The easier changes...
f3091cedd4abeda1026d9117c34e8f625754e8aefieldingThese 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.
f3091cedd4abeda1026d9117c34e8f625754e8aefieldingThese 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
f3091cedd4abeda1026d9117c34e8f625754e8aefieldingThroughout Apache the old pools have been replced by the ap_context_t, though their use remains remarkably similar.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingA 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.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingThe 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.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingThis is the code that was added to mod_mmap_static
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void register_hooks(void)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding static const char * const aszPre[]={ "http_core.c",NULL };
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingThis 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?
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingap_hook_[phase_name](function_name, predecessors, successors, position);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingThere are 3 hook positions defined...
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingTo 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).
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingIn 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.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingThere are now a lot fewer stages to worry about when creating your module definition. The old defintion looked like
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingmodule MODULE_VAR_EXPORT [module_name]_module =
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding STANDARD_MODULE_STUFF,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* initializer */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* dir config creater */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* dir merger --- default is to override */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* server config */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* merge server config */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* command handlers */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* handlers */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* filename translation */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* check_user_id */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* check auth */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* check access */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* type_checker */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* fixups */
cccd31fa4a72fe23cc3249c06db181b274a55a69gstein /* logger */
cccd31fa4a72fe23cc3249c06db181b274a55a69gstein /* header parser */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* child_init */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* child_exit */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* post read-request */
cccd31fa4a72fe23cc3249c06db181b274a55a69gsteinThe new structure is a great deal simpler...
cccd31fa4a72fe23cc3249c06db181b274a55a69gsteinmodule MODULE_VAR_EXPORT [module_name]_module =
1860b2b5f1de31f8cf9d95f1b394fe98c8dbfab7rbb STANDARD20_MODULE_STUFF,
1860b2b5f1de31f8cf9d95f1b394fe98c8dbfab7rbb /* create per-directory config structures */
cccd31fa4a72fe23cc3249c06db181b274a55a69gstein /* merge per-directory config structures */
b980ad7fdc218b4855cde9f75a747527f50c554dwrowe /* create per-server config structures */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* merge per-server config structures */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbb /* command handlers */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* handlers */
bb65aeae7af1d33b64252bbc1b966942d757ac60wrowe /* register hooks */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbbSome of these read directly across, some don't. I'll try to summarise what should be done below.
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbbThe stages that read directly across :
48d7c43629323c8d5ee9f7bd0d194de0a376b391rbb/* dir config creater */ ==> /* create per-directory config structures */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* server config */ ==> /* create per-server config structures */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* dir merger */ ==> /* merge per-directory config structures */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* merge server config */ ==> /* merge per-server config structures */
c53a68af52e2428d833746388b412fb4793759b2trawick/* command table */ ==> /* command ap_table_t */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm/* handlers */ ==> /* handlers */
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbbThe remainder of the old functions should be registered as hooks. There are the following hook stages defined so far...
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbbap_hook_post_config <em>(this is where the old _init routines get registered)</em>
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingap_hook_http_method
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbbap_hook_open_logs
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingap_hook_auth_checker
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingap_hook_default_port
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbbap_hook_access_checker
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbbap_hook_process_connection
f4a8b04b47f09a21b65646b66b19c9649ff7f03arbbap_hook_child_init_hook
c330df4777ee0ff23f104003559a5c4c9e0e5070trawick<!--#include virtual="footer.html" -->