You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by sf...@apache.org on 2011/01/20 20:12:32 UTC

svn commit: r1061465 - in /httpd/httpd/trunk: CHANGES STATUS include/httpd.h server/core.c

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);