From: Roy T. Fielding Date: Thu, 26 Aug 1999 14:18:40 +0000 (+0000) Subject: Start to implement module-defined hooks that are a) fast and b) typesafe. X-Git-Tag: PRE_APR_CHANGES~32 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e3978962f93ce24ab63c0634c306b0a98faa7965;p=apache Start to implement module-defined hooks that are a) fast and b) typesafe. Replace pre_connection module call with a register_hook call and implement pre_connection as a hook. The intent is that these hooks will be extended to allow Apache to be multi-protocol, and also to allow the calling order to be specified on a per-hook/per-module basis. [Ben Laurie] Port a bunch of modules to the new module structure. ["Michael H. Voase" ] Submitted by: Ben Laurie git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@83770 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/http_config.h b/include/http_config.h index ea89594c81..417fff7694 100644 --- a/include/http_config.h +++ b/include/http_config.h @@ -58,6 +58,8 @@ #ifndef APACHE_HTTP_CONFIG_H #define APACHE_HTTP_CONFIG_H +#include "ap_hooks.h" + #ifdef __cplusplus extern "C" { #endif @@ -209,24 +211,10 @@ typedef struct module_struct { * (see also mod_so). */ - /* init() occurs after config parsing, but before any children are - * forked. - * Modules should not rely on the order in which create_server_config - * and create_dir_config are called. - */ -#ifdef ULTRIX_BRAIN_DEATH - void (*init) (); - void *(*create_dir_config) (); - void *(*merge_dir_config) (); - void *(*create_server_config) (); - void *(*merge_server_config) (); -#else - void (*init) (server_rec *, pool *); void *(*create_dir_config) (pool *p, char *dir); void *(*merge_dir_config) (pool *p, void *base_conf, void *new_conf); void *(*create_server_config) (pool *p, server_rec *s); void *(*merge_server_config) (pool *p, void *base_conf, void *new_conf); -#endif const command_rec *cmds; const handler_rec *handlers; @@ -243,38 +231,9 @@ typedef struct module_struct { * supposed to handle this was configured wrong). * type_checker --- Determine MIME type of the requested entity; * sets content_type, _encoding and _language fields. - * logger --- log a transaction. - * post_read_request --- run right after read_request or internal_redirect, - * and not run during any subrequests. */ - int (*translate_handler) (request_rec *); - int (*ap_check_user_id) (request_rec *); - int (*auth_checker) (request_rec *); - int (*access_checker) (request_rec *); - int (*type_checker) (request_rec *); - int (*fixer_upper) (request_rec *); - int (*logger) (request_rec *); - int (*header_parser) (request_rec *); - - /* Regardless of the model the server uses for managing "units of - * execution", i.e. multi-process, multi-threaded, hybrids of those, - * there is the concept of a "heavy weight process". That is, a - * process with its own memory space, file spaces, etc. This method, - * child_init, is called once for each heavy-weight process before - * any requests are served. Note that no provision is made yet for - * initialization per light-weight process (i.e. thread). The - * parameters passed here are the same as those passed to the global - * init method above. - */ -#ifdef ULTRIX_BRAIN_DEATH - void (*child_init) (); - void (*child_exit) (); -#else - void (*child_init) (server_rec *, pool *); - void (*child_exit) (server_rec *, pool *); -#endif - int (*post_read_request) (request_rec *); + void (*register_hooks) (void); } module; /* Initializer for the first few module slots, which are only @@ -337,6 +296,19 @@ API_EXPORT(module *) ap_find_linked_module(const char *name); /* for implementing subconfigs and customized config files */ API_EXPORT(const char *) ap_srm_command_loop(cmd_parms *parms, void *config); +/* ap_check_cmd_context() definitions: */ +API_EXPORT(const char *) ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden); + +/* ap_check_cmd_context(): Forbidden in: */ +#define NOT_IN_VIRTUALHOST 0x01 /* */ +#define NOT_IN_LIMIT 0x02 /* */ +#define NOT_IN_DIRECTORY 0x04 /* */ +#define NOT_IN_LOCATION 0x08 /* */ +#define NOT_IN_FILES 0x10 /* */ +#define NOT_IN_DIR_LOC_FILE (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES) /* //*/ +#define GLOBAL_ONLY (NOT_IN_VIRTUALHOST|NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE) + + #ifdef CORE_PRIVATE extern API_VAR_EXPORT module *top_module; @@ -351,13 +323,12 @@ void ap_single_module_configure(pool *p, server_rec *s, module *m); /* For http_main.c... */ -server_rec *ap_read_config(pool *conf_pool, pool *temp_pool, char *config_name); -void ap_init_modules(pool *p, server_rec *s); -void ap_child_init_modules(pool *p, server_rec *s); -void ap_child_exit_modules(pool *p, server_rec *s); void ap_setup_prelinked_modules(void); void ap_show_directives(void); void ap_show_modules(void); +server_rec *ap_read_config(pool *conf_pool, pool *temp_pool, const char *config_name); +void ap_post_config_hook(pool *pconf, pool *plog, pool *ptemp, server_rec *s); +void ap_child_init_hook(pool *pchild, server_rec *s); /* For http_request.c... */ @@ -376,33 +347,13 @@ int ap_parse_htaccess(void **result, request_rec *r, int override, CORE_EXPORT(const char *) ap_init_virtual_host(pool *p, const char *hostname, server_rec *main_server, server_rec **); -void ap_process_resource_config(server_rec *s, char *fname, pool *p, pool *ptemp); - -/* ap_check_cmd_context() definitions: */ -API_EXPORT(const char *) ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden); - -/* ap_check_cmd_context(): Forbidden in: */ -#define NOT_IN_VIRTUALHOST 0x01 /* */ -#define NOT_IN_LIMIT 0x02 /* */ -#define NOT_IN_DIRECTORY 0x04 /* */ -#define NOT_IN_LOCATION 0x08 /* */ -#define NOT_IN_FILES 0x10 /* */ -#define NOT_IN_DIR_LOC_FILE (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES) /* //*/ -#define GLOBAL_ONLY (NOT_IN_VIRTUALHOST|NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE) - +void ap_process_resource_config(server_rec *s, const char *fname, pool *p, pool *ptemp); /* Module-method dispatchers, also for http_request.c */ int ap_translate_name(request_rec *); -int ap_check_access(request_rec *); /* check access on non-auth basis */ int ap_check_user_id(request_rec *); /* obtain valid username from client auth */ -int ap_check_auth(request_rec *); /* check (validated) user is authorized here */ -int ap_find_types(request_rec *); /* identify MIME type */ -int ap_run_fixups(request_rec *); /* poke around for other metainfo, etc.... */ int ap_invoke_handler(request_rec *); -int ap_log_transaction(request_rec *r); -int ap_header_parse(request_rec *); -int ap_run_post_read_request(request_rec *); /* for mod_perl */ @@ -413,6 +364,15 @@ CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, cons #endif + /* Hooks */ +DECLARE_HOOK(int,header_parser,(request_rec *)) +DECLARE_HOOK(void,pre_config,(pool *pconf,pool *plog,pool *ptemp)) +DECLARE_HOOK(void,post_config, + (pool *pconf,pool *plog,pool *ptemp,server_rec *s)) +DECLARE_HOOK(void,open_logs, + (pool *pconf,pool *plog,pool *ptemp,server_rec *s)) +DECLARE_HOOK(void,child_init,(pool *pchild, server_rec *s)) + #ifdef __cplusplus } #endif diff --git a/include/http_protocol.h b/include/http_protocol.h index dedf134589..4fefb8be7c 100644 --- a/include/http_protocol.h +++ b/include/http_protocol.h @@ -58,6 +58,8 @@ #ifndef APACHE_HTTP_PROTOCOL_H #define APACHE_HTTP_PROTOCOL_H +#include "ap_hooks.h" + #ifdef __cplusplus extern "C" { #endif @@ -216,6 +218,16 @@ CORE_EXPORT(void) ap_parse_uri(request_rec *r, const char *uri); */ API_EXPORT(int) ap_method_number_of(const char *method); + /* Hooks */ + /* + * post_read_request --- run right after read_request or internal_redirect, + * and not run during any subrequests. + */ +DECLARE_HOOK(int,post_read_request,(request_rec *)) +DECLARE_HOOK(int,log_transaction,(request_rec *)) +DECLARE_HOOK(const char *,http_method,(const request_rec *)) +DECLARE_HOOK(unsigned short,default_port,(const request_rec *)) + #ifdef __cplusplus } #endif diff --git a/include/http_request.h b/include/http_request.h index 4d83c543d6..117f9592f7 100644 --- a/include/http_request.h +++ b/include/http_request.h @@ -58,6 +58,8 @@ #ifndef APACHE_HTTP_REQUEST_H #define APACHE_HTTP_REQUEST_H +#include "ap_hooks.h" + #ifdef __cplusplus extern "C" { #endif @@ -110,6 +112,14 @@ void ap_process_request(request_rec *); API_EXPORT(void) ap_die(int type, request_rec *r); #endif + /* Hooks */ +DECLARE_HOOK(int,translate_name,(request_rec *)) +DECLARE_HOOK(int,check_user_id,(request_rec *)) +DECLARE_HOOK(int,fixups,(request_rec *)) +DECLARE_HOOK(int,type_checker,(request_rec *)) +DECLARE_HOOK(int,access_checker,(request_rec *)) +DECLARE_HOOK(int,auth_checker,(request_rec *)) + #ifdef __cplusplus } #endif diff --git a/modules/aaa/mod_access.c b/modules/aaa/mod_access.c index 6179510451..3e372387d1 100644 --- a/modules/aaa/mod_access.c +++ b/modules/aaa/mod_access.c @@ -384,27 +384,19 @@ static int check_dir_access(request_rec *r) return ret; } - +static void register_hooks(void) +{ + ap_hook_access_checker(check_dir_access,NULL,NULL,HOOK_MIDDLE); +} module MODULE_VAR_EXPORT access_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, create_access_dir_config, /* dir config creater */ NULL, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server config */ access_cmds, NULL, /* handlers */ - NULL, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - check_dir_access, /* check access */ - NULL, /* type_checker */ - NULL, /* fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ + register_hooks /* register hooks */ }; diff --git a/modules/aaa/mod_auth.c b/modules/aaa/mod_auth.c index 39c74a3704..e8a861f7dd 100644 --- a/modules/aaa/mod_auth.c +++ b/modules/aaa/mod_auth.c @@ -74,6 +74,7 @@ #include "http_core.h" #include "http_log.h" #include "http_protocol.h" +#include "http_request.h" typedef struct auth_config_struct { char *auth_pwfile; @@ -309,24 +310,19 @@ static int check_user_access(request_rec *r) } module MODULE_VAR_EXPORT auth_module = +static void register_hooks(void) +{ + ap_hook_check_user_id(authenticate_basic_user,NULL,NULL,HOOK_MIDDLE); + ap_hook_auth_checker(check_user_access,NULL,NULL,HOOK_MIDDLE); +} + { STANDARD_MODULE_STUFF, - NULL, /* initializer */ - create_auth_dir_config, /* dir config creater */ + STANDARD20_MODULE_STUFF, NULL, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server config */ auth_cmds, /* command table */ NULL, /* handlers */ NULL, /* filename translation */ - authenticate_basic_user, /* check_user_id */ - check_user_access, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - NULL, /* fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ -}; + register_hooks /* register hooks */ diff --git a/modules/generators/mod_asis.c b/modules/generators/mod_asis.c index 5e299df926..98a40543f3 100644 --- a/modules/generators/mod_asis.c +++ b/modules/generators/mod_asis.c @@ -107,8 +107,10 @@ static int asis_handler(request_rec *r) } ap_send_http_header(r); - if (!r->header_only) - ap_send_fd(f, r); + if (!r->header_only) { + fseek(f, 0, SEEK_CUR); + ap_send_fd(fileno(f), r); + } ap_pfclose(r->pool, f); return OK; @@ -123,23 +125,12 @@ static const handler_rec asis_handlers[] = module MODULE_VAR_EXPORT asis_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, NULL, /* create per-directory config structure */ NULL, /* merge per-directory config structures */ NULL, /* create per-server config structure */ NULL, /* merge per-server config structures */ NULL, /* command table */ asis_handlers, /* handlers */ - NULL, /* translate_handler */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - NULL, /* pre-run fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ + NULL /* register hooks */ }; diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c index 392fb5a1f1..3a6a110adc 100644 --- a/modules/generators/mod_cgi.c +++ b/modules/generators/mod_cgi.c @@ -587,23 +587,21 @@ static const handler_rec cgi_handlers[] = module MODULE_VAR_EXPORT cgi_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, + NULL, /* pre_config */ + NULL, /* post_config */ + NULL, /* open_logs */ + NULL, /* child initializer */ NULL, /* dir config creater */ NULL, /* dir merger --- default is to override */ create_cgi_config, /* server config */ merge_cgi_config, /* merge server config */ cgi_cmds, /* command table */ cgi_handlers, /* handlers */ - NULL, /* filename translation */ - NULL, /* check_user_id */ NULL, /* check auth */ NULL, /* check access */ NULL, /* type_checker */ NULL, /* fixups */ NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ + NULL /* register hooks */ }; diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 0226508270..0cee618fd9 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -2651,24 +2651,37 @@ static const handler_rec core_handlers[] = { { NULL, NULL } }; +static void core_open_logs(pool *pconf, pool *plog, pool *ptemp, server_rec *s) +{ + ap_open_logs(s, pconf); +} + +static const char *core_method(const request_rec *r) + { return "http"; } + +static unsigned short core_port(const request_rec *r) + { return DEFAULT_HTTP_PORT; } + +static void register_hooks(void) +{ + ap_hook_translate_name(core_translate,NULL,NULL,HOOK_REALLY_LAST); + ap_hook_process_connection(ap_process_http_connection,NULL,NULL, + HOOK_REALLY_LAST); + ap_hook_http_method(core_method,NULL,NULL,HOOK_REALLY_LAST); + ap_hook_default_port(core_port,NULL,NULL,HOOK_REALLY_LAST); + ap_hook_open_logs(core_open_logs,NULL,NULL,HOOK_MIDDLE); + /* FIXME: I suspect we can eliminate the need for these - Ben */ + ap_hook_type_checker(do_nothing,NULL,NULL,HOOK_REALLY_LAST); + ap_hook_access_checker(do_nothing,NULL,NULL,HOOK_REALLY_LAST); +} + API_VAR_EXPORT module core_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, create_core_dir_config, /* create per-directory config structure */ merge_core_dir_configs, /* merge per-directory config structures */ create_core_server_config, /* create per-server config structure */ merge_core_server_configs, /* merge per-server config structures */ core_cmds, /* command table */ core_handlers, /* handlers */ - core_translate, /* translate_handler */ - NULL, /* check_user_id */ - NULL, /* check auth */ - do_nothing, /* check access */ - do_nothing, /* type_checker */ - NULL, /* pre-run fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post_read_request */ + register_hooks /* register hooks */ }; diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index 37605ed0ed..8617a66467 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -75,6 +75,13 @@ #include "util_date.h" /* For parseHTTPdate and BAD_DATE */ #include +HOOK_STRUCT( + HOOK_LINK(post_read_request) + HOOK_LINK(log_transaction) + HOOK_LINK(http_method) + HOOK_LINK(default_port) +); + #define SET_BYTES_SENT(r) \ do { if (r->sent_bodyct) \ ap_bgetopt (r->connection->client, BO_BYTECT, &r->bytes_sent); \ @@ -949,7 +956,7 @@ request_rec *ap_read_request(conn_rec *conn) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "request failed: URI too long"); ap_send_error_response(r, 0); - ap_log_transaction(r); + ap_run_log_transaction(r); return r; } return NULL; @@ -964,7 +971,7 @@ request_rec *ap_read_request(conn_rec *conn) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "request failed: error reading the headers"); ap_send_error_response(r, 0); - ap_log_transaction(r); + ap_run_log_transaction(r); return r; } } @@ -981,7 +988,7 @@ request_rec *ap_read_request(conn_rec *conn) r->header_only = 0; r->status = HTTP_BAD_REQUEST; ap_send_error_response(r, 0); - ap_log_transaction(r); + ap_run_log_transaction(r); return r; } } @@ -1013,7 +1020,7 @@ request_rec *ap_read_request(conn_rec *conn) "client sent HTTP/1.1 request without hostname " "(see RFC2068 section 9, and 14.23): %s", r->uri); ap_send_error_response(r, 0); - ap_log_transaction(r); + ap_run_log_transaction(r); return r; } if (((expect = ap_table_get(r->headers_in, "Expect")) != NULL) && @@ -1034,14 +1041,14 @@ request_rec *ap_read_request(conn_rec *conn) "Expect: %s", expect); ap_send_error_response(r, 0); (void) ap_discard_request_body(r); - ap_log_transaction(r); + ap_run_log_transaction(r); return r; } } if ((access_status = ap_run_post_read_request(r))) { ap_die(access_status, r); - ap_log_transaction(r); + ap_run_log_transaction(r); return NULL; } @@ -2740,3 +2747,10 @@ void ap_send_error_response(request_rec *r, int recursive_error) ap_finalize_request_protocol(r); ap_rflush(r); } + +IMPLEMENT_HOOK_RUN_ALL(int,post_read_request,(request_rec *r),(r),OK,DECLINED) +IMPLEMENT_HOOK_RUN_ALL(int,log_transaction,(request_rec *r),(r),OK,DECLINED) +IMPLEMENT_HOOK_RUN_FIRST(const char *,http_method,(const request_rec *r),(r), + NULL) +IMPLEMENT_HOOK_RUN_FIRST(unsigned short,default_port,(const request_rec *r), + (r),0) diff --git a/modules/http/http_request.c b/modules/http/http_request.c index bc4d45f60f..4e4c0cffbc 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -71,12 +71,29 @@ #include "http_request.h" #include "http_core.h" #include "http_protocol.h" -#include "http_conf_globals.h" /* for ap_extended_status */ #include "http_log.h" #include "http_main.h" +#if 0 #include "scoreboard.h" +#endif #include "fnmatch.h" +HOOK_STRUCT( + HOOK_LINK(translate_name) + HOOK_LINK(check_user_id) + HOOK_LINK(fixups) + HOOK_LINK(type_checker) + HOOK_LINK(access_checker) + HOOK_LINK(auth_checker) +) + +IMPLEMENT_HOOK_RUN_FIRST(int,translate_name,(request_rec *r),(r),DECLINED) +IMPLEMENT_HOOK_RUN_FIRST(int,check_user_id,(request_rec *r),(r),DECLINED) +IMPLEMENT_HOOK_RUN_ALL(int,fixups,(request_rec *r),(r),OK,DECLINED) +IMPLEMENT_HOOK_RUN_FIRST(int,type_checker,(request_rec *r),(r),DECLINED) +IMPLEMENT_HOOK_RUN_ALL(int,access_checker,(request_rec *r),(r),OK,DECLINED) +IMPLEMENT_HOOK_RUN_FIRST(int,auth_checker,(request_rec *r),(r),DECLINED) + /***************************************************************** * * Getting and checking directory configuration. Also checks the @@ -229,33 +246,34 @@ static int get_path_info(request_rec *r) *cp = '\0'; - /* We must not stat() filenames that may cause os-specific system - * problems, such as "/file/aux" on DOS-abused filesystems. - * So pretend that they do not exist by returning an ENOENT error. - * This will force us to drop that part of the path and keep - * looking back for a "real" file that exists, while still allowing - * the "invalid" path parts within the PATH_INFO. - */ - if (!ap_os_is_filename_valid(path)) { - errno = ENOENT; - rv = -1; - } - else { - errno = 0; - rv = stat(path, &r->finfo); - } + /* We must not stat() filenames that may cause os-specific system + * problems, such as "/file/aux" on DOS-abused filesystems. + * So pretend that they do not exist by returning an ENOENT error. + * This will force us to drop that part of the path and keep + * looking back for a "real" file that exists, while still allowing + * the "invalid" path parts within the PATH_INFO. + */ + if (!ap_os_is_filename_valid(path)) { + errno = ENOENT; + rv = -1; + } + else { + errno = 0; + /* ZZZ change to AP func for File Info */ + rv = stat(path, &r->finfo); + } if (cp != end) *cp = '/'; - if (!rv) { + if (!rv) { /* ZZZ AP Status check here */ /* * Aha! Found something. If it was a directory, we will search * contents of that directory for a multi_match, so the PATH_INFO * argument starts with the component after that. */ - + /* ZZZ use AP file type checking defines */ if (S_ISDIR(r->finfo.st_mode) && last_cp) { r->finfo.st_mode = 0; /* No such file... */ cp = last_cp; @@ -764,7 +782,7 @@ API_EXPORT(request_rec *) ap_sub_req_method_uri(const char *method, return rnew; } - res = ap_translate_name(rnew); + res = ap_run_translate_name(rnew); if (res) { rnew->status = res; return rnew; @@ -786,16 +804,16 @@ API_EXPORT(request_rec *) ap_sub_req_method_uri(const char *method, || (res = location_walk(rnew)) || ((ap_satisfies(rnew) == SATISFY_ALL || ap_satisfies(rnew) == SATISFY_NOSPEC) - ? ((res = ap_check_access(rnew)) + ? ((res = ap_run_access_checker(rnew)) || (ap_some_auth_required(rnew) - && ((res = ap_check_user_id(rnew)) - || (res = ap_check_auth(rnew))))) - : ((res = ap_check_access(rnew)) + && ((res = ap_run_check_user_id(rnew)) + || (res = ap_run_auth_checker(rnew))))) + : ((res = ap_run_access_checker(rnew)) && (!ap_some_auth_required(rnew) - || ((res = ap_check_user_id(rnew)) - || (res = ap_check_auth(rnew))))) + || ((res = ap_run_check_user_id(rnew)) + || (res = ap_run_auth_checker(rnew))))) ) - || (res = ap_find_types(rnew)) + || (res = ap_run_type_checker(rnew)) || (res = ap_run_fixups(rnew)) ) { rnew->status = res; @@ -877,7 +895,7 @@ API_EXPORT(request_rec *) ap_sub_req_lookup_file(const char *new_file, return rnew; } if (rnew->per_dir_config == r->per_dir_config) { - if ((res = ap_find_types(rnew)) || (res = ap_run_fixups(rnew))) { + if ((res = ap_run_type_checker(rnew)) || (res = ap_run_fixups(rnew))) { rnew->status = res; } return rnew; @@ -906,16 +924,16 @@ API_EXPORT(request_rec *) ap_sub_req_lookup_file(const char *new_file, if (res || ((ap_satisfies(rnew) == SATISFY_ALL || ap_satisfies(rnew) == SATISFY_NOSPEC) - ? ((res = ap_check_access(rnew)) + ? ((res = ap_run_access_checker(rnew)) || (ap_some_auth_required(rnew) - && ((res = ap_check_user_id(rnew)) - || (res = ap_check_auth(rnew))))) - : ((res = ap_check_access(rnew)) + && ((res = ap_run_check_user_id(rnew)) + || (res = ap_run_auth_checker(rnew))))) + : ((res = ap_run_access_checker(rnew)) && (!ap_some_auth_required(rnew) - || ((res = ap_check_user_id(rnew)) - || (res = ap_check_auth(rnew))))) + || ((res = ap_run_check_user_id(rnew)) + || (res = ap_run_auth_checker(rnew))))) ) - || (res = ap_find_types(rnew)) + || (res = ap_run_type_checker(rnew)) || (res = ap_run_fixups(rnew)) ) { rnew->status = res; @@ -1103,7 +1121,7 @@ static void process_request_internal(request_rec *r) return; } - if ((access_status = ap_translate_name(r))) { + if ((access_status = ap_run_translate_name(r))) { decl_die(access_status, "translate", r); return; } @@ -1146,7 +1164,7 @@ static void process_request_internal(request_rec *r) return; } - if ((access_status = ap_header_parse(r))) { + if ((access_status = ap_run_header_parser(r))) { ap_die(access_status, r); return; } @@ -1154,18 +1172,18 @@ static void process_request_internal(request_rec *r) switch (ap_satisfies(r)) { case SATISFY_ALL: case SATISFY_NOSPEC: - if ((access_status = ap_check_access(r)) != 0) { + if ((access_status = ap_run_access_checker(r)) != 0) { decl_die(access_status, "check access", r); return; } if (ap_some_auth_required(r)) { - if (((access_status = ap_check_user_id(r)) != 0) || !ap_auth_type(r)) { + if (((access_status = ap_run_check_user_id(r)) != 0) || !ap_auth_type(r)) { decl_die(access_status, ap_auth_type(r) ? "check user. No user file?" : "perform authentication. AuthType not set!", r); return; } - if (((access_status = ap_check_auth(r)) != 0) || !ap_auth_type(r)) { + if (((access_status = ap_run_auth_checker(r)) != 0) || !ap_auth_type(r)) { decl_die(access_status, ap_auth_type(r) ? "check access. No groups file?" : "perform authentication. AuthType not set!", r); @@ -1174,20 +1192,20 @@ static void process_request_internal(request_rec *r) } break; case SATISFY_ANY: - if (((access_status = ap_check_access(r)) != 0) || !ap_auth_type(r)) { + if (((access_status = ap_run_access_checker(r)) != 0) || !ap_auth_type(r)) { if (!ap_some_auth_required(r)) { decl_die(access_status, ap_auth_type(r) ? "check access" : "perform authentication. AuthType not set!", r); return; } - if (((access_status = ap_check_user_id(r)) != 0) || !ap_auth_type(r)) { + if (((access_status = ap_run_check_user_id(r)) != 0) || !ap_auth_type(r)) { decl_die(access_status, ap_auth_type(r) ? "check user. No user file?" : "perform authentication. AuthType not set!", r); return; } - if (((access_status = ap_check_auth(r)) != 0) || !ap_auth_type(r)) { + if (((access_status = ap_run_auth_checker(r)) != 0) || !ap_auth_type(r)) { decl_die(access_status, ap_auth_type(r) ? "check access. No groups file?" : "perform authentication. AuthType not set!", r); @@ -1200,7 +1218,7 @@ static void process_request_internal(request_rec *r) if (! (r->proxyreq && r->parsed_uri.scheme != NULL && strcmp(r->parsed_uri.scheme, "http") == 0) ) { - if ((access_status = ap_find_types(r)) != 0) { + if ((access_status = ap_run_type_checker(r)) != 0) { decl_die(access_status, "find types", r); return; } @@ -1222,16 +1240,8 @@ static void process_request_internal(request_rec *r) void ap_process_request(request_rec *r) { - int old_stat; - - if (ap_extended_status) - ap_time_process_request(r->connection->child_num, START_PREQUEST); - process_request_internal(r); - old_stat = ap_update_child_status(r->connection->child_num, - SERVER_BUSY_LOG, r); - /* * We want to flush the last packet if this isn't a pipelining connection * *before* we start into logging. Suppose that the logging causes a DNS @@ -1239,12 +1249,9 @@ void ap_process_request(request_rec *r) * this packet, then it'll appear like the link is stalled when really * it's the application that's stalled. */ - ap_bhalfduplex(r->connection->client); - ap_log_transaction(r); - - (void) ap_update_child_status(r->connection->child_num, old_stat, r); - if (ap_extended_status) - ap_time_process_request(r->connection->child_num, STOP_PREQUEST); + /* TODO: re-implement ap_bhalfduplex... not sure how yet */ + /* //ap_bhalfduplex(r->connection->client); */ + ap_run_log_transaction(r); } static table *rename_original_env(pool *p, table *t) diff --git a/modules/http/mod_mime.c b/modules/http/mod_mime.c index f27356bfdd..2311dbafbd 100644 --- a/modules/http/mod_mime.c +++ b/modules/http/mod_mime.c @@ -67,6 +67,7 @@ #include "httpd.h" #include "http_config.h" #include "http_log.h" +#include "http_request.h" typedef struct handlers_info { char *name; @@ -238,12 +239,12 @@ static const command_rec mime_cmds[] = static table *hash_buckets[MIME_HASHSIZE]; -static void init_mime(server_rec *s, pool *p) +static void mime_post_config(pool *p, pool *plog, pool *ptemp, server_rec *s) { configfile_t *f; char l[MAX_STRING_LEN]; int x; - char *types_confname = ap_get_module_config(s->module_config, &mime_module); + const char *types_confname = ap_get_module_config(s->module_config, &mime_module); if (!types_confname) types_confname = TYPES_CONFIG_FILE; @@ -378,25 +379,19 @@ static int find_ct(request_rec *r) return OK; } -module MODULE_VAR_EXPORT mime_module = +static void register_hooks(void) { - STANDARD_MODULE_STUFF, - init_mime, /* initializer */ - create_mime_dir_config, /* dir config creator */ - merge_mime_dir_configs, /* dir config merger */ - NULL, /* server config */ - NULL, /* merge server config */ - mime_cmds, /* command table */ - NULL, /* handlers */ - NULL, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - find_ct, /* type_checker */ - NULL, /* fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ + ap_hook_type_checker(find_ct,NULL,NULL,HOOK_MIDDLE); + ap_hook_post_config(mime_post_config,NULL,NULL,HOOK_MIDDLE); +} + +module MODULE_VAR_EXPORT mime_module = { + STANDARD20_MODULE_STUFF, + create_mime_dir_config, /* create per-directory config structure */ + merge_mime_dir_configs, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + mime_cmds, /* command table */ + NULL, /* handlers */ + register_hooks /* register hooks */ }; diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c index 6ffb669916..9a00f01de4 100644 --- a/modules/loggers/mod_log_config.c +++ b/modules/loggers/mod_log_config.c @@ -173,6 +173,7 @@ #include "http_config.h" #include "http_core.h" /* For REMOTE_NAME */ #include "http_log.h" +#include "http_protocol.h" #include module MODULE_VAR_EXPORT config_log_module; @@ -999,7 +1000,7 @@ static config_log_state *open_config_log(server_rec *s, pool *p, cls->log_fd = ap_piped_log_write_fd(pl); } else { - char *fname = ap_server_root_relative(p, cls->fname); + const char *fname = ap_server_root_relative(p, cls->fname); if ((cls->log_fd = ap_popenf(p, fname, xfer_flags, xfer_mode)) < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, s, "could not open transfer log file %s.", fname); @@ -1067,7 +1068,7 @@ static config_log_state *open_multi_logs(server_rec *s, pool *p) return NULL; } -static void init_config_log(server_rec *s, pool *p) +static void init_config_log(pool *pc, pool *p, pool *pt, server_rec *s) { /* First, do "physical" server, which gets default log fd and format * for the virtual servers, if they don't override... @@ -1080,10 +1081,14 @@ static void init_config_log(server_rec *s, pool *p) for (s = s->next; s; s = s->next) { open_multi_logs(s, p); } +#ifdef BUFFERED_LOGS + /* Now register the last buffer flush with the cleanup engine */ + ap_register_cleanup(p , s, flush_all_logs, flush_all_logs); +#endif } #ifdef BUFFERED_LOGS -static void flush_all_logs(server_rec *s, pool *p) +static void flush_all_logs(server_rec *s) { multi_log_state *mls; array_header *log_list; @@ -1109,29 +1114,20 @@ static void flush_all_logs(server_rec *s, pool *p) } #endif +static void register_hooks(void) +{ + ap_hook_open_logs(init_config_log,NULL,NULL,HOOK_MIDDLE); + ap_hook_log_transaction(multi_log_transaction,NULL,NULL,HOOK_MIDDLE); +} + module MODULE_VAR_EXPORT config_log_module = { - STANDARD_MODULE_STUFF, - init_config_log, /* initializer */ + 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 table */ NULL, /* handlers */ - NULL, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - NULL, /* fixups */ - multi_log_transaction, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ -#ifdef BUFFERED_LOGS - flush_all_logs, /* child_exit */ -#else - NULL, -#endif - NULL /* post read-request */ + register_hooks /* register hooks */ }; diff --git a/modules/mappers/mod_actions.c b/modules/mappers/mod_actions.c index 5906ee4c43..f2f2dc8b13 100644 --- a/modules/mappers/mod_actions.c +++ b/modules/mappers/mod_actions.c @@ -210,23 +210,12 @@ static const handler_rec action_handlers[] = module action_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, create_action_dir_config, /* dir config creater */ merge_action_dir_configs, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server config */ action_cmds, /* command table */ action_handlers, /* handlers */ - NULL, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - NULL, /* fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ + NULL /* register hooks */ }; diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c index f92d982d23..d6d5d0ac7c 100644 --- a/modules/mappers/mod_alias.c +++ b/modules/mappers/mod_alias.c @@ -65,6 +65,7 @@ #include "httpd.h" #include "http_config.h" +#include "http_request.h" typedef struct { char *real; @@ -394,25 +395,22 @@ static int fixup_redir(request_rec *r) return DECLINED; } +static void register_hooks(void) +{ + static const char * const aszPre[]={ "mod_userdir.c",NULL }; + + ap_hook_translate_name(translate_alias_redir,aszPre,NULL,HOOK_MIDDLE); + ap_hook_fixups(fixup_redir,NULL,NULL,HOOK_MIDDLE); +} + module MODULE_VAR_EXPORT alias_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, create_alias_dir_config, /* dir config creater */ merge_alias_dir_config, /* dir merger --- default is to override */ create_alias_config, /* server config */ merge_alias_config, /* merge server configs */ alias_cmds, /* command table */ NULL, /* handlers */ - translate_alias_redir, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - fixup_redir, /* fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ + register_hooks /* register hooks */ }; diff --git a/modules/mappers/mod_dir.c b/modules/mappers/mod_dir.c index a32b390a88..9ead891d85 100644 --- a/modules/mappers/mod_dir.c +++ b/modules/mappers/mod_dir.c @@ -222,25 +222,13 @@ static const handler_rec dir_handlers[] = {NULL} }; -module MODULE_VAR_EXPORT dir_module = -{ - STANDARD_MODULE_STUFF, - NULL, /* initializer */ - create_dir_config, /* dir config creater */ - merge_dir_configs, /* dir merger --- default is to override */ - NULL, /* server config */ - NULL, /* merge server config */ - dir_cmds, /* command table */ - dir_handlers, /* handlers */ - NULL, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - NULL, /* fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ +module MODULE_VAR_EXPORT dir_module = { + STANDARD20_MODULE_STUFF, + create_dir_config, /* create per-directory config structure */ + merge_dir_configs, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + dir_cmds, /* command table */ + dir_handlers, /* handlers */ + NULL /* register hooks */ }; diff --git a/modules/mappers/mod_imap.c b/modules/mappers/mod_imap.c index c5152e71e4..9e387cb4f7 100644 --- a/modules/mappers/mod_imap.c +++ b/modules/mappers/mod_imap.c @@ -897,23 +897,12 @@ static const handler_rec imap_handlers[] = module MODULE_VAR_EXPORT imap_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, create_imap_dir_config, /* dir config creater */ merge_imap_dir_configs, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server config */ imap_cmds, /* command table */ imap_handlers, /* handlers */ - NULL, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - NULL, /* fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ + NULL /* register hooks */ }; diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c index 5f7411260c..2cfefc153f 100644 --- a/modules/mappers/mod_negotiation.c +++ b/modules/mappers/mod_negotiation.c @@ -2724,25 +2724,20 @@ static const handler_rec negotiation_handlers[] = {NULL} }; +static void register_hooks(void) +{ + ap_hook_fixups(fix_encoding,NULL,NULL,HOOK_MIDDLE); + ap_hook_type_checker(handle_multi,NULL,NULL,HOOK_MIDDLE); +} + module MODULE_VAR_EXPORT negotiation_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, create_neg_dir_config, /* dir config creator */ merge_neg_dir_configs, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server config */ negotiation_cmds, /* command table */ negotiation_handlers, /* handlers */ - NULL, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - handle_multi, /* type_checker */ - fix_encoding, /* fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ + register_hooks /* register hooks */ }; diff --git a/modules/mappers/mod_userdir.c b/modules/mappers/mod_userdir.c index 5c0e26d275..105d0040e9 100644 --- a/modules/mappers/mod_userdir.c +++ b/modules/mappers/mod_userdir.c @@ -92,6 +92,7 @@ #include "httpd.h" #include "http_config.h" +#include "http_request.h" module userdir_module; @@ -326,24 +327,20 @@ static int translate_userdir(request_rec *r) return DECLINED; } +static void register_hooks(void) +{ + static const char * const aszSucc[]={ "mod_alias.c",NULL }; + + ap_hook_translate_name(translate_userdir,NULL,aszSucc,HOOK_MIDDLE); +} + module userdir_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, NULL, /* dir config creater */ NULL, /* dir merger --- default is to override */ create_userdir_config, /* server config */ NULL, /* merge server config */ userdir_cmds, /* command table */ NULL, /* handlers */ - translate_userdir, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - NULL, /* fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ + register_hooks /* register hooks */ }; diff --git a/modules/metadata/mod_env.c b/modules/metadata/mod_env.c index 351a48712b..274512cbb3 100644 --- a/modules/metadata/mod_env.c +++ b/modules/metadata/mod_env.c @@ -100,6 +100,7 @@ #include "httpd.h" #include "http_config.h" +#include "http_request.h" typedef struct { table *vars; @@ -246,25 +247,20 @@ static int fixup_env_module(request_rec *r) return OK; } +static void register_hooks(void) +{ + ap_hook_fixups(fixup_env_module,NULL,NULL,HOOK_MIDDLE); +} + + module MODULE_VAR_EXPORT env_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, create_env_dir_config, /* dir config creater */ merge_env_dir_configs, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server configs */ env_module_cmds, /* command table */ NULL, /* handlers */ - NULL, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - fixup_env_module, /* fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ + register_hooks /* register hooks */ }; diff --git a/modules/metadata/mod_setenvif.c b/modules/metadata/mod_setenvif.c index fcf4c70d46..03324558c2 100644 --- a/modules/metadata/mod_setenvif.c +++ b/modules/metadata/mod_setenvif.c @@ -118,6 +118,7 @@ #include "http_config.h" #include "http_core.h" #include "http_log.h" +#include "http_protocol.h" enum special { SPECIAL_NOT, @@ -399,25 +400,20 @@ static int match_headers(request_rec *r) return DECLINED; } +static void register_hooks(void) +{ + ap_hook_post_read_request(match_headers,NULL,NULL,HOOK_MIDDLE); +} + module MODULE_VAR_EXPORT setenvif_module = { - STANDARD_MODULE_STUFF, - NULL, /* initializer */ + STANDARD20_MODULE_STUFF, NULL, /* dir config creater */ NULL, /* dir merger --- default is to override */ create_setenvif_config, /* server config */ merge_setenvif_config, /* merge server configs */ setenvif_module_cmds, /* command table */ NULL, /* handlers */ - NULL, /* filename translation */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - NULL, /* fixups */ - NULL, /* logger */ - NULL, /* input header parse */ - NULL, /* child (process) initialization */ - NULL, /* child (process) rundown */ - match_headers /* post_read_request */ + register_hooks /* register hooks */ }; + diff --git a/server/config.c b/server/config.c index 4a2a6d383f..9073d3576f 100644 --- a/server/config.c +++ b/server/config.c @@ -81,6 +81,25 @@ #include "http_vhost.h" #include "explain.h" +HOOK_STRUCT( + HOOK_LINK(header_parser) + HOOK_LINK(pre_config) + HOOK_LINK(post_config) + HOOK_LINK(open_logs) + HOOK_LINK(child_init) +) + +IMPLEMENT_HOOK_RUN_ALL(int,header_parser,(request_rec *r),(r),OK,DECLINED) +IMPLEMENT_HOOK_VOID(pre_config,(pool *pconf,pool *plog,pool *ptemp), + (pconf,plog,ptemp)) +IMPLEMENT_HOOK_VOID(post_config, + (pool *pconf, pool *plog, pool *ptemp, server_rec *s), + (pconf,plog,ptemp,s)) +IMPLEMENT_HOOK_VOID(open_logs, + (pool *pconf, pool *plog, pool *ptemp, server_rec *s), + (pconf,plog,ptemp,s)) +IMPLEMENT_HOOK_VOID(child_init,(pool *pchild, server_rec *s),(pchild,s)) + DEF_Explain /**************************************************************** @@ -214,207 +233,14 @@ void *ap_create_request_config(pool *p) return create_empty_config(p); } -CORE_EXPORT(void *) ap_create_per_dir_config(pool *p) +void *ap_create_conn_config(pool *p) { return create_empty_config(p); } -#ifdef EXPLAIN - -struct { - int offset; - char *method; -} aMethods[] = - -{ -#define m(meth) { XtOffsetOf(module,meth),#meth } - m(translate_handler), - m(ap_check_user_id), - m(auth_checker), - m(type_checker), - m(fixer_upper), - m(logger), - { -1, "?" }, -#undef m -}; - -char *ShowMethod(module *modp, int offset) -{ - int n; - static char buf[200]; - - for (n = 0; aMethods[n].offset >= 0; ++n) - if (aMethods[n].offset == offset) - break; - ap_snprintf(buf, sizeof(buf), "%s:%s", modp->name, aMethods[n].method); - return buf; -} -#else -#define ShowMethod(modp,offset) -#endif - -/**************************************************************** - * - * Dispatch through the modules to find handlers for various phases - * of request handling. These are invoked by http_request.c to actually - * do the dirty work of slogging through the module structures. - */ - -/* - * Optimized run_method routines. The observation here is that many modules - * have NULL for most of the methods. So we build optimized lists of - * everything. If you think about it, this is really just like a sparse array - * implementation to avoid scanning the zero entries. - */ -static const int method_offsets[] = -{ - XtOffsetOf(module, translate_handler), - XtOffsetOf(module, ap_check_user_id), - XtOffsetOf(module, auth_checker), - XtOffsetOf(module, access_checker), - XtOffsetOf(module, type_checker), - XtOffsetOf(module, fixer_upper), - XtOffsetOf(module, logger), - XtOffsetOf(module, header_parser), - XtOffsetOf(module, post_read_request) -}; -#define NMETHODS (sizeof (method_offsets)/sizeof (method_offsets[0])) - -static struct { - int translate_handler; - int ap_check_user_id; - int auth_checker; - int access_checker; - int type_checker; - int fixer_upper; - int logger; - int header_parser; - int post_read_request; -} offsets_into_method_ptrs; - -/* - * This is just one big array of method_ptrs. It's constructed such that, - * for example, method_ptrs[ offsets_into_method_ptrs.logger ] is the first - * logger function. You go one-by-one from there until you hit a NULL. - * This structure was designed to hopefully maximize cache-coolness. - */ -static handler_func *method_ptrs; - -/* routine to reconstruct all these shortcuts... called after every - * add_module. - * XXX: this breaks if modules dink with their methods pointers - */ -static void build_method_shortcuts(void) -{ - module *modp; - int how_many_ptrs; - int i; - int next_ptr; - handler_func fp; - - if (method_ptrs) { - /* free up any previous set of method_ptrs */ - free(method_ptrs); - } - - /* first we count how many functions we have */ - how_many_ptrs = 0; - for (modp = top_module; modp; modp = modp->next) { - for (i = 0; i < NMETHODS; ++i) { - if (*(handler_func *) (method_offsets[i] + (char *) modp)) { - ++how_many_ptrs; - } - } - } - method_ptrs = malloc((how_many_ptrs + NMETHODS) * sizeof(handler_func)); - if (method_ptrs == NULL) { - fprintf(stderr, "Ouch! Out of memory in build_method_shortcuts()!\n"); - } - next_ptr = 0; - for (i = 0; i < NMETHODS; ++i) { - /* XXX: This is an itsy bit presumptuous about the alignment - * constraints on offsets_into_method_ptrs. I can't remember if - * ANSI says this has to be true... -djg */ - ((int *) &offsets_into_method_ptrs)[i] = next_ptr; - for (modp = top_module; modp; modp = modp->next) { - fp = *(handler_func *) (method_offsets[i] + (char *) modp); - if (fp) { - method_ptrs[next_ptr++] = fp; - } - } - method_ptrs[next_ptr++] = NULL; - } -} - - -static int run_method(request_rec *r, int offset, int run_all) -{ - int i; - - for (i = offset; method_ptrs[i]; ++i) { - handler_func mod_handler = method_ptrs[i]; - - if (mod_handler) { - int result; - - result = (*mod_handler) (r); - - if (result != DECLINED && (!run_all || result != OK)) - return result; - } - } - - return run_all ? OK : DECLINED; -} - -int ap_translate_name(request_rec *r) -{ - return run_method(r, offsets_into_method_ptrs.translate_handler, 0); -} - -int ap_check_access(request_rec *r) -{ - return run_method(r, offsets_into_method_ptrs.access_checker, 1); -} - -int ap_find_types(request_rec *r) -{ - return run_method(r, offsets_into_method_ptrs.type_checker, 0); -} - -int ap_run_fixups(request_rec *r) -{ - return run_method(r, offsets_into_method_ptrs.fixer_upper, 1); -} - -int ap_log_transaction(request_rec *r) -{ - return run_method(r, offsets_into_method_ptrs.logger, 1); -} - -int ap_header_parse(request_rec *r) -{ - return run_method(r, offsets_into_method_ptrs.header_parser, 1); -} - -int ap_run_post_read_request(request_rec *r) -{ - return run_method(r, offsets_into_method_ptrs.post_read_request, 1); -} - -/* Auth stuff --- anything that defines one of these will presumably - * want to define something for the other. Note that check_auth is - * separate from check_access to make catching some config errors easier. - */ - -int ap_check_user_id(request_rec *r) -{ - return run_method(r, offsets_into_method_ptrs.ap_check_user_id, 0); -} - -int ap_check_auth(request_rec *r) +CORE_EXPORT(void *) ap_create_per_dir_config(pool *p) { - return run_method(r, offsets_into_method_ptrs.auth_checker, 0); + return create_empty_config(p); } /* @@ -532,6 +358,23 @@ int ap_invoke_handler(request_rec *r) return HTTP_INTERNAL_SERVER_ERROR; } +int g_bDebugHooks; +const char *g_szCurrentHookName; + +static void register_hooks(module *m) + { + if(m->register_hooks) + { + if(getenv("SHOW_HOOKS")) + { + printf("Registering hooks for %s\n",m->name); + g_bDebugHooks=1; + } + g_szCurrentHookName=m->name; + m->register_hooks(); + } + } + /* One-time setup for precompiled modules --- NOT to be done on restart */ API_EXPORT(void) ap_add_module(module *m) @@ -583,6 +426,9 @@ API_EXPORT(void) ap_add_module(module *m) m->name = tmp; } #endif /*_OSD_POSIX*/ + + /* FIXME: is this the right place to call this? */ + register_hooks(m); } /* @@ -709,6 +555,8 @@ void ap_setup_prelinked_modules() */ for (m = ap_prelinked_modules; *m != NULL; m++) ap_add_module(*m); + + ap_sort_hooks(); } API_EXPORT(const char *) ap_find_module_name(module *m) @@ -1272,7 +1120,6 @@ int ap_parse_htaccess(void **result, request_rec *r, int override, "access to be safe"); return HTTP_FORBIDDEN; } - } /* cache it */ new = ap_palloc(r->pool, sizeof(struct htaccess_result)); @@ -1460,41 +1307,18 @@ void ap_single_module_configure(pool *p, server_rec *s, module *m) (*m->create_dir_config)(p, NULL)); } -void ap_init_modules(pool *p, server_rec *s) +void ap_post_config_hook(pool *pconf, pool *plog, pool *ptemp, server_rec *s) { - module *m; - - for (m = top_module; m; m = m->next) - if (m->init) - (*m->init) (s, p); - build_method_shortcuts(); - init_handlers(p); + ap_run_post_config(pconf,plog,ptemp,s); + init_handlers(pconf); } -void ap_child_init_modules(pool *p, server_rec *s) +void ap_child_init_hook(pool *pchild, server_rec *s) { - module *m; - - for (m = top_module; m; m = m->next) - if (m->child_init) - (*m->child_init) (s, p); -} - -void ap_child_exit_modules(pool *p, server_rec *s) -{ - module *m; - -#ifdef SIGHUP - signal(SIGHUP, SIG_IGN); -#endif -#ifdef SIGUSR1 - signal(SIGUSR1, SIG_IGN); -#endif - - for (m = top_module; m; m = m->next) - if (m->child_exit) - (*m->child_exit) (s, p); + /* TODO: uh this seems ugly, is there a better way? */ + ap_child_init_alloc(); + ap_run_child_init(pchild,s); } /******************************************************************** @@ -1598,3 +1422,4 @@ void ap_show_modules() for (n = 0; ap_loaded_modules[n]; ++n) printf(" %s\n", ap_loaded_modules[n]->name); } +