📄 config.c
字号:
/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * http_config.c: once was auxillary functions for reading httpd's config * file and converting filenames into a namespace * * Rob McCool * * Wall-to-wall rewrite for Apache... commands which are part of the * server core can now be found next door in "http_core.c". Now contains * general command loop, and functions which do bookkeeping for the new * Apache config stuff (modules and configuration vectors). * * rst * */#include "apr.h"#include "apr_strings.h"#include "apr_portable.h"#include "apr_file_io.h"#include "apr_fnmatch.h"#define APR_WANT_STDIO#define APR_WANT_STRFUNC#include "apr_want.h"#define CORE_PRIVATE#include "ap_config.h"#include "httpd.h"#include "http_config.h"#include "http_protocol.h"#include "http_core.h"#include "http_log.h" /* for errors in parse_htaccess */#include "http_request.h" /* for default_handler (see invoke_handler) */#include "http_main.h"#include "http_vhost.h"#include "util_cfgtree.h"#include "mpm.h"AP_DECLARE_DATA const char *ap_server_argv0 = NULL;AP_DECLARE_DATA const char *ap_server_root = NULL;AP_DECLARE_DATA apr_array_header_t *ap_server_pre_read_config = NULL;AP_DECLARE_DATA apr_array_header_t *ap_server_post_read_config = NULL;AP_DECLARE_DATA apr_array_header_t *ap_server_config_defines = NULL;AP_DECLARE_DATA ap_directive_t *ap_conftree = NULL;APR_HOOK_STRUCT( APR_HOOK_LINK(header_parser) APR_HOOK_LINK(pre_config) APR_HOOK_LINK(post_config) APR_HOOK_LINK(open_logs) APR_HOOK_LINK(child_init) APR_HOOK_LINK(handler) APR_HOOK_LINK(quick_handler) APR_HOOK_LINK(optional_fn_retrieve))AP_IMPLEMENT_HOOK_RUN_ALL(int, header_parser, (request_rec *r), (r), OK, DECLINED)AP_IMPLEMENT_HOOK_RUN_ALL(int, pre_config, (apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp), (pconf, plog, ptemp), OK, DECLINED)AP_IMPLEMENT_HOOK_RUN_ALL(int, post_config, (apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s), (pconf, plog, ptemp, s), OK, DECLINED)/* During the course of debugging I expanded this macro out, so * rather than remove all the useful information there is in the * following lines, I'm going to leave it here in case anyone * else finds it useful. * * Ben has looked at it and thinks it correct :) *AP_DECLARE(int) ap_hook_post_config(ap_HOOK_post_config_t *pf, const char * const *aszPre, const char * const *aszSucc, int nOrder){ ap_LINK_post_config_t *pHook; if (!_hooks.link_post_config) { _hooks.link_post_config = apr_array_make(apr_hook_global_pool, 1, sizeof(ap_LINK_post_config_t)); apr_hook_sort_register("post_config", &_hooks.link_post_config); } pHook = apr_array_push(_hooks.link_post_config); pHook->pFunc = pf; pHook->aszPredecessors = aszPre; pHook->aszSuccessors = aszSucc; pHook->nOrder = nOrder; pHook->szName = apr_hook_debug_current; if (apr_hook_debug_enabled) apr_hook_debug_show("post_config", aszPre, aszSucc);}AP_DECLARE(apr_array_header_t *) ap_hook_get_post_config(void) { return _hooks.link_post_config;}AP_DECLARE(int) ap_run_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s){ ap_LINK_post_config_t *pHook; int n; if(!_hooks.link_post_config) return; pHook = (ap_LINK_post_config_t *)_hooks.link_post_config->elts; for (n = 0; n < _hooks.link_post_config->nelts; ++n) pHook[n].pFunc (pconf, plog, ptemp, s);} */AP_IMPLEMENT_HOOK_RUN_ALL(int, open_logs, (apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s), (pconf, plog, ptemp, s), OK, DECLINED)AP_IMPLEMENT_HOOK_VOID(child_init, (apr_pool_t *pchild, server_rec *s), (pchild, s))AP_IMPLEMENT_HOOK_RUN_FIRST(int, handler, (request_rec *r), (r), DECLINED)AP_IMPLEMENT_HOOK_RUN_FIRST(int, quick_handler, (request_rec *r, int lookup), (r, lookup), DECLINED)AP_IMPLEMENT_HOOK_VOID(optional_fn_retrieve, (void), ())/**************************************************************** * * We begin with the functions which deal with the linked list * of modules which control just about all of the server operation. *//* total_modules is the number of modules that have been linked * into the server. */static int total_modules = 0;/* dynamic_modules is the number of modules that have been added * after the pre-loaded ones have been set up. It shouldn't be larger * than DYNAMIC_MODULE_LIMIT. */static int dynamic_modules = 0;AP_DECLARE_DATA module *ap_top_module = NULL;AP_DECLARE_DATA module **ap_loaded_modules=NULL;typedef int (*handler_func)(request_rec *);typedef void *(*dir_maker_func)(apr_pool_t *, char *);typedef void *(*merger_func)(apr_pool_t *, void *, void *);/* maximum nesting level for config directories */#ifndef AP_MAX_INCLUDE_DIR_DEPTH#define AP_MAX_INCLUDE_DIR_DEPTH (128)#endif/* Dealing with config vectors. These are associated with per-directory, * per-server, and per-request configuration, and have a void* pointer for * each modules. The nature of the structure pointed to is private to the * module in question... the core doesn't (and can't) know. However, there * are defined interfaces which allow it to create instances of its private * per-directory and per-server structures, and to merge the per-directory * structures of a directory and its subdirectory (producing a new one in * which the defaults applying to the base directory have been properly * overridden). */static ap_conf_vector_t *create_empty_config(apr_pool_t *p){ void *conf_vector = apr_pcalloc(p, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT)); return conf_vector;}static ap_conf_vector_t *create_default_per_dir_config(apr_pool_t *p){ void **conf_vector = apr_pcalloc(p, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT)); module *modp; for (modp = ap_top_module; modp; modp = modp->next) { dir_maker_func df = modp->create_dir_config; if (df) conf_vector[modp->module_index] = (*df)(p, NULL); } return (ap_conf_vector_t *)conf_vector;}AP_CORE_DECLARE(ap_conf_vector_t *) ap_merge_per_dir_configs(apr_pool_t *p, ap_conf_vector_t *base, ap_conf_vector_t *new_conf){ void **conf_vector = apr_palloc(p, sizeof(void *) * total_modules); void **base_vector = (void **)base; void **new_vector = (void **)new_conf; module *modp; for (modp = ap_top_module; modp; modp = modp->next) { int i = modp->module_index; if (!new_vector[i]) { conf_vector[i] = base_vector[i]; } else { merger_func df = modp->merge_dir_config; if (df && base_vector[i]) { conf_vector[i] = (*df)(p, base_vector[i], new_vector[i]); } else conf_vector[i] = new_vector[i]; } } return (ap_conf_vector_t *)conf_vector;}static ap_conf_vector_t *create_server_config(apr_pool_t *p, server_rec *s){ void **conf_vector = apr_pcalloc(p, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT)); module *modp; for (modp = ap_top_module; modp; modp = modp->next) { if (modp->create_server_config) conf_vector[modp->module_index] = (*modp->create_server_config)(p, s); } return (ap_conf_vector_t *)conf_vector;}static void merge_server_configs(apr_pool_t *p, ap_conf_vector_t *base, ap_conf_vector_t *virt){ /* Can reuse the 'virt' vector for the spine of it, since we don't * have to deal with the moral equivalent of .htaccess files here... */ void **base_vector = (void **)base; void **virt_vector = (void **)virt; module *modp; for (modp = ap_top_module; modp; modp = modp->next) { merger_func df = modp->merge_server_config; int i = modp->module_index; if (!virt_vector[i]) virt_vector[i] = base_vector[i]; else if (df) virt_vector[i] = (*df)(p, base_vector[i], virt_vector[i]); }}AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_request_config(apr_pool_t *p){ return create_empty_config(p);}AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_conn_config(apr_pool_t *p){ return create_empty_config(p);}AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_per_dir_config(apr_pool_t *p){ return create_empty_config(p);}static int ap_invoke_filter_init(ap_filter_t *filters){ while (filters) { if (filters->frec->filter_init_func) { int result = filters->frec->filter_init_func(filters); if (result != OK) { return result; } } filters = filters->next; } return OK;}AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r){ const char *handler; const char *p; int result; const char *old_handler = r->handler; /* * The new insert_filter stage makes the most sense here. We only use * it when we are going to run the request, so we must insert filters * if any are available. Since the goal of this phase is to allow all * modules to insert a filter if they want to, this filter returns * void. I just can't see any way that this filter can reasonably * fail, either your modules inserts something or it doesn't. rbb */ ap_run_insert_filter(r); /* Before continuing, allow each filter that is in the two chains to * run their init function to let them do any magic before we could * start generating data. */ result = ap_invoke_filter_init(r->input_filters); if (result != OK) { return result; } result = ap_invoke_filter_init(r->output_filters); if (result != OK) { return result; } if (!r->handler) { handler = r->content_type ? r->content_type : ap_default_type(r); if ((p=ap_strchr_c(handler, ';')) != NULL) { char *new_handler = (char *)apr_pmemdup(r->pool, handler, p - handler + 1); char *p2 = new_handler + (p - handler); handler = new_handler; /* MIME type arguments */ while (p2 > handler && p2[-1] == ' ') --p2; /* strip trailing spaces */ *p2='\0'; } r->handler = handler; } result = ap_run_handler(r); r->handler = old_handler; if (result == DECLINED && r->handler && r->filename) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "handler \"%s\" not found for: %s", r->handler, r->filename); } return result == DECLINED ? HTTP_INTERNAL_SERVER_ERROR : result;}AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method){ int methnum; methnum = ap_method_number_of(method); /* * A method number either hardcoded into apache or * added by a module and registered. */ if (methnum != M_INVALID) { return (cmd->limited & (AP_METHOD_BIT << methnum)) ? 1 : 0; } return 0; /* not found */}AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p){ if (m->register_hooks) { if (getenv("SHOW_HOOKS")) { printf("Registering hooks for %s\n", m->name); apr_hook_debug_enabled = 1; } apr_hook_debug_current = m->name; m->register_hooks(p); }}/* One-time setup for precompiled modules --- NOT to be done on restart */AP_DECLARE(void) ap_add_module(module *m, apr_pool_t *p){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -