]> granicus.if.org Git - apache/commitdiff
nobody came up with another patch or objections and it should not get lost:
authorAndré Malo <nd@apache.org>
Sun, 11 Apr 2004 16:37:43 +0000 (16:37 +0000)
committerAndré Malo <nd@apache.org>
Sun, 11 Apr 2004 16:37:43 +0000 (16:37 +0000)
add mod_version and invoke it into *x (modules = all) and win32 builds

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@103345 13f79535-47bb-0310-9956-ffa450edef68

Apache.dsw
CHANGES
Makefile.win
modules/metadata/config.m4
modules/metadata/mod_version.c [new file with mode: 0644]
modules/metadata/mod_version.dsp [new file with mode: 0644]
modules/metadata/mod_version.exp [new file with mode: 0644]

index 4bd220acdb5f308f2e61759d2a55179446065b15..ab34e4e76a79a7182c4604aea7a2ee440e1ca2fe 100644 (file)
@@ -198,6 +198,9 @@ Package=<4>
     Project_Dep_Name mod_usertrack
     End Project Dependency
     Begin Project Dependency
+    Project_Dep_Name mod_version
+    End Project Dependency
+    Begin Project Dependency
     Project_Dep_Name mod_vhost_alias
     End Project Dependency
     Begin Project Dependency
@@ -1758,6 +1761,27 @@ Package=<4>
 
 ###############################################################################
 
+Project: "mod_version"=".\modules\metadata\mod_version.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name libapr
+    End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name libaprutil
+    End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name libhttpd
+    End Project Dependency
+}}}
+
+###############################################################################
+
 Project: "mod_vhost_alias"=".\modules\mappers\mod_vhost_alias.dsp" - Package Owner=<4>
 
 Package=<5>
diff --git a/CHANGES b/CHANGES
index fdfa32ca95d9921d3a49bb15b6aa7660a061883a..2a473b115ba098353ae28cf3ee7d5efd18653c0f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,9 @@ Changes with Apache 2.1.0-dev
 
   [Remove entries to the current 2.0 section below, when backported]
 
+  *) Added new module mod_version, which provides version dependent
+     configuration containers.  [André Malo]
+
   *) Accept URLs for the ServerAdmin directive. If the supplied
      argument is not recognized as an URL, assume it's a mail address.
      PR 28174.  [André Malo]
index cbcddad57e914dba7d34d4d4f73e0f81f6087434..15c8d41b3c959880bbde9c6ba5c7c0f17670267d 100644 (file)
@@ -284,6 +284,7 @@ _build:
         $(MAKE) $(MAKEOPT) -f mod_setenvif.mak    CFG="mod_setenvif - Win32 $(LONG)" RECURSE=0 $(CTARGET)
         $(MAKE) $(MAKEOPT) -f mod_unique_id.mak   CFG="mod_unique_id - Win32 $(LONG)" RECURSE=0 $(CTARGET)
         $(MAKE) $(MAKEOPT) -f mod_usertrack.mak   CFG="mod_usertrack - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+        $(MAKE) $(MAKEOPT) -f mod_version.mak     CFG="mod_version - Win32 $(LONG)" RECURSE=0 $(CTARGET)
        cd ..\..
        cd modules\proxy
         $(MAKE) $(MAKEOPT) -f mod_proxy.mak       CFG="mod_proxy - Win32 $(LONG)" RECURSE=0 $(CTARGET)
@@ -420,6 +421,7 @@ _copybin:
        copy modules\metadata\$(LONG)\mod_setenvif.$(src_so)    "$(inst_so)" <.y
        copy modules\metadata\$(LONG)\mod_unique_id.$(src_so)   "$(inst_so)" <.y
        copy modules\metadata\$(LONG)\mod_usertrack.$(src_so)   "$(inst_so)" <.y
+       copy modules\metadata\$(LONG)\mod_version.$(src_so)     "$(inst_so)" <.y
        copy modules\proxy\$(LONG)\mod_proxy.$(src_so)          "$(inst_so)" <.y
        copy modules\proxy\$(LONG)\mod_proxy_connect.$(src_so)  "$(inst_so)" <.y
        copy modules\proxy\$(LONG)\mod_proxy_ftp.$(src_so)      "$(inst_so)" <.y
