下面以log_config作例子
1 在modules.c 声明了这个变量.
#include "httpd.h"
#include "http_config.h"
extern module core_module;
......
extern module log_config_module;
......
extern module netware_module;
module *ap_prelinked_modules[] = {
&core_module, /* core must come first */
......
&log_config_module,
......
&netware_module,
NULL
};
ap_module_symbol_t ap_prelinked_module_symbols[] = {
{"core_module", &core_module},
......
{"log_config_module", &log_config_module},
......
{"netware_module", &netware_module},
{NULL, NULL}
};
module *ap_preloaded_modules[] = {
&core_module,
......
&log_config_module,
......
&netware_module,
NULL
};
2 在 mod_log_config.c 定义了这个变量:
module AP_MODULE_DECLARE_DATA log_config_module;
变量定义/初始化:
AP_DECLARE_MODULE(log_config) =
{
STANDARD20_MODULE_STUFF, /* 这个展开其实就是一些值 */
NULL, /* create per-dir config */
NULL, /* merge per-dir config */
make_config_log_state, /* server config */
merge_config_log_state, /* merge server config */
config_log_cmds, /* command apr_table_t */
register_hooks /* register hooks */
};
其实就是定义了一个 struct module_struct的结构体变量 log_config_module, 然后对其进行初始化.
typedef struct module_struct module;
struct module_struct {
/** API version, *not* module version; check that module is
* compatible with this version of the server.
*/
int version;
/** API minor version. Provides API feature milestones. Not checked
* during module init */
int minor_version;
/** Index to this modules structures in config vectors. */
int module_index;
/** The name of the module's C file */
const char *name;
/** The handle for the DSO. Internal use only */
void *dynamic_load_handle;
/** A pointer to the next module in the list
* @var module_struct *next
*/
struct module_struct *next;
/** Magic Cookie to identify a module structure; It's mainly
* important for the DSO facility (see also mod_so). */
unsigned long magic;
/** Function to allow MPMs to re-write command line arguments. This
* hook is only available to MPMs.
* @param The process that the server is running in.
*/
void (*rewrite_args) (process_rec *process);
/** Function to allow all modules to create per directory configuration
* structures.
* @param p The pool to use for all allocations.
* @param dir The directory currently being processed.
* @return The per-directory structure created
*/
void *(*create_dir_config) (apr_pool_t *p, char *dir);
/** Function to allow all modules to merge the per directory configuration
* structures for two directories.
* @param p The pool to use for all allocations.
* @param base_conf The directory structure created for the parent directory.
* @param new_conf The directory structure currently being processed.
* @return The new per-directory structure created
*/
void *(*merge_dir_config) (apr_pool_t *p, void *base_conf, void *new_conf);
/** Function to allow all modules to create per server configuration
* structures.
* @param p The pool to use for all allocations.
* @param s The server currently being processed.
* @return The per-server structure created
*/
void *(*create_server_config) (apr_pool_t *p, server_rec *s);
/** Function to allow all modules to merge the per server configuration
* structures for two servers.
* @param p The pool to use for all allocations.
* @param base_conf The directory structure created for the parent directory.
* @param new_conf The directory structure currently being processed.
* @return The new per-directory structure created
*/
void *(*merge_server_config) (apr_pool_t *p, void *base_conf,
void *new_conf);
/** A command_rec table that describes all of the directives this module
* defines. */
const command_rec *cmds;
/** A hook to allow modules to hook other points in the request processing.
* In this function, modules should call the ap_hook_*() functions to
* register an interest in a specific step in processing the current
* request.
* @param p the pool to use for all allocations
*/
void (*register_hooks) (apr_pool_t *p);
};
3 模块使用
3.1 模块初始化基本流程
int main(int argc, const char * const argv[])
=> process = init_process(&argc, &argv);
=> error = ap_setup_prelinked_modules(process);
=> loop ap_prelinked_modules
=>ap_add_module(*m, process->pconf, NULL);
=> ap_add_module_commands(m, p); // 设置 m->cmds 保存的命令函数
=> ap_register_hooks(m, p); // 调用该模块的注册函数 m->register_hooks(p); 注册钩子
=> apr_hook_sort_all(); //上面注册完钩子,这里执行排序所有钩子
=> ap_run_rewrite_args(process);
=> loop all module // 循环调用所以module的 rewrite_args 函数
=> (*m->rewrite_args)(process);
=> 判断参数,并调用相应处理函数
=> ap_server_conf = ap_read_config(process, ptemp, confname, &ap_conftree); // 读取配置
=> server_rec *s = init_server_config(process, p); // 创建服务配置变量 s,并初始化默认值。 server_rec: 保存配置的链表节点
=> init_config_globals(p);
=> process_command_config(s, ap_server_pre_read_config, conftree, p, ptemp);
=> confname = ap_server_root_relative(p, filename);
=> error = ap_process_resource_config(s, confname, conftree, p, ptemp);
=> error = ap_check_mpm();
=> error = process_command_config(s, ap_server_post_read_config, conftree, p, ptemp);
=>
钩子排序和具体说明,参考 http://blog.youkuaiyun.com/conezxy/article/details/1897989 http://blog.youkuaiyun.com/conezxy/article/details/1898000