Return-Path: Delivered-To: apmail-httpd-cvs-archive@www.apache.org Received: (qmail 24591 invoked from network); 20 Jan 2011 19:12:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 20 Jan 2011 19:12:55 -0000 Received: (qmail 48509 invoked by uid 500); 20 Jan 2011 19:12:54 -0000 Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 48319 invoked by uid 500); 20 Jan 2011 19:12:54 -0000 Mailing-List: contact cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 48312 invoked by uid 99); 20 Jan 2011 19:12:53 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 20 Jan 2011 19:12:53 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 20 Jan 2011 19:12:53 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 0540523888CF; Thu, 20 Jan 2011 19:12:33 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1061465 - in /httpd/httpd/trunk: CHANGES STATUS include/httpd.h server/core.c Date: Thu, 20 Jan 2011 19:12:32 -0000 To: cvs@httpd.apache.org From: sf@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110120191233.0540523888CF@eris.apache.org> Author: sf Date: Thu Jan 20 19:12:32 2011 New Revision: 1061465 URL: http://svn.apache.org/viewvc?rev=1061465&view=rev Log: Add support to set variables with the 'Define' directive. Change ap_resolve_env() to look for variables defined in this way. This allows to use the variables in the config using the ${VAR} syntax known from envvar interpolation Modified: httpd/httpd/trunk/CHANGES httpd/httpd/trunk/STATUS httpd/httpd/trunk/include/httpd.h httpd/httpd/trunk/server/core.c Modified: httpd/httpd/trunk/CHANGES URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1061465&r1=1061464&r2=1061465&view=diff ============================================================================== --- httpd/httpd/trunk/CHANGES [utf-8] (original) +++ httpd/httpd/trunk/CHANGES [utf-8] Thu Jan 20 19:12:32 2011 @@ -2,6 +2,10 @@ Changes with Apache 2.3.11 + *) core: Add support to set variables with the 'Define' directive. The + variables that can then be used in the config using the ${VAR} syntax + known from envvar interpolation. [Stefan Fritsch] + *) mod_proxy_http: make adding of X-Forwarded-* headers configurable. ProxyAddHeaders defaults to On. [Vincent Deffontaines] Modified: httpd/httpd/trunk/STATUS URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/STATUS?rev=1061465&r1=1061464&r2=1061465&view=diff ============================================================================== --- httpd/httpd/trunk/STATUS (original) +++ httpd/httpd/trunk/STATUS Thu Jan 20 19:12:32 2011 @@ -133,8 +133,6 @@ RELEASE NON-SHOWSTOPPERS BUT WOULD BE RE * Sort out modules selections for most/all/reallyall. Maybe rename all -> most, reallyall -> all, and remove the old 'most'. - * Add mod_define. - * Patches submitted to the bug database: http://issues.apache.org/bugzilla/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Apache+httpd-2&keywords=PatchAvailable Modified: httpd/httpd/trunk/include/httpd.h URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/httpd.h?rev=1061465&r1=1061464&r2=1061465&view=diff ============================================================================== --- httpd/httpd/trunk/include/httpd.h (original) +++ httpd/httpd/trunk/include/httpd.h Thu Jan 20 19:12:32 2011 @@ -1396,10 +1396,11 @@ AP_DECLARE(char *) ap_getword_conf(apr_p AP_DECLARE(char *) ap_getword_conf_nc(apr_pool_t *p, char **line); /** - * Check a string for any ${ENV} environment variable construct and replace - * each them by the value of that environment variable, if it exists. If the - * environment value does not exist, leave the ${ENV} construct alone; it - * means something else. + * Check a string for any config define or environment variable construct + * and replace each of them by the value of that variable, if it exists. + * The default syntax of the constructs is ${ENV} but can be changed by + * setting the define::* config defines. If the variable does not exist, + * leave the ${ENV} construct alone but print a warning. * @param p The pool to allocate from * @param word The string to check * @return The string with the replaced environment variables Modified: httpd/httpd/trunk/server/core.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=1061465&r1=1061464&r2=1061465&view=diff ============================================================================== --- httpd/httpd/trunk/server/core.c (original) +++ httpd/httpd/trunk/server/core.c Thu Jan 20 19:12:32 2011 @@ -108,6 +108,7 @@ AP_DECLARE_DATA int ap_document_root_che static char errordocument_default; static apr_array_header_t *saved_server_config_defines = NULL; +static apr_table_t *server_config_defined_vars = NULL; static void *create_core_dir_config(apr_pool_t *a, char *dir) { @@ -1087,12 +1088,6 @@ static const char *set_access_name(cmd_p return NULL; } -/* Check a string for any ${ENV} environment variable - * construct and replace each them by the value of - * that environment variable, if it exists. If the - * environment value does not exist, leave the ${ENV} - * construct alone; it means something else. - */ AP_DECLARE(const char *) ap_resolve_env(apr_pool_t *p, const char * word) { # define SMALL_EXPANSION 5 @@ -1134,13 +1129,22 @@ AP_DECLARE(const char *) ap_resolve_env( if (*s == '$') { if (s[1] == '{' && (e = ap_strchr_c(s, '}'))) { - word = getenv(apr_pstrndup(p, s+2, e-s-2)); + char *name = apr_pstrndup(p, s+2, e-s-2); + word = NULL; + if (server_config_defined_vars) + word = apr_table_get(server_config_defined_vars, name); + if (!word) + word = getenv(name); if (word) { current->string = word; current->len = strlen(word); outlen += current->len; } else { + if (ap_strchr(name, ':') == 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, + "Config variable ${%s} is not defined", + name); current->string = s; current->len = e - s + 1; outlen += current->len; @@ -1179,44 +1183,68 @@ AP_DECLARE(const char *) ap_resolve_env( static int reset_config_defines(void *dummy) { ap_server_config_defines = saved_server_config_defines; + server_config_defined_vars = NULL; return OK; } +/* + * Make sure we can revert the effects of Define/UnDefine when restarting. + * This function must be called once per loading of the config, before + * ap_server_config_defines is changed. This may be during reading of the + * config, which is even before the pre_config hook is run (due to + * EXEC_ON_READ for Define/UnDefine). + */ +static void init_config_defines(apr_pool_t *pconf) +{ + saved_server_config_defines = ap_server_config_defines; + /* Use apr_array_copy instead of apr_array_copy_hdr because it does not + * protect from the way unset_define removes entries. + */ + ap_server_config_defines = apr_array_copy(pconf, ap_server_config_defines); +} static const char *set_define(cmd_parms *cmd, void *dummy, - const char *optarg) + const char *name, const char *value) { - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } + if (ap_strchr_c(name, ':') != NULL) + return "Variable name must not contain ':'"; - if (!ap_exists_config_define(optarg)) { + if (!saved_server_config_defines) + init_config_defines(cmd->pool); + if (!ap_exists_config_define(name)) { char **newv = (char **)apr_array_push(ap_server_config_defines); - *newv = apr_pstrdup(cmd->pool, optarg); + *newv = apr_pstrdup(cmd->pool, name); + } + if (value) { + if (!server_config_defined_vars) + server_config_defined_vars = apr_table_make(cmd->pool, 5); + apr_table_setn(server_config_defined_vars, name, value); } return NULL; } static const char *unset_define(cmd_parms *cmd, void *dummy, - const char *optarg) + const char *name) { int i; char **defines; - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } + if (ap_strchr_c(name, ':') != NULL) + return "Variable name must not contain ':'"; + + if (!saved_server_config_defines) + init_config_defines(cmd->pool); defines = (char **)ap_server_config_defines->elts; for (i = 0; i < ap_server_config_defines->nelts; i++) { - if (strcmp(defines[i], optarg) == 0) { + if (strcmp(defines[i], name) == 0) { defines[i] = apr_array_pop(ap_server_config_defines); break; } } + apr_table_unset(server_config_defined_vars, name); + return NULL; } @@ -3601,9 +3629,9 @@ AP_INIT_TAKE1("AddDefaultCharset", set_a "The name of the default charset to add to any Content-Type without one or 'Off' to disable"), AP_INIT_TAKE1("AcceptPathInfo", set_accept_path_info, NULL, OR_FILEINFO, "Set to on or off for PATH_INFO to be accepted by handlers, or default for the per-handler preference"), -AP_INIT_TAKE1("Define", set_define, NULL, RSRC_CONF, - "Define the existence of a variable. Same as passing -D to the command line."), -AP_INIT_TAKE1("UnDefine", unset_define, NULL, RSRC_CONF, +AP_INIT_TAKE12("Define", set_define, NULL, EXEC_ON_READ|ACCESS_CONF|RSRC_CONF, + "Define a variable, optionally to a value. Same as passing -D to the command line."), +AP_INIT_TAKE1("UnDefine", unset_define, NULL, EXEC_ON_READ|ACCESS_CONF|RSRC_CONF, "Undefine the existence of a variable. Undo a Define."), AP_INIT_RAW_ARGS("Error", generate_error, NULL, OR_ALL, "Generate error message from within configuration"), @@ -4097,13 +4125,8 @@ static int core_pre_config(apr_pool_t *p { ap_mutex_init(pconf); - /* - * Make sure we revert the effects of Define/UnDefine when restarting. - * We cannot use apr_array_copy_hdr because it does not protect from the - * way unset_define removes entries. - */ - saved_server_config_defines = ap_server_config_defines; - ap_server_config_defines = apr_array_copy(pconf, ap_server_config_defines); + if (!saved_server_config_defines) + init_config_defines(pconf); apr_pool_cleanup_register(pconf, NULL, reset_config_defines, apr_pool_cleanup_null);