index 4efd4a16830cbd95d895901180fc54f43d687988..c970a717238b78a1b5791e10d07753c2cee16a37 100644 (file)
@@ -18,5 +18,6 @@ APACHE_MODULE(usertrack, user-session tracking, , , , [
 
 APACHE_MODULE(unique_id, per-request unique ids)
 APACHE_MODULE(setenvif, basing ENV vars on headers, , , yes)
+APACHE_MODULE(version, determining httpd version in config files)
 
 APACHE_MODPATH_FINISH
diff --git a/modules/metadata/mod_version.c b/modules/metadata/mod_version.c
new file mode 100644 (file)
index 0000000..e4ade98
--- /dev/null
@@ -0,0 +1,311 @@
+/* Copyright 2004 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+/*
+ * mod_version.c
+ * Allow conditional configuration depending on the httpd version
+ * 
+ * André Malo (nd/perlig.de), January 2004
+ *
+ * Some stuff coded here is heavily based on the core <IfModule>
+ * containers.
+ *
+ * The module makes the following confgurations possible:
+ *
+ * <IfVersion op major.minor.patch>
+ *     # conditional config here ...
+ *</IfVersion>
+ *
+ * where "op" is one of:
+ * = / ==       equal
+ * >            greater than
+ * >=           greater or equal
+ * <            less than
+ * <=           less or equal
+ *
+ * If minor version and patch level are omitted they are assumed to be 0.
+ *
+ * Alternatively you can match the whole version (including some vendor-added
+ * string of the CORE version, see ap_release.h) against a regular expression:
+ *
+ * <IfVersion op regex>
+ *     # conditional config here ...
+ *</IfVersion>
+ *
+ * where "op" is one of:
+ * = / ==       match; regex must be surrounded by slashes
+ * ~            match; regex MAY NOT be surrounded by slashes
+ *
+ * Note that all operators may be preceeded by an exclamation mark
+ * (without spaces) in order to reverse their meaning.
+ *
+ */
+
+#include "apr.h"
+#include "apr_strings.h"
+#include "apr_lib.h"
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_log.h"
+
+
+/* module structure */
+module AP_MODULE_DECLARE_DATA version_module;
+
+/* queried httpd version */
+static ap_version_t httpd_version;
+
+
+/*
+ * compare the supplied version with the core one
+ */
+static int compare_version(char *version_string, const char **error)
+{
+    char *p = version_string, *ep;
+    int version[3] = {0, 0, 0};
+    int c = 0;
+
+    *error = "Version appears to be invalid. It must have the format "
+             "major[.minor[.patch]] where major, minor and patch are "
+             "numbers.";
+
+    if (!apr_isdigit(*p)) {
+        return 0;
+    }
+
+    /* parse supplied version */
+    ep = version_string + strlen(version_string);
+    while (p <= ep && c < 3) {
+        if (*p == '.') {
+            *p = '\0';
+        }
+
+        if (!*p) {
+            version[c++] = atoi(version_string);
+            version_string = ++p;
+            continue;
+        }
+
+        if (!apr_isdigit(*p)) {
+            break;
+        }
+
+        ++p;
+    }
+
+    if (p < ep) { /* syntax error */
+        return 0;
+    }
+
+    *error = NULL;
+
+    if      (httpd_version.major > version[0]) {
+        return 1;
+    }
+    else if (httpd_version.major < version[0]) {
+        return -1;
+    }
+    else if (httpd_version.minor > version[1]) {
+        return 1;
+    }
+    else if (httpd_version.minor < version[1]) {
+        return -1;
+    }
+    else if (httpd_version.patch > version[2]) {
+        return 1;
+    }
+    else if (httpd_version.patch < version[2]) {
+        return -1;
+    }
+
+    /* seems to be the same */
+    return 0;
+}
+
+/*
+ * match version against a regular expression
+ */
+static int match_version(apr_pool_t *pool, char *version_string,
+                         const char **error)
+{
+    regex_t *compiled;
+    const char *to_match;
+    int rc;
+
+    compiled = ap_pregcomp(pool, version_string, REG_EXTENDED);
+    if (!compiled) {
+        *error = "Unable to compile regular expression";
+        return 0;
+    }
+
+    *error = NULL;
+
+    to_match = apr_psprintf(pool, "%d.%d.%d%s",
+                            httpd_version.major,
+                            httpd_version.minor,
+                            httpd_version.patch,
+                            httpd_version.add_string);
+
+    rc = !ap_regexec(compiled, to_match, 0, NULL, 0);
+
+    ap_pregfree(pool, compiled);
+    return rc;    
+}
+
+/*
+ * Implements the <IfVersion> container
+ */
+static const char *start_ifversion(cmd_parms *cmd, void *mconfig,
+                                   const char *arg1, const char *arg2,
+                                   const char *arg3)
+{
+    const char *endp;
+    int reverse = 0, done = 0, match = 0, compare;
+    const char *p, *error;
+    char c;
+
+    /* supplying one argument is possible, we assume an equality check then */
+    if (!arg2) {
+        arg2 = arg1;
+        arg1 = "=";
+    }
+
+    /* surrounding quotes without operator */
+    if (!arg3 && *arg2 == '>' && !arg2[1]) {
+        arg3 = ">";
+        arg2 = arg1;
+        arg1 = "=";
+    }
+
+    /* the third argument makes version surrounding quotes plus operator
+     * possible.
+     */
+    endp = arg2 + strlen(arg2);
+    if (   endp == arg2
+        || (!(arg3 && *arg3 == '>' && !arg3[1]) && *--endp != '>')) {
+        return apr_pstrcat(cmd->pool, cmd->cmd->name,
+                           "> directive missing closing '>'", NULL);
+    }
+
+    p = arg1;
+    if (*p == '!') {
+        reverse = 1;
+        if (p[1]) {
+            ++p;
+        }
+    }
+
+    c = *p++;
+    if (!*p || (*p == '=' && !p[1] && c != '~')) {
+        if (!httpd_version.major) {
+            ap_get_server_revision(&httpd_version);
+        }
+
+        done = 1;
+        switch (c) {
+        case '=':
+            /* normal comparison */
+            if (*arg2 != '/') {
+                compare = compare_version(apr_pstrmemdup(cmd->pool, arg2,
+                                                         endp-arg2),
+                                          &error);
+                if (error) {
+                    return error;
+                }
+
+                match = !compare;
+                break;
+            }
+
+            /* regexp otherwise */
+            if (endp == ++arg2 || *--endp != '/') {
+                return "Missing delimiting / of regular expression.";
+            }
+
+        case '~':
+            /* regular expression */
+            match = match_version(cmd->pool, apr_pstrmemdup(cmd->pool, arg2,
+                                                            endp-arg2),
+                                  &error);
+            if (error) {
+                return error;
+            }
+            break;
+
+        case '<':
+            compare = compare_version(apr_pstrmemdup(cmd->pool, arg2,
+                                                     endp-arg2),
+                                      &error);
+            if (error) {
+                return error;
+            }
+
+            match = ((-1 == compare) || (*p && !compare));
+            break;
+
+        case '>':
+            compare = compare_version(apr_pstrmemdup(cmd->pool, arg2,
+                                                     endp-arg2),
+                                      &error);
+            if (error) {
+                return error;
+            }
+
+            match = ((1 == compare) || (*p && !compare));
+            break;
+
+        default:
+            done = 0;
+            break;
+        }
+    }
+
+    if (!done) {
+        return apr_pstrcat(cmd->pool, "unrecognized operator '", arg1, "'",
+                           NULL);
+    }
+
+    if ((!reverse && match) || (reverse && !match)) {
+        ap_directive_t *parent = NULL;
+        ap_directive_t *current = NULL;
+        const char *retval;
+
+        retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd,
+                                      &current, &parent, "<IfVersion");
+        *(ap_directive_t **)mconfig = current;
+        return retval;
+    }
+
+    *(ap_directive_t **)mconfig = NULL;
+    return ap_soak_end_container(cmd, "<IfVersion");
+}
+
+static const command_rec version_cmds[] = {
+    AP_INIT_TAKE123("<IfVersion", start_ifversion, NULL, EXEC_ON_READ | OR_ALL,
+                    "a comparison operator, a version (and a delimiter)"),
+    { NULL }
+};
+
+module AP_MODULE_DECLARE_DATA version_module =
+{
+    STANDARD20_MODULE_STUFF,
+    NULL,             /* dir config creater */
+    NULL,             /* dir merger --- default is to override */
+    NULL,             /* server config */
+    NULL,             /* merge server configs */
+    version_cmds,     /* command apr_table_t */
+    NULL,             /* register hooks */
+};
diff --git a/modules/metadata/mod_version.dsp b/modules/metadata/mod_version.dsp
new file mode 100644 (file)
index 0000000..9b4a9bb
--- /dev/null
@@ -0,0 +1,128 @@
+# Microsoft Developer Studio Project File - Name="mod_version" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_version - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "mod_version.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "mod_version.mak" CFG="mod_version - Win32 Release"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "mod_version - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_version - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "mod_version - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_version_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so /opt:ref
+
+!ELSEIF  "$(CFG)" == "mod_version - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_version_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so
+
+!ENDIF 
+
+# Begin Target
+
+# Name "mod_version - Win32 Release"
+# Name "mod_version - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_version.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mod_version.rc
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\win32ver.awk
+
+!IF  "$(CFG)" == "mod_version - Win32 Release"
+
+# PROP Ignore_Default_Tool 1
+# Begin Custom Build - Creating Version Resource
+InputPath=..\..\build\win32\win32ver.awk
+
+".\mod_version.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+       awk -f ../../build/win32/win32ver.awk mod_version.so "version_module for Apache" ../../include/ap_release.h  > .\mod_version.rc
+
+# End Custom Build
+
+!ELSEIF  "$(CFG)" == "mod_version - Win32 Debug"
+
+# PROP Ignore_Default_Tool 1
+# Begin Custom Build - Creating Version Resource
+InputPath=..\..\build\win32\win32ver.awk
+
+".\mod_version.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+       awk -f ../../build/win32/win32ver.awk mod_version.so "version_module for Apache" ../../include/ap_release.h  > .\mod_version.rc
+
+# End Custom Build
+
+!ENDIF 
+
+# End Source File
+# End Target
+# End Project
diff --git a/modules/metadata/mod_version.exp b/modules/metadata/mod_version.exp
new file mode 100644 (file)
index 0000000..3dce845
--- /dev/null
@@ -0,0 +1 @@
+version_module