/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
*
* 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.
*/
/*
* Allow conditional configuration depending on the httpd version
*
*
* 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 */
/* queried httpd version */
/*
* compare the supplied version with the core one
*/
{
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 */
while (p <= ep && c < 3) {
if (*p == '.') {
*p = '\0';
}
if (!*p) {
version_string = ++p;
continue;
}
if (!apr_isdigit(*p)) {
break;
}
++p;
}
if (p < ep) { /* syntax error */
return 0;
}
return 1;
}
return -1;
}
return 1;
}
return -1;
}
return 1;
}
return -1;
}
/* seems to be the same */
return 0;
}
/*
* match version against a regular expression
*/
const char **error)
{
const char *to_match;
int rc;
if (!compiled) {
*error = "Unable to compile regular expression";
return 0;
}
return rc;
}
/*
* Implements the <IfVersion> container
*/
const char *arg3)
{
const char *endp;
const char *p, *error;
char c;
/* supplying one argument is possible, we assume an equality check then */
if (!arg2) {
arg1 = "=";
}
/* surrounding quotes without operator */
arg3 = ">";
arg1 = "=";
}
/* the third argument makes version surrounding quotes plus operator
* possible.
*/
"> 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) {
}
done = 1;
switch (c) {
case '=':
/* normal comparison */
if (*arg2 != '/') {
&error);
if (error) {
return error;
}
break;
}
/* regexp otherwise */
return "Missing delimiting / of regular expression.";
}
case '~':
/* regular expression */
&error);
if (error) {
return error;
}
break;
case '<':
&error);
if (error) {
return error;
}
break;
case '>':
&error);
if (error) {
return error;
}
break;
default:
done = 0;
break;
}
}
if (!done) {
NULL);
}
const char *retval;
return retval;
}
}
"a comparison operator, a version (and a delimiter)"),
{ NULL }
};
{
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 */
};