📄 mod_example.c
字号:
* true anywhere in the upstream configuration. */ merged_config->congenital = (pconf->congenital | pconf->local); /* * If we're merging records for two different types of environment (server * and directory), mark the new record appropriately. Otherwise, inherit * the current value. */ merged_config->cmode = (pconf->cmode == nconf->cmode) ? pconf->cmode : CONFIG_MODE_COMBO; /* * Now just record our being called in the trace list. Include the * locations we were asked to merge. */ note = ap_pstrcat(p, "example_merge_dir_config(\"", pconf->loc, "\",\"", nconf->loc, "\")", NULL); trace_add(NULL, NULL, merged_config, note); return (void *) merged_config;}/* * This function gets called to create a per-server configuration * record. It will always be called for the "default" server. * * The return value is a pointer to the created module-specific * structure. */static void *example_create_server_config(pool *p, server_rec *s){ excfg *cfg; char *sname = s->server_hostname; /* * As with the example_create_dir_config() reoutine, we allocate and fill * in an empty record. */ cfg = (excfg *) ap_pcalloc(p, sizeof(excfg)); cfg->local = 0; cfg->congenital = 0; cfg->cmode = CONFIG_MODE_SERVER; /* * Note that we were called in the trace list. */ sname = (sname != NULL) ? sname : ""; cfg->loc = ap_pstrcat(p, "SVR(", sname, ")", NULL); trace_add(s, NULL, cfg, "example_create_server_config()"); return (void *) cfg;}/* * This function gets called to merge two per-server configuration * records. This is typically done to cope with things like virtual hosts and * the default server configuration The routine has the responsibility of * creating a new record and merging the contents of the other two into it * appropriately. If the module doesn't declare a merge routine, the more * specific existing record is used exclusively. * * The routine MUST NOT modify any of its arguments! * * The return value is a pointer to the created module-specific structure * containing the merged values. */static void *example_merge_server_config(pool *p, void *server1_conf, void *server2_conf){ excfg *merged_config = (excfg *) ap_pcalloc(p, sizeof(excfg)); excfg *s1conf = (excfg *) server1_conf; excfg *s2conf = (excfg *) server2_conf; char *note; /* * Our inheritance rules are our own, and part of our module's semantics. * Basically, just note whence we came. */ merged_config->cmode = (s1conf->cmode == s2conf->cmode) ? s1conf->cmode : CONFIG_MODE_COMBO; merged_config->local = s2conf->local; merged_config->congenital = (s1conf->congenital | s1conf->local); merged_config->loc = ap_pstrdup(p, s2conf->loc); /* * Trace our call, including what we were asked to merge. */ note = ap_pstrcat(p, "example_merge_server_config(\"", s1conf->loc, "\",\"", s2conf->loc, "\")", NULL); trace_add(NULL, NULL, merged_config, note); return (void *) merged_config;}/* * This routine is called after the request has been read but before any other * phases have been processed. This allows us to make decisions based upon * the input header fields. * * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no * further modules are called for this phase. */static int example_post_read_request(request_rec *r){ excfg *cfg; cfg = our_dconfig(r); /* * We don't actually *do* anything here, except note the fact that we were * called. */ trace_add(r->server, r, cfg, "example_post_read_request()"); return DECLINED;}/* * This routine gives our module an opportunity to translate the URI into an * actual filename. If we don't do anything special, the server's default * rules (Alias directives and the like) will continue to be followed. * * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no * further modules are called for this phase. */static int example_translate_handler(request_rec *r){ excfg *cfg; cfg = our_dconfig(r); /* * We don't actually *do* anything here, except note the fact that we were * called. */ trace_add(r->server, r, cfg, "example_translate_handler()"); return DECLINED;}/* * This routine is called to check the authentication information sent with * the request (such as looking up the user in a database and verifying that * the [encrypted] password sent matches the one in the database). * * The return value is OK, DECLINED, or some HTTP_mumble error (typically * HTTP_UNAUTHORIZED). If we return OK, no other modules are given a chance * at the request during this phase. */static int example_check_user_id(request_rec *r){ excfg *cfg; cfg = our_dconfig(r); /* * Don't do anything except log the call. */ trace_add(r->server, r, cfg, "example_check_user_id()"); return DECLINED;}/* * This routine is called to check to see if the resource being requested * requires authorisation. * * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no * other modules are called during this phase. * * If *all* modules return DECLINED, the request is aborted with a server * error. */static int example_auth_checker(request_rec *r){ excfg *cfg; cfg = our_dconfig(r); /* * Log the call and return OK, or access will be denied (even though we * didn't actually do anything). */ trace_add(r->server, r, cfg, "example_auth_checker()"); return DECLINED;}/* * This routine is called to check for any module-specific restrictions placed * upon the requested resource. (See the mod_access module for an example.) * * The return value is OK, DECLINED, or HTTP_mumble. All modules with an * handler for this phase are called regardless of whether their predecessors * return OK or DECLINED. The first one to return any other status, however, * will abort the sequence (and the request) as usual. */static int example_access_checker(request_rec *r){ excfg *cfg; cfg = our_dconfig(r); trace_add(r->server, r, cfg, "example_access_checker()"); return DECLINED;}/* * This routine is called to determine and/or set the various document type * information bits, like Content-type (via r->content_type), language, et * cetera. * * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no * further modules are given a chance at the request for this phase. */static int example_type_checker(request_rec *r){ excfg *cfg; cfg = our_dconfig(r); /* * Log the call, but don't do anything else - and report truthfully that * we didn't do anything. */ trace_add(r->server, r, cfg, "example_type_checker()"); return DECLINED;}/* * This routine is called to perform any module-specific fixing of header * fields, et cetera. It is invoked just before any content-handler. * * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the * server will still call any remaining modules with an handler for this * phase. */static int example_fixer_upper(request_rec *r){ excfg *cfg; cfg = our_dconfig(r); /* * Log the call and exit. */ trace_add(r->server, r, cfg, "example_fixer_upper()"); return OK;}/* * This routine is called to perform any module-specific logging activities * over and above the normal server things. * * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, any * remaining modules with an handler for this phase will still be called. */static int example_logger(request_rec *r){ excfg *cfg; cfg = our_dconfig(r); trace_add(r->server, r, cfg, "example_logger()"); return DECLINED;}/* * This routine is called to give the module a chance to look at the request * headers and take any appropriate specific actions early in the processing * sequence. * * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, any * remaining modules with handlers for this phase will still be called. */static int example_header_parser(request_rec *r){ excfg *cfg; cfg = our_dconfig(r); trace_add(r->server, r, cfg, "example_header_parser()"); return DECLINED;}/*--------------------------------------------------------------------------*//* *//* All of the routines have been declared now. Here's the list of *//* directives specific to our module, and information about where they *//* may appear and how the command parser should pass them to us for *//* processing. Note that care must be taken to ensure that there are NO *//* collisions of directive names between modules. *//* *//*--------------------------------------------------------------------------*//* * List of directives specific to our module. */static const command_rec example_cmds[] ={ { "Example", /* directive name */ cmd_example, /* config action routine */ NULL, /* argument to include in call */ OR_OPTIONS, /* where available */ NO_ARGS, /* arguments */ "Example directive - no arguments" /* directive description */ }, {NULL}};/*--------------------------------------------------------------------------*//* *//* Now the list of content handlers available from this module. *//* *//*--------------------------------------------------------------------------*//* * List of content handlers our module supplies. Each handler is defined by * two parts: a name by which it can be referenced (such as by * {Add,Set}Handler), and the actual routine name. The list is terminated by * a NULL block, since it can be of variable length. * * Note that content-handlers are invoked on a most-specific to least-specific * basis; that is, a handler that is declared for "text/plain" will be * invoked before one that was declared for "text / *". Note also that * if a content-handler returns anything except DECLINED, no other * content-handlers will be called. */static const handler_rec example_handlers[] ={ {"example-handler", example_handler}, {NULL}};/*--------------------------------------------------------------------------*//* *//* Finally, the list of callback routines and data structures that *//* provide the hooks into our module from the other parts of the server. *//* *//*--------------------------------------------------------------------------*//* * Module definition for configuration. If a particular callback is not * needed, replace its routine name below with the word NULL. * * The number in brackets indicates the order in which the routine is called * during request processing. Note that not all routines are necessarily * called (such as if a resource doesn't have access restrictions). */module MODULE_VAR_EXPORT example_module ={ STANDARD_MODULE_STUFF, example_init, /* module initializer */ example_create_dir_config, /* per-directory config creator */ example_merge_dir_config, /* dir config merger */ example_create_server_config, /* server config creator */ example_merge_server_config, /* server config merger */ example_cmds, /* command table */ example_handlers, /* [9] list of handlers */ example_translate_handler, /* [2] filename-to-URI translation */ example_check_user_id, /* [5] check/validate user_id */ example_auth_checker, /* [6] check user_id is valid *here* */ example_access_checker, /* [4] check access by host address */ example_type_checker, /* [7] MIME type checker/setter */ example_fixer_upper, /* [8] fixups */ example_logger, /* [10] logger */#if MODULE_MAGIC_NUMBER >= 19970103 example_header_parser, /* [3] header parser */#endif#if MODULE_MAGIC_NUMBER >= 19970719 example_child_init, /* process initializer */#endif#if MODULE_MAGIC_NUMBER >= 19970728 example_child_exit, /* process exit/cleanup */#endif#if MODULE_MAGIC_NUMBER >= 19970902 example_post_read_request /* [1] post read_request handling */#endif};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -