From ab31187b8dc15713e11977d3fab730b7fbc4f6bf Mon Sep 17 00:00:00 2001 From: Ryan Bloom Date: Sat, 22 Apr 2000 22:54:30 +0000 Subject: [PATCH] Parse the config tree, instead of the config file. This is a first step there are some big improvements to be made to this code, but this works now, and it is a first step. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85015 13f79535-47bb-0310-9956-ffa450edef68 --- include/http_config.h | 4 +- modules/http/http_core.c | 78 ++++------------------ server/config.c | 140 +++++++++++++++++++++++---------------- server/util_cfgtree.c | 8 +-- 4 files changed, 102 insertions(+), 128 deletions(-) diff --git a/include/http_config.h b/include/http_config.h index 8d94afac88..e2b7f70f61 100644 --- a/include/http_config.h +++ b/include/http_config.h @@ -60,6 +60,7 @@ #define APACHE_HTTP_CONFIG_H #include "ap_hooks.h" +#include "util_cfgtree.h" #ifdef __cplusplus extern "C" { @@ -304,7 +305,8 @@ API_EXPORT(const char *) ap_find_module_name(module *m); 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); +API_EXPORT(ap_directive_t *) ap_build_config(cmd_parms *parms, ap_directive_t *current); +API_EXPORT(const char *)ap_walk_config(ap_directive_t *conftree, cmd_parms *parms, void *config, int container); /* ap_check_cmd_context() definitions: */ API_EXPORT(const char *) ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden); diff --git a/modules/http/http_core.c b/modules/http/http_core.c index b444edee16..25d9b7e464 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -1383,7 +1383,7 @@ static const char *end_nested_section(cmd_parms *cmd, void *dummy) return ap_pstrcat(cmd->pool, "Expected ", cmd->end_token, " but saw ", cmd->cmd->name, NULL); } - return cmd->end_token; + return NULL; } /* @@ -1436,16 +1436,9 @@ static const char *dirsection(cmd_parms *cmd, void *dummy, const char *arg) old_end_token = cmd->end_token; cmd->end_token = thiscmd->cmd_data ? end_directorymatch_section : end_directory_section; - errmsg = ap_srm_command_loop(cmd, new_dir_conf); - if (errmsg == NULL) { - errmsg = missing_endsection(cmd, 1); - } + + ap_walk_config(NULL, cmd, new_dir_conf, 1); cmd->end_token = old_end_token; - if (errmsg != (thiscmd->cmd_data - ? end_directorymatch_section - : end_directory_section)) { - return errmsg; - } conf = (core_dir_config *)ap_get_module_config(new_dir_conf, &core_module); conf->r = r; @@ -1502,16 +1495,9 @@ static const char *urlsection(cmd_parms *cmd, void *dummy, const char *arg) old_end_token = cmd->end_token; cmd->end_token = thiscmd->cmd_data ? end_locationmatch_section : end_location_section; - errmsg = ap_srm_command_loop(cmd, new_url_conf); - if (errmsg == NULL) { - errmsg = missing_endsection(cmd, 1); - } - cmd->end_token = old_end_token; - if (errmsg != (thiscmd->cmd_data - ? end_locationmatch_section - : end_location_section)) { - return errmsg; - } + + ap_walk_config(NULL, cmd, new_url_conf, 1); + cmd->end_token = old_end_token; conf = (core_dir_config *)ap_get_module_config(new_url_conf, &core_module); conf->d = ap_pstrdup(cmd->pool, cmd->path); /* No mangling, please */ @@ -1576,16 +1562,9 @@ static const char *filesection(cmd_parms *cmd, core_dir_config *c, old_end_token = cmd->end_token; cmd->end_token = thiscmd->cmd_data ? end_filesmatch_section : end_files_section; - errmsg = ap_srm_command_loop(cmd, new_file_conf); - if (errmsg == NULL) { - errmsg = missing_endsection(cmd, 1); - } + + ap_walk_config(NULL, cmd, new_file_conf, 1); cmd->end_token = old_end_token; - if (errmsg != (thiscmd->cmd_data - ? end_filesmatch_section - : end_files_section)) { - return errmsg; - } conf = (core_dir_config *)ap_get_module_config(new_file_conf, &core_module); @@ -1637,23 +1616,9 @@ static const char *start_ifmod(cmd_parms *cmd, void *dummy, char *arg) found = ap_find_linked_module(arg); if ((!not && found) || (not && !found)) { + ap_walk_config(NULL, cmd, cmd->server->lookup_defaults, 1); return NULL; } - - while (nest && !(ap_cfg_getline(l, MAX_STRING_LEN, cmd->config_file))) { - if (!strncasecmp(l, "")) { - nest--; - } - } - - if (nest) { - cmd->end_token = end_ifmodule_section; - return missing_endsection(cmd, nest); - } - return NULL; } API_EXPORT(int) ap_exists_config_define(char *name) @@ -1698,22 +1663,9 @@ static const char *start_ifdefine(cmd_parms *cmd, void *dummy, char *arg) defined = ap_exists_config_define(arg); if ((!not && defined) || (not && !defined)) { - return NULL; - } - - while (nest && !(ap_cfg_getline(l, MAX_STRING_LEN, cmd->config_file))) { - if (!strncasecmp(l, "")) { - nest--; - } - } - if (nest) { - cmd->end_token = end_ifdefine_section; - return missing_endsection(cmd, nest); + ap_walk_config(NULL, cmd, dummy, 1); + return NULL; } - return NULL; } /* httpd.conf commands... beginning with the business */ @@ -1760,12 +1712,10 @@ static const char *virtualhost_section(cmd_parms *cmd, void *dummy, char *arg) old_end_token = cmd->end_token; cmd->end_token = end_virtualhost_section; cmd->server = s; - errmsg = ap_srm_command_loop(cmd, s->lookup_defaults); - cmd->server = main_server; - if (errmsg == NULL) { - errmsg = missing_endsection(cmd, 1); - } + + ap_walk_config(NULL, cmd, s->lookup_defaults, 1); cmd->end_token = old_end_token; + cmd->server = main_server; if (errmsg == end_virtualhost_section) { return NULL; diff --git a/server/config.c b/server/config.c index 9bbc86ef1a..0f899bc74d 100644 --- a/server/config.c +++ b/server/config.c @@ -831,19 +831,13 @@ CORE_EXPORT(void *) ap_set_config_vectors(cmd_parms *parms, void *config, module return mconfig; } - -CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, const char *l) +CORE_EXPORT(void) ap_build_config_sub(cmd_parms *parms, const char *l, ap_directive_t **current, ap_directive_t **curr_parent) { - void *oldconfig; - const char *args, *cmd_name, *retval; - const command_rec *cmd; - module *mod = top_module; + const char *args, *cmd_name; ap_directive_t *newdir; - static ap_directive_t *current = NULL; - static ap_directive_t *curr_parent = NULL; if ((l[0] == '#') || (!l[0])) - return NULL; + return; #if RESOLVE_ENV_PER_TOKEN args = l; @@ -852,7 +846,7 @@ CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, cons #endif cmd_name = ap_getword_conf(parms->temp_pool, &args); if (*cmd_name == '\0') - return NULL; + return; newdir = ap_pcalloc(parms->pool, sizeof(ap_directive_t)); newdir->line_num = parms->config_file->line_number; @@ -861,58 +855,100 @@ CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, cons if (cmd_name[0] == '<') { if (cmd_name[1] != '/') { - current = ap_add_node(&curr_parent, current, newdir, 1); + (*current) = ap_add_node(curr_parent, *current, newdir, 1); } else { /* The next line needs to be removed once we have a validating * tree building routine. - * It is left in for now, so that we can ensure that + * It is left in for now, so that we can ensure that * a container directive is followed by an appropriate closing * directive. */ - current = ap_add_node(&curr_parent, current, newdir, 0); - current = curr_parent; - curr_parent = current->parent; + *current = ap_add_node(curr_parent, *current, newdir, 0); + *current = *curr_parent; + *curr_parent = (*current)->parent; } } else { - current = ap_add_node(&curr_parent, current, newdir, 0); + *current = ap_add_node(curr_parent, *current, newdir, 0); } - newdir = NULL; +} + +API_EXPORT(const char *)ap_walk_config_sub(ap_directive_t *current, cmd_parms *parms, void *config) +{ + void *oldconfig; + const command_rec *cmd; + module *mod = top_module; + const char *retval; oldconfig = parms->context; parms->context = config; do { - if (!(cmd = ap_find_command_in_modules(cmd_name, &mod))) { - errno = EINVAL; - return ap_pstrcat(parms->pool, "Invalid command '", cmd_name, + if (!(cmd = ap_find_command_in_modules(current->directive, &mod))) { + retval = ap_pstrcat(parms->pool, "Invalid command '", + current->directive, "', perhaps mis-spelled or defined by a module " "not included in the server configuration", NULL); } else { void *mconfig = ap_set_config_vectors(parms,config, mod); - retval = invoke_cmd(cmd, parms, mconfig, args); + retval = invoke_cmd(cmd, parms, mconfig, current->args); mod = mod->next; /* Next time around, skip this one */ } } while (retval && !strcmp(retval, DECLINE_CMD)); parms->context = oldconfig; - return retval; + if (retval) { + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + "Syntax error on line %d of %s:", + parms->config_file->line_number, parms->config_file->name); + ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, + "%s", retval); + exit(1); + } } -API_EXPORT(const char *) ap_srm_command_loop(cmd_parms *parms, void *config) +API_EXPORT(const char *)ap_walk_config(ap_directive_t *conftree, cmd_parms *parms, void *config, int container) { + static ap_directive_t *current; + + if (conftree != NULL) { + current = conftree; + } + if (container && current->first_child) { + current = current->first_child; + } + + while (current != NULL) { + /* actually parse the command and execute the correct function */ + ap_walk_config_sub(current, parms, config); + + if (current->next == NULL) { + current = current->parent; + break; + } else { + current = current->next; + continue; + } + } +} + + +API_EXPORT(ap_directive_t *) ap_build_config(cmd_parms *parms, ap_directive_t *current) +{ + ap_directive_t *curr_parent = NULL; + ap_directive_t *cfg_root = NULL; char l[MAX_STRING_LEN]; while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) { - const char *errmsg = ap_handle_command(parms, config, l); - if (errmsg) { - return errmsg; - } + ap_build_config_sub(parms, l, ¤t, &curr_parent); + if (cfg_root == NULL && current != NULL) { + cfg_root = current; + } } - return NULL; + return cfg_root; } /* @@ -1039,8 +1075,8 @@ static void process_command_config(server_rec *s, ap_array_header_t *arr, ap_poo parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives", &arr_parms, NULL, arr_elts_getstr, arr_elts_close); - - errmsg = ap_srm_command_loop(&parms, s->lookup_defaults); +/* + errmsg = ap_build_config(&parms, s->lookup_defaults); if (errmsg) { ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, @@ -1049,13 +1085,14 @@ static void process_command_config(server_rec *s, ap_array_header_t *arr, ap_poo } ap_cfg_closefile(parms.config_file); +*/ } void ap_process_resource_config(server_rec *s, const char *fname, ap_pool_t *p, ap_pool_t *ptemp) { - const char *errmsg; cmd_parms parms; ap_finfo_t finfo; + ap_directive_t *current = NULL; fname = ap_server_root_relative(p, fname); @@ -1081,16 +1118,8 @@ void ap_process_resource_config(server_rec *s, const char *fname, ap_pool_t *p, exit(1); } - errmsg = ap_srm_command_loop(&parms, s->lookup_defaults); - - if (errmsg) { - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "Syntax error on line %d of %s:", - parms.config_file->line_number, parms.config_file->name); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "%s", errmsg); - exit(1); - } + current = ap_build_config(&parms, NULL); + ap_walk_config(current, &parms, s->lookup_defaults, 0); ap_cfg_closefile(parms.config_file); } @@ -1101,12 +1130,13 @@ int ap_parse_htaccess(void **result, request_rec *r, int override, { configfile_t *f = NULL; cmd_parms parms; - const char *errmsg; + const char *errmsg = NULL; char *filename = NULL; const struct htaccess_result *cache; struct htaccess_result *new; void *dc = NULL; ap_status_t status; + ap_directive_t *htaccess_tree = NULL; /* firstly, search cache */ for (cache = r->htaccess; cache != NULL; cache = cache->next) @@ -1136,7 +1166,8 @@ int ap_parse_htaccess(void **result, request_rec *r, int override, parms.config_file = f; - errmsg = ap_srm_command_loop(&parms, dc); + htaccess_tree = ap_build_config(&parms, NULL); + ap_walk_config(htaccess_tree, &parms, dc, 0); ap_cfg_closefile(f); @@ -1147,19 +1178,16 @@ int ap_parse_htaccess(void **result, request_rec *r, int override, } *result = dc; break; - } else { - ap_status_t cerr = ap_canonical_error(status); - - if (cerr != APR_ENOENT && cerr != APR_ENOTDIR) { - ap_log_rerror(APLOG_MARK, APLOG_CRIT, status, r, - "%s pcfg_openfile: unable to check htaccess file, " - "ensure it is readable", - filename); - ap_table_setn(r->notes, "error-notes", - "Server unable to read htaccess file, denying " - "access to be safe"); - return HTTP_FORBIDDEN; - } + } + else if (status != APR_ENOENT && status != APR_ENOTDIR) { + ap_log_rerror(APLOG_MARK, APLOG_CRIT, errno, r, + "%s pcfg_openfile: unable to check htaccess file, " + "ensure it is readable", + filename); + ap_table_setn(r->notes, "error-notes", + "Server unable to read htaccess file, denying " + "access to be safe"); + return HTTP_FORBIDDEN; } } diff --git a/server/util_cfgtree.c b/server/util_cfgtree.c index 30756243ae..2f3fe0fd36 100644 --- a/server/util_cfgtree.c +++ b/server/util_cfgtree.c @@ -60,18 +60,12 @@ #include "util_cfgtree.h" #include -ap_directive_t *conf_tree; - ap_directive_t *ap_add_node(ap_directive_t **parent, ap_directive_t *current, ap_directive_t *toadd, int child) { if (current == NULL) { /* we just started a new parent */ - if (*parent == NULL) { - /* no parent, no current: root of tree */ - conf_tree = toadd; - } - else { + if (*parent != NULL) { (*parent)->first_child = toadd; toadd->parent = *parent; } -- 2.50.1