const ap_directive_t *err_directive;
};
-typedef struct handler_rec handler_rec;
-
-/** This structure records the existence of handlers in a module... */
-struct handler_rec {
- /** The type of content this handler function will handle.
- * MUST be all lower case
- */
- const char *content_type;
- /** The function to call when this context-type is requested.
- * @deffunc int handler(request_rec *)
- */
- int (*handler) (request_rec *);
-};
-
typedef struct module_struct module;
/**
* Module structures. Just about everything is dispatched through
/** A command_rec table that describes all of the directives this module
* defines. */
const command_rec *cmds;
- /** A handler_rec table that describes all of the mime-types this module
- * will server responses for. */
- const handler_rec *handlers;
/** A hook to allow modules to hook other points in the request processing.
* In this function, modules should call the ap_hook_*() functions to
*/
AP_DECLARE_HOOK(void,child_init,(apr_pool_t *pchild, server_rec *s))
+/**
+ * Run the handler functions for each module
+ * @param handler The handler string (a MIME type or a handler)
+ * @param r The request_rec
+ * @deffunc void ap_run_handler(const char *handler,request_rec *r)
+ * @tip non-wildcard handlers should HOOK_MIDDLE, wildcard HOOK_LAST
+ */
+AP_DECLARE_HOOK(int,handler,(const char *handler,request_rec *r))
+
#ifdef __cplusplus
}
#endif
NULL, /* server config */
NULL, /* merge server config */
access_cmds,
- NULL, /* handlers */
register_hooks /* register hooks */
};
NULL, /* server config */
NULL, /* merge server config */
auth_cmds, /* command apr_table_t */
- NULL, /* handlers */
register_hooks /* register hooks */
};
NULL,
NULL,
NULL,
- NULL,
ExportRegisterHooks
};
NULL,
NULL,
NULL,
- NULL,
ImportRegisterHooks
};
NULL, /* server config */
NULL, /* merge server config */
includes_cmds, /* command apr_table_t */
- NULL, /* handlers */
register_hooks /* register hooks */
};
#define ASIS_MAGIC_TYPE "httpd/send-as-is"
-static int asis_handler(request_rec *r)
+static int asis_handler(const char *handler,request_rec *r)
{
apr_file_t *f = NULL;
apr_status_t status;
const char *location;
apr_size_t nbytes;
+ if(strcmp(handler,ASIS_MAGIC_TYPE) && strcmp(handler,"send-as-is"))
+ return DECLINED;
+
r->allowed |= (1 << M_GET);
if (r->method_number != M_GET)
return DECLINED;
return OK;
}
-static const handler_rec asis_handlers[] =
+static void register_hooks(void)
{
- {ASIS_MAGIC_TYPE, asis_handler},
- {"send-as-is", asis_handler},
- {NULL}
-};
+ ap_hook_handler(asis_handler,NULL,NULL,AP_HOOK_MIDDLE);
+}
module AP_MODULE_DECLARE_DATA asis_module =
{
NULL, /* create per-server config structure */
NULL, /* merge per-server config structures */
NULL, /* command apr_table_t */
- asis_handlers, /* handlers */
- NULL /* register hooks */
+ register_hooks /* register hooks */
};
/* The formal handler... */
-static int handle_autoindex(request_rec *r)
+static int handle_autoindex(const char *handler,request_rec *r)
{
autoindex_config_rec *d;
- int allow_opts = ap_allow_options(r);
+ int allow_opts;
+
+ if(strcmp(handler,DIR_MAGIC_TYPE))
+ return DECLINED;
+
+ allow_opts = ap_allow_options(r);
d = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config,
&autoindex_module);
}
}
-
-static const handler_rec autoindex_handlers[] =
+static void register_hooks(void)
{
- {DIR_MAGIC_TYPE, handle_autoindex},
- {NULL}
-};
+ ap_hook_handler(handle_autoindex,NULL,NULL,AP_HOOK_MIDDLE);
+}
module AP_MODULE_DECLARE_DATA autoindex_module =
{
NULL, /* server config */
NULL, /* merge server config */
autoindex_cmds, /* command apr_table_t */
- autoindex_handlers, /* handlers */
- NULL /* register hooks */
+ register_hooks /* register hooks */
};
return APR_SUCCESS;
}
-static int cgi_handler(request_rec *r)
+static int cgi_handler(const char *handler, request_rec *r)
{
int retval, nph, dbpos = 0;
const char *argv0;
cgi_server_conf *conf;
apr_status_t rv;
+ if(strcmp(handler,CGI_MAGIC_TYPE) && strcmp(handler,"cgi-script"))
+ return DECLINED;
+
p = r->main ? r->main->pool : r->pool;
if (r->method_number == M_OPTIONS) {
return OK; /* NOT r->status, even if it has changed. */
}
-static const handler_rec cgi_handlers[] =
+static void register_hooks(void)
{
- {CGI_MAGIC_TYPE, cgi_handler},
- {"cgi-script", cgi_handler},
- {NULL}
-};
+ ap_hook_handler(cgi_handler, NULL, NULL, AP_HOOK_MIDDLE);
+}
module AP_MODULE_DECLARE_DATA cgi_module =
{
create_cgi_config, /* server config */
merge_cgi_config, /* merge server config */
cgi_cmds, /* command apr_table_t */
- cgi_handlers, /* handlers */
- NULL /* register hooks */
+ register_hooks /* register hooks */
};
*
* Actual cgid handling...
*/
-static int cgid_handler(request_rec *r)
+static int cgid_handler(const char *handler, request_rec *r)
{
int retval, nph, dbpos = 0;
char *argv0, *dbuf = NULL;
ap_bucket_brigade *bb;
ap_bucket *b;
char argsbuffer[HUGE_STRING_LEN];
- void *sconf = r->server->module_config;
- cgid_server_conf *conf = (cgid_server_conf *) ap_get_module_config(sconf, &cgid_module);
- int is_included = !strcmp(r->protocol, "INCLUDED");
+ void *sconf;
+ cgid_server_conf *conf;
+ int is_included;
int sd;
char **env;
struct sockaddr_un unix_addr;
apr_file_t *tempsock = NULL;
apr_size_t nbytes;
+ if(strcmp(handler,CGI_MAGIC_TYPE) && strcmp(handler,"cgi-script"))
+ return DECLINED;
+
if (r->method_number == M_OPTIONS) {
/* 99 out of 100 cgid scripts, this is all they support */
r->allowed |= (1 << M_GET);
return DECLINED;
}
+ sconf = r->server->module_config;
+ conf = (cgid_server_conf *) ap_get_module_config(sconf, &cgid_module);
+ is_included = !strcmp(r->protocol, "INCLUDED");
+
if ((argv0 = strrchr(r->filename, '/')) != NULL)
argv0++;
else
return OK; /* NOT r->status, even if it has changed. */
}
-static const handler_rec cgid_handlers[] =
-{
- {CGI_MAGIC_TYPE, cgid_handler},
- {"cgi-script", cgid_handler},
- {NULL}
-};
-
static void register_hook(void)
{
ap_hook_post_config(cgid_init, NULL, NULL, AP_HOOK_MIDDLE);
+ ap_hook_handler(cgid_handler, NULL, NULL, AP_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA cgid_module = {
create_cgid_config, /* server config */
merge_cgid_config, /* merge server config */
cgid_cmds, /* command table */
- cgid_handlers, /* handlers */
register_hook /* register_handlers */
};
static int do_nothing(request_rec *r) { return OK; }
-static int default_handler(request_rec *r)
+static int default_handler(const char *handler, request_rec *r)
{
ap_bucket_brigade *bb;
ap_bucket *e;
- core_dir_config *d =
- (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
+ core_dir_config *d;
int errstatus;
apr_file_t *fd = NULL;
apr_status_t status;
* support fairly closely (unlike 1.3, we don't handle computing md5
* when the charset is translated).
*/
- int bld_content_md5 =
- (d->content_md5 & 1) && r->output_filters->frec->ftype != AP_FTYPE_CONTENT;
+ int bld_content_md5;
+
+ /*
+ * The old way of doing handlers meant that this handler would
+ * match literally anything - this way will require handler to
+ * have a / in the middle, which probably captures the original
+ * intent, but may cause problems at first - Ben 7th Jan 01
+ */
+ if(strcmp(handler,"request-handler")
+ && ap_strcmp_match(handler,"*/*"))
+ return DECLINED;
+
+ d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
+ &core_module);
+ bld_content_md5 = (d->content_md5 & 1)
+ && r->output_filters->frec->ftype != AP_FTYPE_CONTENT;
ap_allow_methods(r, MERGE_ALLOW, "GET", "OPTIONS", "POST", NULL);
return APR_SUCCESS;
}
-static const handler_rec core_handlers[] = {
-{ "*/*", default_handler },
-{ "default-handler", default_handler },
-{ NULL, NULL }
-};
-
static void core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
{
ap_init_bucket_types(pconf);
ap_hook_http_method(core_method,NULL,NULL,AP_HOOK_REALLY_LAST);
ap_hook_default_port(core_port,NULL,NULL,AP_HOOK_REALLY_LAST);
ap_hook_open_logs(core_open_logs,NULL,NULL,AP_HOOK_MIDDLE);
+ ap_hook_handler(default_handler,NULL,NULL,AP_HOOK_REALLY_LAST);
/* FIXME: I suspect we can eliminate the need for these - Ben */
ap_hook_type_checker(do_nothing,NULL,NULL,AP_HOOK_REALLY_LAST);
ap_hook_access_checker(do_nothing,NULL,NULL,AP_HOOK_REALLY_LAST);
create_core_server_config, /* create per-server config structure */
merge_core_server_configs, /* merge per-server config structures */
core_cmds, /* command apr_table_t */
- core_handlers, /* handlers */
register_hooks /* register hooks */
};
NULL, /* create per-server config structure */
NULL, /* merge per-server config structures */
mime_cmds, /* command apr_table_t */
- NULL, /* handlers */
register_hooks /* register hooks */
};
make_config_log_state, /* server config */
merge_config_log_state, /* merge server config */
config_log_cmds, /* command apr_table_t */
- NULL, /* handlers */
register_hooks /* register hooks */
};
{NULL}
};
-static int action_handler(request_rec *r)
+static int action_handler(const char *handler,request_rec *r)
{
action_dir_config *conf = (action_dir_config *)
ap_get_module_config(r->per_dir_config, &action_module);
const char *script;
int i;
+ /* Note that this handler handles _all_ types, so handler is unchecked */
+
/* Set allowed stuff */
for (i = 0; i < METHODS; ++i) {
if (conf->scripted[i])
return OK;
}
-static const handler_rec action_handlers[] =
+static void register_hooks(void)
{
- {"*/*", action_handler},
- {NULL}
-};
+ ap_hook_handler(action_handler,NULL,NULL,AP_HOOK_LAST);
+}
module action_module =
{
NULL, /* server config */
NULL, /* merge server config */
action_cmds, /* command apr_table_t */
- action_handlers, /* handlers */
- NULL /* register hooks */
+ register_hooks /* register hooks */
};
create_alias_config, /* server config */
merge_alias_config, /* merge server configs */
alias_cmds, /* command apr_table_t */
- NULL, /* handlers */
register_hooks /* register hooks */
};
return new;
}
-static int handle_dir(request_rec *r)
+static int handle_dir(const char *handler,request_rec *r)
{
- dir_config_rec *d =
- (dir_config_rec *) ap_get_module_config(r->per_dir_config,
- &dir_module);
+ dir_config_rec *d;
char *dummy_ptr[1];
char **names_ptr;
int num_names;
int error_notfound = 0;
+ if(strcmp(handler,DIR_MAGIC_TYPE))
+ return DECLINED;
+
+ d = (dir_config_rec *) ap_get_module_config(r->per_dir_config,
+ &dir_module);
+
if (r->uri[0] == '\0' || r->uri[strlen(r->uri) - 1] != '/') {
char *ifile;
if (r->args != NULL)
}
-static const handler_rec dir_handlers[] =
+static void register_hooks(void)
{
- {DIR_MAGIC_TYPE, handle_dir},
- {NULL}
-};
+ static const char * const aszSucc[]={ "mod_autoindex.c", NULL };
+
+ ap_hook_handler(handle_dir,NULL,aszSucc,AP_HOOK_MIDDLE);
+}
module AP_MODULE_DECLARE_DATA dir_module = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-server config structure */
NULL, /* merge per-server config structures */
dir_cmds, /* command apr_table_t */
- dir_handlers, /* handlers */
- NULL /* register hooks */
+ register_hooks /* register hooks */
};
ap_rputs("\n\n</body>\n</html>\n", r); /* finish the menu */
}
-static int imap_handler(request_rec *r)
+static int imap_handler(const char *handler,request_rec *r)
{
char input[MAX_STRING_LEN];
char *directive;
char *string_pos;
int showmenu = 0;
- imap_conf_rec *icr = ap_get_module_config(r->per_dir_config, &imap_module);
+ imap_conf_rec *icr;
- char *imap_menu = icr->imap_menu ? icr->imap_menu : IMAP_MENU_DEFAULT;
- char *imap_default = icr->imap_default
- ? icr->imap_default : IMAP_DEFAULT_DEFAULT;
- char *imap_base = icr->imap_base ? icr->imap_base : IMAP_BASE_DEFAULT;
+ char *imap_menu;
+ char *imap_default;
+ char *imap_base;
configfile_t *imap;
- if (r->method_number != M_GET) {
+ if (r->method_number != M_GET || (strcmp(handler,IMAP_MAGIC_TYPE)
+ && strcmp(handler, "imap-file")))
return DECLINED;
- }
+
+ icr = ap_get_module_config(r->per_dir_config, &imap_module);
+
+ imap_menu = icr->imap_menu ? icr->imap_menu : IMAP_MENU_DEFAULT;
+ imap_default = icr->imap_default
+ ? icr->imap_default : IMAP_DEFAULT_DEFAULT;
+ imap_base = icr->imap_base ? icr->imap_base : IMAP_BASE_DEFAULT;
status = ap_pcfg_openfile(&imap, r->pool, r->filename);
return HTTP_INTERNAL_SERVER_ERROR;
}
-
-static const handler_rec imap_handlers[] =
+static void register_hooks(void)
{
- {IMAP_MAGIC_TYPE, imap_handler},
- {"imap-file", imap_handler},
- {NULL}
-};
+ ap_hook_handler(imap_handler,NULL,NULL,AP_HOOK_MIDDLE);
+}
module AP_MODULE_DECLARE_DATA imap_module =
{
NULL, /* server config */
NULL, /* merge server config */
imap_cmds, /* command apr_table_t */
- imap_handlers, /* handlers */
- NULL /* register hooks */
+ register_hooks /* register hooks */
};
return OK;
}
-static int handle_map_file(request_rec *r)
+static int handle_map_file(const char *handler,request_rec *r)
{
- negotiation_state *neg = parse_accept_headers(r);
+ negotiation_state *neg;
var_rec *best;
int res;
-
char *udir;
+ if(strcmp(handler,MAP_FILE_MAGIC_TYPE) && strcmp(handler,"type-map"))
+ return DECLINED;
+
+ neg = parse_accept_headers(r);
if ((res = read_type_map(neg, r))) {
return res;
}
return DECLINED;
}
-static const handler_rec negotiation_handlers[] =
-{
- {MAP_FILE_MAGIC_TYPE, handle_map_file},
- {"type-map", handle_map_file},
- {NULL}
-};
-
static void register_hooks(void)
{
ap_hook_fixups(fix_encoding,NULL,NULL,AP_HOOK_MIDDLE);
ap_hook_type_checker(handle_multi,NULL,NULL,AP_HOOK_FIRST);
+ ap_hook_handler(handle_map_file,NULL,NULL,AP_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA negotiation_module =
NULL, /* server config */
NULL, /* merge server config */
negotiation_cmds, /* command apr_table_t */
- negotiation_handlers, /* handlers */
register_hooks /* register hooks */
};
create_userdir_config, /* server config */
NULL, /* merge server config */
userdir_cmds, /* command apr_table_t */
- NULL, /* handlers */
register_hooks /* register hooks */
};
NULL, /* server config */
NULL, /* merge server configs */
env_module_cmds, /* command apr_table_t */
- NULL, /* handlers */
register_hooks /* register hooks */
};
create_setenvif_config_svr, /* server config */
merge_setenvif_config, /* merge server configs */
setenvif_module_cmds, /* command apr_table_t */
- NULL, /* handlers */
register_hooks /* register hooks */
};
AP_DECLARE_DATA ap_directive_t *ap_conftree;
AP_HOOK_STRUCT(
- AP_HOOK_LINK(header_parser)
- AP_HOOK_LINK(pre_config)
- AP_HOOK_LINK(post_config)
- AP_HOOK_LINK(open_logs)
- AP_HOOK_LINK(child_init)
+ AP_HOOK_LINK(header_parser)
+ AP_HOOK_LINK(pre_config)
+ AP_HOOK_LINK(post_config)
+ AP_HOOK_LINK(open_logs)
+ AP_HOOK_LINK(child_init)
+ AP_HOOK_LINK(handler)
)
AP_IMPLEMENT_HOOK_RUN_ALL(int,header_parser,
AP_IMPLEMENT_HOOK_VOID(child_init,
(apr_pool_t *pchild, server_rec *s),(pchild,s))
+AP_IMPLEMENT_HOOK_RUN_FIRST(int,handler,(const char *handler,request_rec *r),
+ (handler,r),DECLINED)
+
/****************************************************************
*
* We begin with the functions which deal with the linked list
return create_empty_config(p);
}
-/*
- * For speed/efficiency we generate a compact list of all the handlers
- * and wildcard handlers. This means we won't have to scan the entire
- * module list looking for handlers... where we'll find a whole whack
- * of NULLs.
- */
-typedef struct {
- handler_rec hr;
- size_t len;
-} fast_handler_rec;
-
-static fast_handler_rec *handlers;
-static fast_handler_rec *wildhandlers;
-
-static void init_handlers(apr_pool_t *p)
-{
- module *modp;
- int nhandlers = 0;
- int nwildhandlers = 0;
- const handler_rec *handp;
- fast_handler_rec *ph, *pw;
- const char *starp;
-
- for (modp = top_module; modp; modp = modp->next) {
- if (!modp->handlers)
- continue;
- for (handp = modp->handlers; handp->content_type; ++handp) {
- if (ap_strchr_c(handp->content_type, '*')) {
- nwildhandlers ++;
- } else {
- nhandlers ++;
- }
- }
- }
- ph = handlers = apr_palloc(p, sizeof(*ph)*(nhandlers + 1));
- pw = wildhandlers = apr_palloc(p, sizeof(*pw)*(nwildhandlers + 1));
- for (modp = top_module; modp; modp = modp->next) {
- if (!modp->handlers)
- continue;
- for (handp = modp->handlers; handp->content_type; ++handp) {
- if ((starp = ap_strchr_c(handp->content_type, '*'))) {
- pw->hr.content_type = handp->content_type;
- pw->hr.handler = handp->handler;
- pw->len = starp - handp->content_type;
- pw ++;
- } else {
- ph->hr.content_type = handp->content_type;
- ph->hr.handler = handp->handler;
- ph->len = strlen(handp->content_type);
- ph ++;
- }
- }
- }
- pw->hr.content_type = NULL;
- pw->hr.handler = NULL;
- ph->hr.content_type = NULL;
- ph->hr.handler = NULL;
-}
-
int ap_invoke_handler(request_rec *r)
{
- fast_handler_rec *handp;
const char *handler;
const char *p;
size_t handler_len;
}
}
- /* Pass one --- direct matches */
-
- for (handp = handlers; handp->hr.content_type; ++handp) {
- if (handler_len == handp->len
- && !strncmp(handler, handp->hr.content_type, handler_len)) {
- result = (*handp->hr.handler) (r);
-
- if (result != DECLINED)
- return result;
- }
- }
-
- /* Pass two --- wildcard matches */
-
- for (handp = wildhandlers; handp->hr.content_type; ++handp) {
- if (handler_len >= handp->len
- && !strncmp(handler, handp->hr.content_type, handp->len)) {
- result = (*handp->hr.handler) (r);
-
- if (result != DECLINED)
- return result;
- }
- }
+ result=ap_run_handler(handler,r);
- if (result == HTTP_INTERNAL_SERVER_ERROR && r->handler && r->filename) {
+ if (result == DECLINED && r->handler && r->filename) {
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
"handler \"%s\" not found for: %s", r->handler, r->filename);
}
- return HTTP_INTERNAL_SERVER_ERROR;
+ return result == DECLINED ? HTTP_INTERNAL_SERVER_ERROR : result;
}
AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method) {
AP_DECLARE(void) ap_post_config_hook(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
ap_run_post_config(pconf,plog,ptemp,s);
- init_handlers(pconf);
}
void ap_child_init_hook(apr_pool_t *pchild, server_rec *s)
NULL, /* create per-server config structure */
NULL, /* merge per-server config structures */
mpmt_pthread_cmds, /* command apr_table_t */
- NULL, /* handlers */
mpmt_pthread_hooks /* register_hooks */
};
static int restart_num = 0;
int no_detach = 0;
- one_process = !!getenv("ONE_PROCESS");
no_detach = !!getenv("NO_DETACH");
/* sigh, want this only the second time around */
#ifdef AUX3
(void) set42sig();
#endif
- /* TODO: set one_process properly */ one_process = 0;
+ one_process = !!getenv("ONE_PROCESS");
ap_hook_pre_config(prefork_pre_config, NULL, NULL, AP_HOOK_MIDDLE);
}
NULL, /* create per-server config structure */
NULL, /* merge per-server config structures */
prefork_cmds, /* command apr_table_t */
- NULL, /* handlers */
prefork_hooks, /* register hooks */
};