1 /* ====================================================================
2 * Copyright (c) 1995-2000 The Apache Software Foundation. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the Apache Software Foundation
19 * for use in the Apache HTTP server project (http://www.apache.org/)."
21 * 4. The names "Apache Server" and "Apache Software Foundation" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
26 * 5. Products derived from this software may not be called "Apache"
27 * nor may "Apache" appear in their names without prior written
28 * permission of the Apache Software Foundation.
30 * 6. Redistributions of any form whatsoever must retain the following
32 * "This product includes software developed by the Apache Software Foundation
33 * for use in the Apache HTTP server project (http://www.apache.org/)."
35 * THIS SOFTWARE IS PROVIDED BY THE Apache Software Foundation ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE Apache Software Foundation OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
49 * This software consists of voluntary contributions made by many
50 * individuals on behalf of the Apache Software Foundation and was originally based
51 * on public domain software written at the National Center for
52 * Supercomputing Applications, University of Illinois, Urbana-Champaign.
53 * For more information on the Apache Software Foundation and the Apache HTTP server
54 * project, please see <http://www.apache.org/>.
59 * http_config.c: once was auxillary functions for reading httpd's config
60 * file and converting filenames into a namespace
64 * Wall-to-wall rewrite for Apache... commands which are part of the
65 * server core can now be found next door in "http_core.c". Now contains
66 * general command loop, and functions which do bookkeeping for the new
67 * Apache config stuff (modules and configuration vectors).
75 #include "ap_config.h"
76 #include "apr_portable.h"
77 #include "apr_file_io.h"
79 #include "http_config.h"
80 #include "http_core.h"
81 #include "http_log.h" /* for errors in parse_htaccess */
82 #include "http_request.h" /* for default_handler (see invoke_handler) */
83 #include "http_main.h"
84 #include "http_vhost.h"
87 HOOK_LINK(header_parser)
89 HOOK_LINK(post_config)
94 IMPLEMENT_HOOK_RUN_ALL(int,header_parser,(request_rec *r),(r),OK,DECLINED)
95 IMPLEMENT_HOOK_VOID(pre_config,(ap_context_t *pconf,ap_context_t *plog,ap_context_t *ptemp),
97 IMPLEMENT_HOOK_VOID(post_config,
98 (ap_context_t *pconf, ap_context_t *plog, ap_context_t *ptemp, server_rec *s),
100 IMPLEMENT_HOOK_VOID(open_logs,
101 (ap_context_t *pconf, ap_context_t *plog, ap_context_t *ptemp, server_rec *s),
102 (pconf,plog,ptemp,s))
103 IMPLEMENT_HOOK_VOID(child_init,(ap_context_t *pchild, server_rec *s),(pchild,s))
105 /****************************************************************
107 * We begin with the functions which deal with the linked list
108 * of modules which control just about all of the server operation.
111 /* total_modules is the number of modules that have been linked
114 static int total_modules = 0;
115 /* dynamic_modules is the number of modules that have been added
116 * after the pre-loaded ones have been set up. It shouldn't be larger
117 * than DYNAMIC_MODULE_LIMIT.
119 static int dynamic_modules = 0;
120 API_VAR_EXPORT module *top_module = NULL;
121 API_VAR_EXPORT module **ap_loaded_modules=NULL;
123 typedef int (*handler_func) (request_rec *);
124 typedef void *(*dir_maker_func) (ap_context_t *, char *);
125 typedef void *(*merger_func) (ap_context_t *, void *, void *);
127 /* Dealing with config vectors. These are associated with per-directory,
128 * per-server, and per-request configuration, and have a void* pointer for
129 * each modules. The nature of the structure pointed to is private to the
130 * module in question... the core doesn't (and can't) know. However, there
131 * are defined interfaces which allow it to create instances of its private
132 * per-directory and per-server structures, and to merge the per-directory
133 * structures of a directory and its subdirectory (producing a new one in
134 * which the defaults applying to the base directory have been properly
138 #ifndef ap_get_module_config
139 API_EXPORT(void *) ap_get_module_config(void *conf_vector, module *m)
141 void **confv = (void **) conf_vector;
142 return confv[m->module_index];
146 #ifndef ap_set_module_config
147 API_EXPORT(void) ap_set_module_config(void *conf_vector, module *m, void *val)
149 void **confv = (void **) conf_vector;
150 confv[m->module_index] = val;
154 static void *create_empty_config(ap_context_t *p)
156 void **conf_vector = (void **) ap_pcalloc(p, sizeof(void *) *
157 (total_modules + DYNAMIC_MODULE_LIMIT));
158 return (void *) conf_vector;
161 static void *create_default_per_dir_config(ap_context_t *p)
163 void **conf_vector = (void **) ap_pcalloc(p, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT));
166 for (modp = top_module; modp; modp = modp->next) {
167 dir_maker_func df = modp->create_dir_config;
170 conf_vector[modp->module_index] = (*df) (p, NULL);
173 return (void *) conf_vector;
177 ap_merge_per_dir_configs(ap_context_t *p, void *base, void *new)
179 void **conf_vector = (void **) ap_palloc(p, sizeof(void *) * total_modules);
180 void **base_vector = (void **) base;
181 void **new_vector = (void **) new;
184 for (modp = top_module; modp; modp = modp->next) {
185 merger_func df = modp->merge_dir_config;
186 int i = modp->module_index;
188 if (df && new_vector[i])
189 conf_vector[i] = (*df) (p, base_vector[i], new_vector[i]);
191 conf_vector[i] = new_vector[i] ? new_vector[i] : base_vector[i];
194 return (void *) conf_vector;
197 static void *create_server_config(ap_context_t *p, server_rec *s)
199 void **conf_vector = (void **) ap_pcalloc(p, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT));
202 for (modp = top_module; modp; modp = modp->next) {
203 if (modp->create_server_config)
204 conf_vector[modp->module_index] = (*modp->create_server_config) (p, s);
207 return (void *) conf_vector;
210 static void merge_server_configs(ap_context_t *p, void *base, void *virt)
212 /* Can reuse the 'virt' vector for the spine of it, since we don't
213 * have to deal with the moral equivalent of .htaccess files here...
216 void **base_vector = (void **) base;
217 void **virt_vector = (void **) virt;
220 for (modp = top_module; modp; modp = modp->next) {
221 merger_func df = modp->merge_server_config;
222 int i = modp->module_index;
225 virt_vector[i] = base_vector[i];
227 virt_vector[i] = (*df) (p, base_vector[i], virt_vector[i]);
231 void *ap_create_request_config(ap_context_t *p)
233 return create_empty_config(p);
236 void *ap_create_conn_config(ap_context_t *p)
238 return create_empty_config(p);
241 CORE_EXPORT(void *) ap_create_per_dir_config(ap_context_t *p)
243 return create_empty_config(p);
247 * For speed/efficiency we generate a compact list of all the handlers
248 * and wildcard handlers. This means we won't have to scan the entire
249 * module list looking for handlers... where we'll find a whole whack
257 static fast_handler_rec *handlers;
258 static fast_handler_rec *wildhandlers;
260 static void init_handlers(ap_context_t *p)
264 int nwildhandlers = 0;
265 const handler_rec *handp;
266 fast_handler_rec *ph, *pw;
269 for (modp = top_module; modp; modp = modp->next) {
272 for (handp = modp->handlers; handp->content_type; ++handp) {
273 if (strchr(handp->content_type, '*')) {
280 ph = handlers = ap_palloc(p, sizeof(*ph)*(nhandlers + 1));
281 pw = wildhandlers = ap_palloc(p, sizeof(*pw)*(nwildhandlers + 1));
282 for (modp = top_module; modp; modp = modp->next) {
285 for (handp = modp->handlers; handp->content_type; ++handp) {
286 if ((starp = strchr(handp->content_type, '*'))) {
287 pw->hr.content_type = handp->content_type;
288 pw->hr.handler = handp->handler;
289 pw->len = starp - handp->content_type;
292 ph->hr.content_type = handp->content_type;
293 ph->hr.handler = handp->handler;
294 ph->len = strlen(handp->content_type);
299 pw->hr.content_type = NULL;
300 pw->hr.handler = NULL;
301 ph->hr.content_type = NULL;
302 ph->hr.handler = NULL;
305 int ap_invoke_handler(request_rec *r)
307 fast_handler_rec *handp;
311 int result = HTTP_INTERNAL_SERVER_ERROR;
314 handler = r->handler;
315 handler_len = strlen(handler);
318 handler = r->content_type ? r->content_type : ap_default_type(r);
319 if ((p = strchr(handler, ';')) != NULL) { /* MIME type arguments */
320 while (p > handler && p[-1] == ' ')
321 --p; /* strip trailing spaces */
322 handler_len = p - handler;
325 handler_len = strlen(handler);
329 /* Pass one --- direct matches */
331 for (handp = handlers; handp->hr.content_type; ++handp) {
332 if (handler_len == handp->len
333 && !strncmp(handler, handp->hr.content_type, handler_len)) {
334 result = (*handp->hr.handler) (r);
336 if (result != DECLINED)
341 /* Pass two --- wildcard matches */
343 for (handp = wildhandlers; handp->hr.content_type; ++handp) {
344 if (handler_len >= handp->len
345 && !strncmp(handler, handp->hr.content_type, handp->len)) {
346 result = (*handp->hr.handler) (r);
348 if (result != DECLINED)
353 if (result == HTTP_INTERNAL_SERVER_ERROR && r->handler && r->filename) {
354 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
355 "handler \"%s\" not found for: %s", r->handler, r->filename);
357 return HTTP_INTERNAL_SERVER_ERROR;
361 const char *g_szCurrentHookName;
363 static void register_hooks(module *m)
365 if(m->register_hooks)
367 if(getenv("SHOW_HOOKS"))
369 printf("Registering hooks for %s\n",m->name);
372 g_szCurrentHookName=m->name;
377 /* One-time setup for precompiled modules --- NOT to be done on restart */
379 API_EXPORT(void) ap_add_module(module *m)
381 /* This could be called from an AddModule httpd.conf command,
382 * after the file has been linked and the module structure within it
386 if (m->version != MODULE_MAGIC_NUMBER_MAJOR) {
387 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
388 "%s: module \"%s\" is not compatible with this "
389 "version of Apache.", ap_server_argv0, m->name);
390 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "Please contact the vendor for the correct version.");
394 if (m->next == NULL) {
395 m->next = top_module;
398 if (m->module_index == -1) {
399 m->module_index = total_modules++;
402 if (dynamic_modules > DYNAMIC_MODULE_LIMIT) {
403 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
404 "%s: module \"%s\" could not be loaded, because"
405 " the dynamic", ap_server_argv0, m->name);
406 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
407 "module limit was reached. Please increase "
408 "DYNAMIC_MODULE_LIMIT and recompile.");
413 /* Some C compilers put a complete path into __FILE__, but we want
414 * only the filename (e.g. mod_includes.c). So check for path
415 * components (Unix and DOS), and remove them.
418 if (strrchr(m->name, '/'))
419 m->name = 1 + strrchr(m->name, '/');
420 if (strrchr(m->name, '\\'))
421 m->name = 1 + strrchr(m->name, '\\');
423 #ifdef _OSD_POSIX /* __FILE__="*POSIX(/home/martin/apache/src/modules/standard/mod_info.c)" */
424 /* We cannot fix the string in-place, because it's const */
425 if (m->name[strlen(m->name)-1]==')') {
426 char *tmp = strdup(m->name); /* FIXME:memory leak, albeit a small one */
427 tmp[strlen(tmp)-1] = '\0';
430 #endif /*_OSD_POSIX*/
432 /* FIXME: is this the right place to call this? */
437 * remove_module undoes what add_module did. There are some caveats:
438 * when the module is removed, its slot is lost so all the current
439 * per-dir and per-server configurations are invalid. So we should
440 * only ever call this function when you are invalidating almost
441 * all our current data. I.e. when doing a restart.
444 API_EXPORT(void) ap_remove_module(module *m)
450 /* We are the top module, special case */
451 top_module = modp->next;
455 /* Not the top module, find use. When found modp will
456 * point to the module _before_ us in the list
459 while (modp && modp->next != m) {
463 /* Uh-oh, this module doesn't exist */
464 ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, NULL,
465 "Cannot remove module %s: not found in module list",
469 /* Eliminate us from the module list */
470 modp->next = modp->next->next;
473 m->module_index = -1; /* simulate being unloaded, should
479 API_EXPORT(void) ap_add_loaded_module(module *mod)
484 * Add module pointer to top of chained module list
489 * And module pointer to list of loaded modules
491 * Notes: 1. ap_add_module() would already complain if no more space
492 * exists for adding a dynamically loaded module
493 * 2. ap_add_module() accepts double inclusion, so we have
494 * to accept this, too.
496 for (m = ap_loaded_modules; *m != NULL; m++)
502 API_EXPORT(void) ap_remove_loaded_module(module *mod)
509 * Remove module pointer from chained module list
511 ap_remove_module(mod);
514 * Remove module pointer from list of loaded modules
516 * Note: 1. We cannot determine if the module was successfully
517 * removed by ap_remove_module().
518 * 2. We have not to complain explicity when the module
519 * is not found because ap_remove_module() did it
522 for (m = m2 = ap_loaded_modules, done = 0; *m2 != NULL; m2++) {
523 if (*m2 == mod && done == 0)
531 void ap_setup_prelinked_modules(process_rec *process)
537 * Initialise total_modules variable and module indices
540 for (m = ap_preloaded_modules; *m != NULL; m++)
541 (*m)->module_index = total_modules++;
544 * Initialise list of loaded modules
546 ap_loaded_modules = (module **)ap_palloc(process->pool,
547 sizeof(module *)*(total_modules+DYNAMIC_MODULE_LIMIT+1));
548 if (ap_loaded_modules == NULL) {
549 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
550 "Ouch! Out of memory in ap_setup_prelinked_modules()!");
552 for (m = ap_preloaded_modules, m2 = ap_loaded_modules; *m != NULL; )
557 * Initialize chain of linked (=activate) modules
559 for (m = ap_prelinked_modules; *m != NULL; m++)
565 API_EXPORT(const char *) ap_find_module_name(module *m)
570 API_EXPORT(module *) ap_find_linked_module(const char *name)
574 for (modp = top_module; modp; modp = modp->next) {
575 if (strcmp(modp->name, name) == 0)
581 /* Add a named module. Returns 1 if module found, 0 otherwise. */
582 API_EXPORT(int) ap_add_named_module(const char *name)
587 for (modp = ap_loaded_modules[i]; modp; modp = ap_loaded_modules[++i]) {
588 if (strcmp(modp->name, name) == 0) {
589 /* Only add modules that are not already enabled. */
590 if (modp->next == NULL) {
600 /* Clear the internal list of modules, in preparation for starting over. */
601 API_EXPORT(void) ap_clear_module_list()
603 module **m = &top_module;
607 next_m = &((*m)->next);
612 /* This is required; so we add it always. */
613 ap_add_named_module("http_core.c");
616 /*****************************************************************
618 * Resource, access, and .htaccess config files now parsed by a common
621 * Let's begin with the basics; parsing the line and
622 * invoking the function...
625 static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
626 void *mconfig, const char *args)
631 if ((parms->override & cmd->req_override) == 0)
632 return ap_pstrcat(parms->pool, cmd->name, " not allowed here", NULL);
634 parms->info = cmd->cmd_data;
637 switch (cmd->args_how) {
639 #ifdef RESOLVE_ENV_PER_TOKEN
640 args = ap_resolve_env(parms->pool,args);
642 return ((const char *(*)(cmd_parms *, void *, const char *))
643 (cmd->func)) (parms, mconfig, args);
647 return ap_pstrcat(parms->pool, cmd->name, " takes no arguments",
650 return ((const char *(*)(cmd_parms *, void *))
651 (cmd->func)) (parms, mconfig);
654 w = ap_getword_conf(parms->pool, &args);
656 if (*w == '\0' || *args != 0)
657 return ap_pstrcat(parms->pool, cmd->name, " takes one argument",
658 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
660 return ((const char *(*)(cmd_parms *, void *, const char *))
661 (cmd->func)) (parms, mconfig, w);
665 w = ap_getword_conf(parms->pool, &args);
666 w2 = ap_getword_conf(parms->pool, &args);
668 if (*w == '\0' || *w2 == '\0' || *args != 0)
669 return ap_pstrcat(parms->pool, cmd->name, " takes two arguments",
670 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
672 return ((const char *(*)(cmd_parms *, void *, const char *,
673 const char *)) (cmd->func)) (parms, mconfig, w, w2);
677 w = ap_getword_conf(parms->pool, &args);
678 w2 = ap_getword_conf(parms->pool, &args);
680 if (*w == '\0' || *args != 0)
681 return ap_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments",
682 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
684 return ((const char *(*)(cmd_parms *, void *, const char *,
685 const char *)) (cmd->func)) (parms, mconfig, w,
690 w = ap_getword_conf(parms->pool, &args);
691 w2 = ap_getword_conf(parms->pool, &args);
692 w3 = ap_getword_conf(parms->pool, &args);
694 if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0)
695 return ap_pstrcat(parms->pool, cmd->name, " takes three arguments",
696 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
698 return ((const char *(*)(cmd_parms *, void *, const char *,
699 const char *, const char *)) (cmd->func)) (parms,
704 w = ap_getword_conf(parms->pool, &args);
705 w2 = ap_getword_conf(parms->pool, &args);
706 w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
708 if (*w == '\0' || *w2 == '\0' || *args != 0)
709 return ap_pstrcat(parms->pool, cmd->name,
710 " takes two or three arguments",
711 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
713 return ((const char *(*)(cmd_parms *, void *, const char *,
714 const char *, const char *)) (cmd->func)) (parms,
719 w = ap_getword_conf(parms->pool, &args);
720 w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
721 w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
723 if (*w == '\0' || *args != 0)
724 return ap_pstrcat(parms->pool, cmd->name,
725 " takes one, two or three arguments",
726 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
728 return ((const char *(*)(cmd_parms *, void *, const char *,
729 const char *, const char *)) (cmd->func)) (parms,
734 w = ap_getword_conf(parms->pool, &args);
735 w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
736 w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
738 if (*w == '\0' || (*w2 && !w3) || *args != 0)
739 return ap_pstrcat(parms->pool, cmd->name,
740 " takes one or three arguments",
741 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
743 return ((const char *(*)(cmd_parms *, void *, const char *,
744 const char *, const char *)) (cmd->func)) (parms,
749 while (*(w = ap_getword_conf(parms->pool, &args)) != '\0')
750 if ((errmsg = ((const char *(*)(cmd_parms *, void *,
751 const char *)) (cmd->func)) (parms, mconfig, w)))
758 w = ap_getword_conf(parms->pool, &args);
760 if (*w == '\0' || *args == 0)
761 return ap_pstrcat(parms->pool, cmd->name,
762 " requires at least two arguments",
763 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
766 while (*(w2 = ap_getword_conf(parms->pool, &args)) != '\0')
767 if ((errmsg = ((const char *(*)(cmd_parms *, void *,
768 const char *, const char *)) (cmd->func)) (parms,
776 w = ap_getword_conf(parms->pool, &args);
778 if (*w == '\0' || (strcasecmp(w, "on") && strcasecmp(w, "off")))
779 return ap_pstrcat(parms->pool, cmd->name, " must be On or Off",
782 return ((const char *(*)(cmd_parms *, void *, int))
783 (cmd->func)) (parms, mconfig, strcasecmp(w, "off") != 0);
787 return ap_pstrcat(parms->pool, cmd->name,
788 " is improperly configured internally (server bug)",
793 CORE_EXPORT(const command_rec *) ap_find_command(const char *name, const command_rec *cmds)
796 if (!strcasecmp(name, cmds->name))
804 CORE_EXPORT(const command_rec *) ap_find_command_in_modules(const char *cmd_name, module **mod)
806 const command_rec *cmdp;
809 for (modp = *mod; modp; modp = modp->next)
810 if (modp->cmds && (cmdp = ap_find_command(cmd_name, modp->cmds))) {
818 CORE_EXPORT(void *) ap_set_config_vectors(cmd_parms *parms, void *config, module *mod)
820 void *mconfig = ap_get_module_config(config, mod);
821 void *sconfig = ap_get_module_config(parms->server->module_config, mod);
823 if (!mconfig && mod->create_dir_config) {
824 mconfig = (*mod->create_dir_config) (parms->pool, parms->path);
825 ap_set_module_config(config, mod, mconfig);
828 if (!sconfig && mod->create_server_config) {
829 sconfig = (*mod->create_server_config) (parms->pool, parms->server);
830 ap_set_module_config(parms->server->module_config, mod, sconfig);
836 CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, const char *l)
839 const char *args, *cmd_name, *retval;
840 const command_rec *cmd;
841 module *mod = top_module;
843 if ((l[0] == '#') || (!l[0]))
846 #if RESOLVE_ENV_PER_TOKEN
849 args = ap_resolve_env(parms->temp_pool,l);
851 cmd_name = ap_getword_conf(parms->temp_pool, &args);
852 if (*cmd_name == '\0')
855 oldconfig = parms->context;
856 parms->context = config;
858 if (!(cmd = ap_find_command_in_modules(cmd_name, &mod))) {
860 return ap_pstrcat(parms->pool, "Invalid command '", cmd_name,
861 "', perhaps mis-spelled or defined by a module "
862 "not included in the server configuration", NULL);
865 void *mconfig = ap_set_config_vectors(parms,config, mod);
867 retval = invoke_cmd(cmd, parms, mconfig, args);
868 mod = mod->next; /* Next time around, skip this one */
870 } while (retval && !strcmp(retval, DECLINE_CMD));
871 parms->context = oldconfig;
876 API_EXPORT(const char *) ap_srm_command_loop(cmd_parms *parms, void *config)
878 char l[MAX_STRING_LEN];
880 while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) {
881 const char *errmsg = ap_handle_command(parms, config, l);
891 * Generic command functions...
894 API_EXPORT_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd,
895 char *struct_ptr, char *arg)
897 /* This one's pretty generic... */
899 int offset = (int) (long) cmd->info;
900 *(char **) (struct_ptr + offset) = arg;
904 API_EXPORT_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd,
905 char *struct_ptr, char *arg)
907 /* This one's pretty generic... */
909 int offset = (int) (long) cmd->info;
911 *(char **) (struct_ptr + offset) = arg;
915 API_EXPORT_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd,
916 char *struct_ptr, int arg)
918 /* This one's pretty generic too... */
920 int offset = (int) (long) cmd->info;
921 *(int *) (struct_ptr + offset) = arg ? 1 : 0;
925 API_EXPORT_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, char *struct_ptr, char *arg)
927 /* Prepend server_root to relative arg.
928 This allows .htaccess to be independent of server_root,
929 so the server can be moved or mirrored with less pain. */
931 int offset = (int) (long) cmd->info;
932 if (ap_os_is_path_absolute(arg))
935 p = ap_make_full_path(cmd->pool, ap_server_root, arg);
936 *(char **) (struct_ptr + offset) = p;
940 /*****************************************************************
942 * Reading whole config files...
945 static cmd_parms default_parms =
946 {NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
948 API_EXPORT(const char *) ap_server_root_relative(ap_context_t *p, const char *file)
950 if(ap_os_is_path_absolute(file))
952 return ap_make_full_path(p, ap_server_root, file);
956 /* This structure and the following functions are needed for the
957 * table-based config file reading. They are passed to the
958 * cfg_open_custom() routine.
961 /* Structure to be passed to cfg_open_custom(): it contains an
962 * index which is incremented from 0 to nelts on each call to
963 * cfg_getline() (which in turn calls arr_elts_getstr())
964 * and an ap_array_header_t pointer for the string array.
967 ap_array_header_t *array;
972 /* arr_elts_getstr() returns the next line from the string array. */
973 static void *arr_elts_getstr(void *buf, size_t bufsiz, void *param)
975 arr_elts_param_t *arr_param = (arr_elts_param_t *) param;
977 /* End of array reached? */
978 if (++arr_param->curr_idx > arr_param->array->nelts)
981 /* return the line */
982 ap_cpystrn(buf, ((char **) arr_param->array->elts)[arr_param->curr_idx - 1], bufsiz);
988 /* arr_elts_close(): dummy close routine (makes sure no more lines can be read) */
989 static int arr_elts_close(void *param)
991 arr_elts_param_t *arr_param = (arr_elts_param_t *) param;
992 arr_param->curr_idx = arr_param->array->nelts;
996 static void process_command_config(server_rec *s, ap_array_header_t *arr, ap_context_t *p,
1001 arr_elts_param_t arr_parms;
1003 arr_parms.curr_idx = 0;
1004 arr_parms.array = arr;
1006 parms = default_parms;
1008 parms.temp_pool = ptemp;
1010 parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
1011 parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives",
1013 arr_elts_getstr, arr_elts_close);
1015 errmsg = ap_srm_command_loop(&parms, s->lookup_defaults);
1018 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
1019 "Syntax error in -C/-c directive:\n%s", errmsg);
1023 ap_cfg_closefile(parms.config_file);
1026 void ap_process_resource_config(server_rec *s, const char *fname, ap_context_t *p, ap_context_t *ptemp)
1032 fname = ap_server_root_relative(p, fname);
1034 if (!(strcmp(fname, ap_server_root_relative(p, RESOURCE_CONFIG_FILE))) ||
1035 !(strcmp(fname, ap_server_root_relative(p, ACCESS_CONFIG_FILE)))) {
1036 if (ap_stat(&finfo, fname, p) != APR_SUCCESS)
1040 /* don't require conf/httpd.conf if we have a -C or -c switch */
1041 if((ap_server_pre_read_config->nelts || ap_server_post_read_config->nelts) &&
1042 !(strcmp(fname, ap_server_root_relative(p, SERVER_CONFIG_FILE)))) {
1043 if (ap_stat(&finfo, fname, p) != APR_SUCCESS)
1047 /* GCC's initialization extensions are soooo nice here... */
1049 parms = default_parms;
1051 parms.temp_pool = ptemp;
1053 parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
1055 if (ap_pcfg_openfile(&parms.config_file, p, fname) != APR_SUCCESS) {
1056 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
1057 "%s: could not open document config file %s",
1058 ap_server_argv0, fname);
1062 errmsg = ap_srm_command_loop(&parms, s->lookup_defaults);
1065 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
1066 "Syntax error on line %d of %s:",
1067 parms.config_file->line_number, parms.config_file->name);
1068 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
1073 ap_cfg_closefile(parms.config_file);
1077 int ap_parse_htaccess(void **result, request_rec *r, int override,
1078 const char *d, const char *access_name)
1080 configfile_t *f = NULL;
1083 char *filename = NULL;
1084 const struct htaccess_result *cache;
1085 struct htaccess_result *new;
1089 /* firstly, search cache */
1090 for (cache = r->htaccess; cache != NULL; cache = cache->next)
1091 if (cache->override == override && strcmp(cache->dir, d) == 0) {
1092 if (cache->htaccess != NULL)
1093 *result = cache->htaccess;
1097 parms = default_parms;
1098 parms.override = override;
1099 parms.pool = r->pool;
1100 parms.temp_pool = r->pool;
1101 parms.server = r->server;
1102 parms.path = ap_pstrdup(r->pool, d);
1104 /* loop through the access names and find the first one */
1106 while (access_name[0]) {
1107 filename = ap_make_full_path(r->pool, d,
1108 ap_getword_conf(r->pool, &access_name));
1109 status = ap_pcfg_openfile(&f, r->pool, filename);
1111 if (status == APR_SUCCESS) {
1113 dc = ap_create_per_dir_config(r->pool);
1115 parms.config_file = f;
1117 errmsg = ap_srm_command_loop(&parms, dc);
1119 ap_cfg_closefile(f);
1122 ap_log_rerror(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, 0, r,
1123 "%s: %s", filename, errmsg);
1124 return HTTP_INTERNAL_SERVER_ERROR;
1129 else if (status != APR_ENOENT && status != APR_ENOTDIR) {
1130 ap_log_rerror(APLOG_MARK, APLOG_CRIT, errno, r,
1131 "%s pcfg_openfile: unable to check htaccess file, "
1132 "ensure it is readable",
1134 ap_table_setn(r->notes, "error-notes",
1135 "Server unable to read htaccess file, denying "
1136 "access to be safe");
1137 return HTTP_FORBIDDEN;
1142 new = ap_palloc(r->pool, sizeof(struct htaccess_result));
1143 new->dir = parms.path;
1144 new->override = override;
1146 /* add to head of list */
1147 new->next = r->htaccess;
1154 CORE_EXPORT(const char *) ap_init_virtual_host(ap_context_t *p, const char *hostname,
1155 server_rec *main_server, server_rec **ps)
1157 server_rec *s = (server_rec *) ap_pcalloc(p, sizeof(server_rec));
1159 #ifdef RLIMIT_NOFILE
1160 struct rlimit limits;
1162 getrlimit(RLIMIT_NOFILE, &limits);
1163 if (limits.rlim_cur < limits.rlim_max) {
1164 limits.rlim_cur += 2;
1165 if (setrlimit(RLIMIT_NOFILE, &limits) < 0) {
1166 perror("setrlimit(RLIMIT_NOFILE)");
1167 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
1168 "Cannot exceed hard limit for open files");
1173 /* TODO: this crap belongs in http_core */
1174 s->process = main_server->process;
1175 s->server_admin = NULL;
1176 s->server_hostname = NULL;
1177 s->error_fname = NULL;
1178 s->srm_confname = NULL;
1179 s->access_confname = NULL;
1181 s->keep_alive_timeout = 0;
1183 s->keep_alive_max = -1;
1184 s->error_log = main_server->error_log;
1185 s->loglevel = main_server->loglevel;
1186 /* useful default, otherwise we get a port of 0 on redirects */
1187 s->port = main_server->port;
1191 s->names = ap_make_array(p, 4, sizeof(char **));
1192 s->wild_names = ap_make_array(p, 4, sizeof(char **));
1194 s->module_config = create_empty_config(p);
1195 s->lookup_defaults = ap_create_per_dir_config(p);
1198 s->server_uid = ap_user_id;
1199 s->server_gid = ap_group_id;
1202 s->limit_req_line = main_server->limit_req_line;
1203 s->limit_req_fieldsize = main_server->limit_req_fieldsize;
1204 s->limit_req_fields = main_server->limit_req_fields;
1208 return ap_parse_vhost_addrs(p, hostname, s);
1212 static void fixup_virtual_hosts(ap_context_t *p, server_rec *main_server)
1216 for (virt = main_server->next; virt; virt = virt->next) {
1217 merge_server_configs(p, main_server->module_config,
1218 virt->module_config);
1220 virt->lookup_defaults =
1221 ap_merge_per_dir_configs(p, main_server->lookup_defaults,
1222 virt->lookup_defaults);
1224 if (virt->server_admin == NULL)
1225 virt->server_admin = main_server->server_admin;
1227 if (virt->srm_confname == NULL)
1228 virt->srm_confname = main_server->srm_confname;
1230 if (virt->access_confname == NULL)
1231 virt->access_confname = main_server->access_confname;
1233 if (virt->timeout == 0)
1234 virt->timeout = main_server->timeout;
1236 if (virt->keep_alive_timeout == 0)
1237 virt->keep_alive_timeout = main_server->keep_alive_timeout;
1239 if (virt->keep_alive == -1)
1240 virt->keep_alive = main_server->keep_alive;
1242 if (virt->keep_alive_max == -1)
1243 virt->keep_alive_max = main_server->keep_alive_max;
1245 /* XXX: this is really something that should be dealt with by a
1246 * post-config api phase */
1247 ap_core_reorder_directories(p, virt);
1249 ap_core_reorder_directories(p, main_server);
1252 /*****************************************************************
1254 * Getting *everything* configured...
1257 static void init_config_globals(ap_context_t *p)
1259 /* Global virtual host hash bucket pointers. Init to null. */
1260 ap_init_vhost_config(p);
1263 static server_rec *init_server_config(process_rec *process, ap_context_t *p)
1265 server_rec *s = (server_rec *) ap_pcalloc(p, sizeof(server_rec));
1267 ap_open_stderr(&s->error_log, p);
1268 s->process = process;
1270 s->server_admin = DEFAULT_ADMIN;
1271 s->server_hostname = NULL;
1272 s->error_fname = DEFAULT_ERRORLOG;
1273 s->loglevel = DEFAULT_LOGLEVEL;
1274 s->srm_confname = RESOURCE_CONFIG_FILE;
1275 s->access_confname = ACCESS_CONFIG_FILE;
1276 s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
1277 s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
1278 s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
1279 s->timeout = DEFAULT_TIMEOUT;
1280 s->keep_alive_timeout = DEFAULT_KEEPALIVE_TIMEOUT;
1281 s->keep_alive_max = DEFAULT_KEEPALIVE;
1284 s->addrs = ap_pcalloc(p, sizeof(server_addr_rec));
1285 /* NOT virtual host; don't match any real network interface */
1286 s->addrs->host_addr.s_addr = htonl(INADDR_ANY);
1287 s->addrs->host_port = 0; /* matches any port */
1288 s->addrs->virthost = ""; /* must be non-NULL */
1289 s->names = s->wild_names = NULL;
1291 s->module_config = create_server_config(p, s);
1292 s->lookup_defaults = create_default_per_dir_config(p);
1298 server_rec *ap_read_config(process_rec *process, ap_context_t *ptemp, const char *confname)
1300 ap_context_t *p = process->pconf;
1301 server_rec *s = init_server_config(process, p);
1303 init_config_globals(p);
1305 /* All server-wide config files now have the SAME syntax... */
1307 process_command_config(s, ap_server_pre_read_config, p, ptemp);
1309 ap_process_resource_config(s, confname, p, ptemp);
1310 ap_process_resource_config(s, s->srm_confname, p, ptemp);
1311 ap_process_resource_config(s, s->access_confname, p, ptemp);
1313 process_command_config(s, ap_server_post_read_config, p, ptemp);
1315 fixup_virtual_hosts(p, s);
1316 ap_fini_vhost_config(p, s);
1322 void ap_single_module_configure(ap_context_t *p, server_rec *s, module *m)
1324 if (m->create_server_config)
1325 ap_set_module_config(s->module_config, m,
1326 (*m->create_server_config)(p, s));
1327 if (m->create_dir_config)
1328 ap_set_module_config(s->lookup_defaults, m,
1329 (*m->create_dir_config)(p, NULL));
1332 void ap_post_config_hook(ap_context_t *pconf, ap_context_t *plog, ap_context_t *ptemp, server_rec *s)
1334 ap_run_post_config(pconf,plog,ptemp,s);
1335 init_handlers(pconf);
1338 void ap_child_init_hook(ap_context_t *pchild, server_rec *s)
1340 /* TODO: uh this seems ugly, is there a better way? */
1341 /*ap_child_init_alloc(); PUT THIS BACK IN XXXXX */
1343 ap_run_child_init(pchild,s);
1346 /********************************************************************
1347 * Configuration directives are restricted in terms of where they may
1348 * appear in the main configuration files and/or .htaccess files according
1349 * to the bitmask req_override in the command_rec structure.
1350 * If any of the overrides set in req_override are also allowed in the
1351 * context in which the command is read, then the command is allowed.
1352 * The context is determined as follows:
1354 * inside *.conf --> override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);
1355 * within <Directory> or <Location> --> override = OR_ALL|ACCESS_CONF;
1356 * within .htaccess --> override = AllowOverride for current directory;
1358 * the result is, well, a rather confusing set of possibilities for when
1359 * a particular directive is allowed to be used. This procedure prints
1360 * in English where the given (pc) directive can be used.
1362 static void show_overrides(const command_rec *pc, module *pm)
1366 printf("\tAllowed in *.conf ");
1367 if ((pc->req_override & (OR_OPTIONS | OR_FILEINFO | OR_INDEXES)) ||
1368 ((pc->req_override & RSRC_CONF) &&
1369 ((pc->req_override & (ACCESS_CONF | OR_AUTHCFG | OR_LIMIT)))))
1371 else if (pc->req_override & RSRC_CONF)
1372 printf("only outside <Directory>, <Files> or <Location>");
1374 printf("only inside <Directory>, <Files> or <Location>");
1376 /* Warn if the directive is allowed inside <Directory> or .htaccess
1377 * but module doesn't support per-dir configuration */
1379 if ((pc->req_override & (OR_ALL | ACCESS_CONF)) && !pm->create_dir_config)
1380 printf(" [no per-dir config]");
1382 if (pc->req_override & OR_ALL) {
1383 printf(" and in .htaccess\n\twhen AllowOverride");
1385 if ((pc->req_override & OR_ALL) == OR_ALL)
1386 printf(" isn't None");
1388 printf(" includes ");
1390 if (pc->req_override & OR_AUTHCFG) {
1393 printf("AuthConfig");
1395 if (pc->req_override & OR_LIMIT) {
1400 if (pc->req_override & OR_OPTIONS) {
1405 if (pc->req_override & OR_FILEINFO) {
1410 if (pc->req_override & OR_INDEXES) {
1420 /* Show the preloaded configuration directives, the help string explaining
1421 * the directive arguments, in what module they are handled, and in
1422 * what parts of the configuration they are allowed. Used for httpd -h.
1424 void ap_show_directives()
1426 const command_rec *pc;
1429 for (n = 0; ap_loaded_modules[n]; ++n)
1430 for (pc = ap_loaded_modules[n]->cmds; pc && pc->name; ++pc) {
1431 printf("%s (%s)\n", pc->name, ap_loaded_modules[n]->name);
1433 printf("\t%s\n", pc->errmsg);
1434 show_overrides(pc, ap_loaded_modules[n]);
1438 /* Show the preloaded module names. Used for httpd -l. */
1439 void ap_show_modules()
1443 printf("Compiled in modules:\n");
1444 for (n = 0; ap_loaded_modules[n]; ++n)
1445 printf(" %s\n", ap_loaded_modules[n]->name);