summaryrefslogtreecommitdiffstats
path: root/modules/mappers
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-25 04:41:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-25 04:41:28 +0000
commitb1a1c1d95059e2fefd7b5671eb110ab690409a84 (patch)
tree97ecfcc9425e2d09d2cd669594d626a616f324a3 /modules/mappers
parentReleasing progress-linux version 2.4.38-3+deb10u10progress5u1. (diff)
downloadapache2-b1a1c1d95059e2fefd7b5671eb110ab690409a84.tar.xz
apache2-b1a1c1d95059e2fefd7b5671eb110ab690409a84.zip
Merging upstream version 2.4.59.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'modules/mappers')
-rw-r--r--modules/mappers/config9.m45
-rw-r--r--modules/mappers/mod_alias.c186
-rw-r--r--modules/mappers/mod_imagemap.c2
-rw-r--r--modules/mappers/mod_negotiation.c10
-rw-r--r--modules/mappers/mod_rewrite.c288
-rw-r--r--modules/mappers/mod_rewrite.mak4
-rw-r--r--modules/mappers/mod_speling.c37
-rw-r--r--modules/mappers/mod_vhost_alias.c2
8 files changed, 340 insertions, 194 deletions
diff --git a/modules/mappers/config9.m4 b/modules/mappers/config9.m4
index 55a97ab..7120b72 100644
--- a/modules/mappers/config9.m4
+++ b/modules/mappers/config9.m4
@@ -14,6 +14,11 @@ APACHE_MODULE(userdir, mapping of requests to user-specific directories, , , mos
APACHE_MODULE(alias, mapping of requests to different filesystem parts, , , yes)
APACHE_MODULE(rewrite, rule based URL manipulation, , , most)
+if test "x$enable_rewrite" != "xno"; then
+ # mod_rewrite needs test_char.h
+ APR_ADDTO(INCLUDES, [-I\$(top_builddir)/server])
+fi
+
APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
APACHE_MODPATH_FINISH
diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c
index 79d58d8..35eca74 100644
--- a/modules/mappers/mod_alias.c
+++ b/modules/mappers/mod_alias.c
@@ -37,6 +37,12 @@
#include "ap_expr.h"
+#define ALIAS_FLAG_DEFAULT -1
+#define ALIAS_FLAG_OFF 0
+#define ALIAS_FLAG_ON 1
+
+#define ALIAS_PRESERVE_PATH_DEFAULT 0
+
typedef struct {
const char *real;
const char *fake;
@@ -55,9 +61,12 @@ typedef struct {
unsigned int redirect_set:1;
apr_array_header_t *redirects;
const ap_expr_info_t *alias;
+ const char *alias_fake;
char *handler;
const ap_expr_info_t *redirect;
int redirect_status; /* 301, 302, 303, 410, etc */
+ int allow_relative; /* skip ap_construct_url() */
+ int alias_preserve_path; /* map full path */
} alias_dir_conf;
module AP_MODULE_DECLARE_DATA alias_module;
@@ -80,6 +89,8 @@ static void *create_alias_dir_config(apr_pool_t *p, char *d)
alias_dir_conf *a =
(alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf));
a->redirects = apr_array_make(p, 2, sizeof(alias_entry));
+ a->allow_relative = ALIAS_FLAG_DEFAULT;
+ a->alias_preserve_path = ALIAS_FLAG_DEFAULT;
return a;
}
@@ -105,12 +116,19 @@ static void *merge_alias_dir_config(apr_pool_t *p, void *basev, void *overridesv
a->redirects = apr_array_append(p, overrides->redirects, base->redirects);
a->alias = (overrides->alias_set == 0) ? base->alias : overrides->alias;
+ a->alias_fake = (overrides->alias_set == 0) ? base->alias_fake : overrides->alias_fake;
a->handler = (overrides->alias_set == 0) ? base->handler : overrides->handler;
a->alias_set = overrides->alias_set || base->alias_set;
a->redirect = (overrides->redirect_set == 0) ? base->redirect : overrides->redirect;
a->redirect_status = (overrides->redirect_set == 0) ? base->redirect_status : overrides->redirect_status;
a->redirect_set = overrides->redirect_set || base->redirect_set;
+ a->allow_relative = (overrides->allow_relative != ALIAS_FLAG_DEFAULT)
+ ? overrides->allow_relative
+ : base->allow_relative;
+ a->alias_preserve_path = (overrides->alias_preserve_path != ALIAS_FLAG_DEFAULT)
+ ? overrides->alias_preserve_path
+ : base->alias_preserve_path;
return a;
}
@@ -210,6 +228,7 @@ static const char *add_alias(cmd_parms *cmd, void *dummy, const char *fake,
NULL);
}
+ dirconf->alias_fake = cmd->path;
dirconf->handler = cmd->info;
dirconf->alias_set = 1;
@@ -373,33 +392,6 @@ static const char *add_redirect_regex(cmd_parms *cmd, void *dirconf,
return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 1);
}
-static const command_rec alias_cmds[] =
-{
- AP_INIT_TAKE12("Alias", add_alias, NULL, RSRC_CONF | ACCESS_CONF,
- "a fakename and a realname, or a realname in a Location"),
- AP_INIT_TAKE12("ScriptAlias", add_alias, "cgi-script", RSRC_CONF | ACCESS_CONF,
- "a fakename and a realname, or a realname in a Location"),
- AP_INIT_TAKE123("Redirect", add_redirect, (void *) HTTP_MOVED_TEMPORARILY,
- OR_FILEINFO,
- "an optional status, then document to be redirected and "
- "destination URL"),
- AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF,
- "a regular expression and a filename"),
- AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF,
- "a regular expression and a filename"),
- AP_INIT_TAKE23("RedirectMatch", add_redirect_regex,
- (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
- "an optional status, then a regular expression and "
- "destination URL"),
- AP_INIT_TAKE2("RedirectTemp", add_redirect2,
- (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
- "a document to be redirected, then the destination URL"),
- AP_INIT_TAKE2("RedirectPermanent", add_redirect2,
- (void *) HTTP_MOVED_PERMANENTLY, OR_FILEINFO,
- "a document to be redirected, then the destination URL"),
- {NULL}
-};
-
static int alias_matches(const char *uri, const char *alias_fakename)
{
const char *aliasp = alias_fakename, *urip = uri;
@@ -455,6 +447,17 @@ static char *try_alias(request_rec *r)
return PREGSUB_ERROR;
}
+ if (dirconf->alias_fake && dirconf->alias_preserve_path == ALIAS_FLAG_ON) {
+ int l;
+
+ l = alias_matches(r->uri, dirconf->alias_fake);
+
+ if (l > 0) {
+ ap_set_context_info(r, dirconf->alias_fake, found);
+ found = apr_pstrcat(r->pool, found, r->uri + l, NULL);
+ }
+ }
+
if (dirconf->handler) { /* Set handler, and leave a note for mod_cgi */
r->handler = dirconf->handler;
apr_table_setn(r->notes, "alias-forced-type", r->handler);
@@ -618,31 +621,33 @@ static int translate_alias_redir(request_rec *r)
if (ret == PREGSUB_ERROR)
return HTTP_INTERNAL_SERVER_ERROR;
if (ap_is_HTTP_REDIRECT(status)) {
- if (ret[0] == '/') {
- char *orig_target = ret;
-
- ret = ap_construct_url(r->pool, ret, r);
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00673)
- "incomplete redirection target of '%s' for "
- "URI '%s' modified to '%s'",
- orig_target, r->uri, ret);
- }
- if (!ap_is_url(ret)) {
- status = HTTP_INTERNAL_SERVER_ERROR;
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00674)
- "cannot redirect '%s' to '%s'; "
- "target is not a valid absoluteURI or abs_path",
- r->uri, ret);
- }
- else {
- /* append requested query only, if the config didn't
- * supply its own.
- */
- if (r->args && !ap_strchr(ret, '?')) {
- ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
+ alias_dir_conf *dirconf = (alias_dir_conf *)
+ ap_get_module_config(r->per_dir_config, &alias_module);
+ if (dirconf->allow_relative != ALIAS_FLAG_ON || ret[0] != '/') {
+ if (ret[0] == '/') {
+ char *orig_target = ret;
+
+ ret = ap_construct_url(r->pool, ret, r);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00673)
+ "incomplete redirection target of '%s' for "
+ "URI '%s' modified to '%s'",
+ orig_target, r->uri, ret);
}
- apr_table_setn(r->headers_out, "Location", ret);
+ if (!ap_is_url(ret)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00674)
+ "cannot redirect '%s' to '%s'; "
+ "target is not a valid absoluteURI or abs_path",
+ r->uri, ret);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+ /* append requested query only, if the config didn't
+ * supply its own.
+ */
+ if (r->args && !ap_strchr(ret, '?')) {
+ ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
}
+ apr_table_setn(r->headers_out, "Location", ret);
}
return status;
}
@@ -673,31 +678,31 @@ static int fixup_redir(request_rec *r)
if (ret == PREGSUB_ERROR)
return HTTP_INTERNAL_SERVER_ERROR;
if (ap_is_HTTP_REDIRECT(status)) {
- if (ret[0] == '/') {
- char *orig_target = ret;
-
- ret = ap_construct_url(r->pool, ret, r);
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00675)
- "incomplete redirection target of '%s' for "
- "URI '%s' modified to '%s'",
- orig_target, r->uri, ret);
- }
- if (!ap_is_url(ret)) {
- status = HTTP_INTERNAL_SERVER_ERROR;
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00676)
- "cannot redirect '%s' to '%s'; "
- "target is not a valid absoluteURI or abs_path",
- r->uri, ret);
- }
- else {
- /* append requested query only, if the config didn't
- * supply its own.
- */
- if (r->args && !ap_strchr(ret, '?')) {
- ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
+ if (dirconf->allow_relative != ALIAS_FLAG_ON || ret[0] != '/') {
+ if (ret[0] == '/') {
+ char *orig_target = ret;
+
+ ret = ap_construct_url(r->pool, ret, r);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00675)
+ "incomplete redirection target of '%s' for "
+ "URI '%s' modified to '%s'",
+ orig_target, r->uri, ret);
}
- apr_table_setn(r->headers_out, "Location", ret);
+ if (!ap_is_url(ret)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00676)
+ "cannot redirect '%s' to '%s'; "
+ "target is not a valid absoluteURI or abs_path",
+ r->uri, ret);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+ /* append requested query only, if the config didn't
+ * supply its own.
+ */
+ if (r->args && !ap_strchr(ret, '?')) {
+ ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL);
}
+ apr_table_setn(r->headers_out, "Location", ret);
}
return status;
}
@@ -705,6 +710,41 @@ static int fixup_redir(request_rec *r)
return DECLINED;
}
+static const command_rec alias_cmds[] =
+{
+ AP_INIT_TAKE12("Alias", add_alias, NULL, RSRC_CONF | ACCESS_CONF,
+ "a fakename and a realname, or a realname in a Location"),
+ AP_INIT_TAKE12("ScriptAlias", add_alias, "cgi-script", RSRC_CONF | ACCESS_CONF,
+ "a fakename and a realname, or a realname in a Location"),
+ AP_INIT_TAKE123("Redirect", add_redirect, (void *) HTTP_MOVED_TEMPORARILY,
+ OR_FILEINFO,
+ "an optional status, then document to be redirected and "
+ "destination URL"),
+ AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF,
+ "a regular expression and a filename"),
+ AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF,
+ "a regular expression and a filename"),
+ AP_INIT_TAKE23("RedirectMatch", add_redirect_regex,
+ (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
+ "an optional status, then a regular expression and "
+ "destination URL"),
+ AP_INIT_TAKE2("RedirectTemp", add_redirect2,
+ (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO,
+ "a document to be redirected, then the destination URL"),
+ AP_INIT_TAKE2("RedirectPermanent", add_redirect2,
+ (void *) HTTP_MOVED_PERMANENTLY, OR_FILEINFO,
+ "a document to be redirected, then the destination URL"),
+ AP_INIT_FLAG("RedirectRelative", ap_set_flag_slot,
+ (void*)APR_OFFSETOF(alias_dir_conf, allow_relative), OR_FILEINFO,
+ "Set to ON to allow relative redirect targets to be issued as-is"),
+ AP_INIT_FLAG("AliasPreservePath", ap_set_flag_slot,
+ (void*)APR_OFFSETOF(alias_dir_conf, alias_preserve_path), OR_FILEINFO,
+ "Set to ON to map the full path after the fakename to the realname."),
+
+ {NULL}
+};
+
+
static void register_hooks(apr_pool_t *p)
{
static const char * const aszSucc[]={ "mod_userdir.c",
diff --git a/modules/mappers/mod_imagemap.c b/modules/mappers/mod_imagemap.c
index 187a500..206c0b6 100644
--- a/modules/mappers/mod_imagemap.c
+++ b/modules/mappers/mod_imagemap.c
@@ -319,7 +319,7 @@ static void read_quoted(char **string, char **quoted_part)
static const char *imap_url(request_rec *r, const char *base, const char *value)
{
/* translates a value into a URL. */
- int slen, clen;
+ apr_size_t slen, clen;
char *string_pos = NULL;
const char *string_pos_const = NULL;
char *directory = NULL;
diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c
index b6dfedc..c056b28 100644
--- a/modules/mappers/mod_negotiation.c
+++ b/modules/mappers/mod_negotiation.c
@@ -774,7 +774,7 @@ static enum header_state get_header_line(char *buffer, int len, apr_file_t *map)
/* We need to shortcut the rest of this block following the Body:
* tag - we will not look for continutation after this line.
*/
- if (!strncasecmp(buffer, "Body:", 5))
+ if (!ap_cstr_casecmpn(buffer, "Body:", 5))
return header_seen;
while (apr_file_getc(&c, map) != APR_EOF) {
@@ -988,19 +988,17 @@ static int read_type_map(apr_file_t **map, negotiation_state *neg,
has_content = 1;
}
else if (!strncmp(buffer, "content-length:", 15)) {
- char *errp;
- apr_off_t number;
+ apr_off_t clen;
body1 = ap_get_token(neg->pool, &body, 0);
- if (apr_strtoff(&number, body1, &errp, 10) != APR_SUCCESS
- || *errp || number < 0) {
+ if (!ap_parse_strict_length(&clen, body1)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00684)
"Parse error in type map, Content-Length: "
"'%s' in %s is invalid.",
body1, r->filename);
break;
}
- mime_info.bytes = number;
+ mime_info.bytes = clen;
has_content = 1;
}
else if (!strncmp(buffer, "content-language:", 17)) {
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 68a33b6..bbcc11b 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -55,6 +55,12 @@
#include "apr_global_mutex.h"
#include "apr_dbm.h"
#include "apr_dbd.h"
+
+#include "apr_version.h"
+#if !APR_VERSION_AT_LEAST(2,0,0)
+#include "apu_version.h"
+#endif
+
#include "mod_dbd.h"
#if APR_HAS_THREADS
@@ -93,14 +99,15 @@
#include "http_core.h"
#include "http_log.h"
#include "http_protocol.h"
+#include "http_ssl.h"
#include "http_vhost.h"
#include "util_mutex.h"
-#include "mod_ssl.h"
-
#include "mod_rewrite.h"
#include "ap_expr.h"
+#include "test_char.h"
+
static ap_dbd_t *(*dbd_acquire)(request_rec*) = NULL;
static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
static const char* really_last_key = "rewrite_really_last";
@@ -168,6 +175,8 @@ static const char* really_last_key = "rewrite_really_last";
#define RULEFLAG_END (1<<17)
#define RULEFLAG_ESCAPENOPLUS (1<<18)
#define RULEFLAG_QSLAST (1<<19)
+#define RULEFLAG_QSNONE (1<<20) /* programattic only */
+#define RULEFLAG_ESCAPECTLS (1<<21)
/* return code of the rewrite rule
* the result may be escaped - or not
@@ -321,7 +330,8 @@ typedef struct {
data_item *cookie; /* added cookies */
int skip; /* number of next rules to skip */
int maxrounds; /* limit on number of loops with N flag */
- char *escapes; /* specific backref escapes */
+ const char *escapes; /* specific backref escapes */
+ const char *noescapes; /* specific backref chars not to escape */
} rewriterule_entry;
typedef struct {
@@ -421,9 +431,9 @@ static apr_global_mutex_t *rewrite_mapr_lock_acquire = NULL;
static const char *rewritemap_mutex_type = "rewrite-map";
/* Optional functions imported from mod_ssl when loaded: */
-static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *rewrite_ssl_lookup = NULL;
-static APR_OPTIONAL_FN_TYPE(ssl_is_https) *rewrite_is_https = NULL;
-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int noplus);
+static char *escape_backref(apr_pool_t *p, const char *path,
+ const char *escapeme, const char *noescapeme,
+ int flags);
/*
* +-------------------------------------------------------+
@@ -524,7 +534,7 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs)
switch (*uri++) {
case 'a':
case 'A':
- if (!strncasecmp(uri, "jp://", 5)) { /* ajp:// */
+ if (!ap_cstr_casecmpn(uri, "jp://", 5)) { /* ajp:// */
*sqs = 1;
return 6;
}
@@ -532,7 +542,7 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs)
case 'b':
case 'B':
- if (!strncasecmp(uri, "alancer://", 10)) { /* balancer:// */
+ if (!ap_cstr_casecmpn(uri, "alancer://", 10)) { /* balancer:// */
*sqs = 1;
return 11;
}
@@ -540,10 +550,10 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs)
case 'f':
case 'F':
- if (!strncasecmp(uri, "tp://", 5)) { /* ftp:// */
+ if (!ap_cstr_casecmpn(uri, "tp://", 5)) { /* ftp:// */
return 6;
}
- if (!strncasecmp(uri, "cgi://", 6)) { /* fcgi:// */
+ if (!ap_cstr_casecmpn(uri, "cgi://", 6)) { /* fcgi:// */
*sqs = 1;
return 7;
}
@@ -551,26 +561,26 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs)
case 'g':
case 'G':
- if (!strncasecmp(uri, "opher://", 8)) { /* gopher:// */
+ if (!ap_cstr_casecmpn(uri, "opher://", 8)) { /* gopher:// */
return 9;
}
break;
case 'h':
case 'H':
- if (!strncasecmp(uri, "ttp://", 6)) { /* http:// */
+ if (!ap_cstr_casecmpn(uri, "ttp://", 6)) { /* http:// */
*sqs = 1;
return 7;
}
- else if (!strncasecmp(uri, "ttps://", 7)) { /* https:// */
+ else if (!ap_cstr_casecmpn(uri, "ttps://", 7)) { /* https:// */
*sqs = 1;
return 8;
}
- else if (!strncasecmp(uri, "2://", 4)) { /* h2:// */
+ else if (!ap_cstr_casecmpn(uri, "2://", 4)) { /* h2:// */
*sqs = 1;
return 5;
}
- else if (!strncasecmp(uri, "2c://", 5)) { /* h2c:// */
+ else if (!ap_cstr_casecmpn(uri, "2c://", 5)) { /* h2c:// */
*sqs = 1;
return 6;
}
@@ -578,14 +588,14 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs)
case 'l':
case 'L':
- if (!strncasecmp(uri, "dap://", 6)) { /* ldap:// */
+ if (!ap_cstr_casecmpn(uri, "dap://", 6)) { /* ldap:// */
return 7;
}
break;
case 'm':
case 'M':
- if (!strncasecmp(uri, "ailto:", 6)) { /* mailto: */
+ if (!ap_cstr_casecmpn(uri, "ailto:", 6)) { /* mailto: */
*sqs = 1;
return 7;
}
@@ -593,17 +603,17 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs)
case 'n':
case 'N':
- if (!strncasecmp(uri, "ews:", 4)) { /* news: */
+ if (!ap_cstr_casecmpn(uri, "ews:", 4)) { /* news: */
return 5;
}
- else if (!strncasecmp(uri, "ntp://", 6)) { /* nntp:// */
+ else if (!ap_cstr_casecmpn(uri, "ntp://", 6)) { /* nntp:// */
return 7;
}
break;
case 's':
case 'S':
- if (!strncasecmp(uri, "cgi://", 6)) { /* scgi:// */
+ if (!ap_cstr_casecmpn(uri, "cgi://", 6)) { /* scgi:// */
*sqs = 1;
return 7;
}
@@ -611,15 +621,22 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs)
case 'w':
case 'W':
- if (!strncasecmp(uri, "s://", 4)) { /* ws:// */
+ if (!ap_cstr_casecmpn(uri, "s://", 4)) { /* ws:// */
*sqs = 1;
return 5;
}
- else if (!strncasecmp(uri, "ss://", 5)) { /* wss:// */
+ else if (!ap_cstr_casecmpn(uri, "ss://", 5)) { /* wss:// */
*sqs = 1;
return 6;
}
break;
+
+ case 'u':
+ case 'U':
+ if (!ap_cstr_casecmpn(uri, "nix:", 4)) { /* unix: */
+ *sqs = 1;
+ return (uri[4] == '/' && uri[5] == '/') ? 7 : 5;
+ }
}
return 0;
@@ -643,14 +660,21 @@ static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix,
* Escapes a backreference in a similar way as php's urlencode does.
* Based on ap_os_escape_path in server/util.c
*/
-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int noplus) {
- char *copy = apr_palloc(p, 3 * strlen(path) + 3);
+static char *escape_backref(apr_pool_t *p, const char *path,
+ const char *escapeme, const char *noescapeme,
+ int flags)
+{
+ char *copy = apr_palloc(p, 3 * strlen(path) + 1);
const unsigned char *s = (const unsigned char *)path;
unsigned char *d = (unsigned char *)copy;
- unsigned c;
+ int noplus = (flags & RULEFLAG_ESCAPENOPLUS) != 0;
+ int ctls = (flags & RULEFLAG_ESCAPECTLS) != 0;
+ unsigned char c;
while ((c = *s)) {
- if (!escapeme) {
+ if (((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
+ || (escapeme && ap_strchr_c(escapeme, c)))
+ && (!noescapeme || !ap_strchr_c(noescapeme, c))) {
if (apr_isalnum(c) || c == '_') {
*d++ = c;
}
@@ -661,23 +685,8 @@ static char *escape_backref(apr_pool_t *p, const char *path, const char *escapem
d = c2x(c, '%', d);
}
}
- else {
- const char *esc = escapeme;
- while (*esc) {
- if (c == *esc) {
- if (c == ' ' && !noplus) {
- *d++ = '+';
- }
- else {
- d = c2x(c, '%', d);
- }
- break;
- }
- ++esc;
- }
- if (!*esc) {
- *d++ = c;
- }
+ else {
+ *d++ = c;
}
++s;
}
@@ -723,7 +732,7 @@ static char *escape_absolute_uri(apr_pool_t *p, char *uri, unsigned scheme)
* [dn ["?" [attributes] ["?" [scope]
* ["?" [filter] ["?" extensions]]]]]]
*/
- if (!strncasecmp(uri, "ldap", 4)) {
+ if (!ap_cstr_casecmpn(uri, "ldap", 4)) {
char *token[5];
int c = 0;
@@ -759,27 +768,35 @@ static char *escape_absolute_uri(apr_pool_t *p, char *uri, unsigned scheme)
* split out a QUERY_STRING part from
* the current URI string
*/
-static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard,
- int qslast)
+static void splitout_queryargs(request_rec *r, int flags)
{
char *q;
- int split;
+ int split, skip;
+ int qsappend = flags & RULEFLAG_QSAPPEND;
+ int qsdiscard = flags & RULEFLAG_QSDISCARD;
+ int qslast = flags & RULEFLAG_QSLAST;
+
+ if (flags & RULEFLAG_QSNONE) {
+ rewritelog((r, 2, NULL, "discarding query string, no parse from substitution"));
+ r->args = NULL;
+ return;
+ }
/* don't touch, unless it's a scheme for which a query string makes sense.
* See RFC 1738 and RFC 2368.
*/
- if (is_absolute_uri(r->filename, &split)
+ if ((skip = is_absolute_uri(r->filename, &split))
&& !split) {
r->args = NULL; /* forget the query that's still flying around */
return;
}
- if ( qsdiscard ) {
+ if (qsdiscard) {
r->args = NULL; /* Discard query string */
rewritelog((r, 2, NULL, "discarding query string"));
}
- q = qslast ? ap_strrchr(r->filename, '?') : ap_strchr(r->filename, '?');
+ q = qslast ? ap_strrchr(r->filename + skip, '?') : ap_strchr(r->filename + skip, '?');
if (q != NULL) {
char *olduri;
@@ -788,7 +805,7 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard,
olduri = apr_pstrdup(r->pool, r->filename);
*q++ = '\0';
if (qsappend) {
- if (*q) {
+ if (*q) {
r->args = apr_pstrcat(r->pool, q, "&" , r->args, NULL);
}
}
@@ -796,9 +813,9 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard,
r->args = apr_pstrdup(r->pool, q);
}
- if (r->args) {
+ if (r->args) {
len = strlen(r->args);
-
+
if (!len) {
r->args = NULL;
}
@@ -810,8 +827,6 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard,
rewritelog((r, 3, NULL, "split uri=%s -> uri=%s, args=%s", olduri,
r->filename, r->args ? r->args : "<none>"));
}
-
- return;
}
/*
@@ -825,7 +840,7 @@ static void reduce_uri(request_rec *r)
cp = (char *)ap_http_scheme(r);
l = strlen(cp);
if ( strlen(r->filename) > l+3
- && strncasecmp(r->filename, cp, l) == 0
+ && ap_cstr_casecmpn(r->filename, cp, l) == 0
&& r->filename[l] == ':'
&& r->filename[l+1] == '/'
&& r->filename[l+2] == '/' ) {
@@ -1029,6 +1044,7 @@ static void set_cache_value(const char *name, apr_time_t t, char *key,
#endif
return;
}
+ apr_pool_tag(p, "rewrite_cachedmap");
map = apr_palloc(cachep->pool, sizeof(cachedmap));
map->pool = p;
@@ -1106,6 +1122,7 @@ static int init_cache(apr_pool_t *p)
cachep = NULL; /* turns off cache */
return 0;
}
+ apr_pool_tag(cachep->pool, "rewrite_cachep");
cachep->maps = apr_hash_make(cachep->pool);
#if APR_HAS_THREADS
@@ -1353,12 +1370,31 @@ static char *lookup_map_txtfile(request_rec *r, const char *file, char *key)
static char *lookup_map_dbmfile(request_rec *r, const char *file,
const char *dbmtype, char *key)
{
+#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
+ const apr_dbm_driver_t *driver;
+ const apu_err_t *err;
+#endif
apr_dbm_t *dbmfp = NULL;
apr_datum_t dbmkey;
apr_datum_t dbmval;
char *value;
apr_status_t rv;
+#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
+ if ((rv = apr_dbm_get_driver(&driver, dbmtype, &err,
+ r->pool)) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10287)
+ "mod_rewrite: can't load DBM library '%s': %s",
+ err->reason, err->msg);
+ return NULL;
+ }
+ if ((rv = apr_dbm_open2(&dbmfp, driver, file, APR_DBM_READONLY,
+ APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00656)
+ "mod_rewrite: can't open DBM RewriteMap %s", file);
+ return NULL;
+ }
+#else
if ((rv = apr_dbm_open_ex(&dbmfp, dbmtype, file, APR_DBM_READONLY,
APR_OS_DEFAULT, r->pool)) != APR_SUCCESS)
{
@@ -1366,6 +1402,7 @@ static char *lookup_map_dbmfile(request_rec *r, const char *file,
"mod_rewrite: can't open DBM RewriteMap %s", file);
return NULL;
}
+#endif
dbmkey.dptr = key;
dbmkey.dsize = strlen(key);
@@ -1864,8 +1901,8 @@ static char *lookup_variable(char *var, rewrite_ctx *ctx)
result = getenv(var);
}
}
- else if (var[4] && !strncasecmp(var, "SSL", 3) && rewrite_ssl_lookup) {
- result = rewrite_ssl_lookup(r->pool, r->server, r->connection, r,
+ else if (var[4] && !strncasecmp(var, "SSL", 3)) {
+ result = ap_ssl_var_lookup(r->pool, r->server, r->connection, r,
var + 4);
}
}
@@ -1963,7 +2000,7 @@ static char *lookup_variable(char *var, rewrite_ctx *ctx)
case 5:
if (!strcmp(var, "HTTPS")) {
- int flag = rewrite_is_https && rewrite_is_https(r->connection);
+ int flag = ap_ssl_conn_is_ssl(r->connection);
return apr_pstrdup(r->pool, flag ? "on" : "off");
}
break;
@@ -2430,7 +2467,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
/* escape the backreference */
char *tmp2, *tmp;
tmp = apr_pstrmemdup(pool, bri->source + bri->regmatch[n].rm_so, span);
- tmp2 = escape_backref(pool, tmp, entry->escapes, entry->flags & RULEFLAG_ESCAPENOPLUS);
+ tmp2 = escape_backref(pool, tmp, entry->escapes, entry->noescapes,
+ entry->flags);
rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
tmp, tmp2));
@@ -2538,6 +2576,7 @@ static void add_cookie(request_rec *r, char *s)
char *path;
char *secure;
char *httponly;
+ char *samesite;
char *tok_cntx;
char *cookie;
@@ -2572,6 +2611,7 @@ static void add_cookie(request_rec *r, char *s)
path = expires ? apr_strtok(NULL, sep, &tok_cntx) : NULL;
secure = path ? apr_strtok(NULL, sep, &tok_cntx) : NULL;
httponly = secure ? apr_strtok(NULL, sep, &tok_cntx) : NULL;
+ samesite = httponly ? apr_strtok(NULL, sep, &tok_cntx) : NULL;
if (expires) {
apr_time_exp_t tms;
@@ -2599,18 +2639,23 @@ static void add_cookie(request_rec *r, char *s)
: NULL,
expires ? (exp_time ? exp_time : "")
: NULL,
- (secure && (!strcasecmp(secure, "true")
+ (secure && (!ap_cstr_casecmp(secure, "true")
|| !strcmp(secure, "1")
- || !strcasecmp(secure,
+ || !ap_cstr_casecmp(secure,
"secure"))) ?
"; secure" : NULL,
- (httponly && (!strcasecmp(httponly, "true")
+ (httponly && (!ap_cstr_casecmp(httponly, "true")
|| !strcmp(httponly, "1")
- || !strcasecmp(httponly,
+ || !ap_cstr_casecmp(httponly,
"HttpOnly"))) ?
"; HttpOnly" : NULL,
NULL);
+ if (samesite && strcmp(samesite, "0") && ap_cstr_casecmp(samesite,"false")) {
+ cookie = apr_pstrcat(rmain->pool, cookie, "; SameSite=",
+ samesite, NULL);
+ }
+
apr_table_addn(rmain->err_headers_out, "Set-Cookie", cookie);
apr_pool_userdata_set("set", notename, NULL, rmain->pool);
rewritelog((rmain, 5, NULL, "setting cookie '%s'", cookie));
@@ -2724,7 +2769,7 @@ static apr_status_t rewritelock_remove(void *data)
* XXX: what an inclined parser. Seems we have to leave it so
* for backwards compat. *sigh*
*/
-static int parseargline(char *str, char **a1, char **a2, char **a3)
+static int parseargline(char *str, char **a1, char **a2, char **a2_end, char **a3)
{
char quote;
@@ -2775,8 +2820,10 @@ static int parseargline(char *str, char **a1, char **a2, char **a3)
if (!*str) {
*a3 = NULL; /* 3rd argument is optional */
+ *a2_end = str;
return 0;
}
+ *a2_end = str;
*str++ = '\0';
while (apr_isspace(*str)) {
@@ -3316,7 +3363,7 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
rewrite_server_conf *sconf;
rewritecond_entry *newcond;
ap_regex_t *regexp;
- char *a1 = NULL, *a2 = NULL, *a3 = NULL;
+ char *a1 = NULL, *a2 = NULL, *a2_end, *a3 = NULL;
const char *err;
sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
@@ -3334,7 +3381,7 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
* of the argument line. So we can use a1 .. a3 without
* copying them again.
*/
- if (parseargline(str, &a1, &a2, &a3)) {
+ if (parseargline(str, &a1, &a2, &a2_end, &a3)) {
return apr_pstrcat(cmd->pool, "RewriteCond: bad argument line '", str,
"'", NULL);
}
@@ -3493,13 +3540,24 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg,
case 'B':
if (!*key || !strcasecmp(key, "ackrefescaping")) {
cfg->flags |= RULEFLAG_ESCAPEBACKREF;
- if (val && *val) {
+ if (val && *val) {
cfg->escapes = val;
}
}
+ else if (!strcasecmp(key, "NE")) {
+ if (val && *val) {
+ cfg->noescapes = val;
+ }
+ else {
+ return "flag 'BNE' wants a list of characters (i.e. [BNE=...])";
+ }
+ }
else if (!strcasecmp(key, "NP") || !strcasecmp(key, "ackrefernoplus")) {
cfg->flags |= RULEFLAG_ESCAPENOPLUS;
}
+ else if (!strcasecmp(key, "CTLS")) {
+ cfg->flags |= RULEFLAG_ESCAPECTLS|RULEFLAG_ESCAPEBACKREF;
+ }
else {
++error;
}
@@ -3742,7 +3800,7 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
rewrite_server_conf *sconf;
rewriterule_entry *newrule;
ap_regex_t *regexp;
- char *a1 = NULL, *a2 = NULL, *a3 = NULL;
+ char *a1 = NULL, *a2 = NULL, *a2_end, *a3 = NULL;
const char *err;
sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
@@ -3756,12 +3814,11 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
}
/* parse the argument line ourself */
- if (parseargline(str, &a1, &a2, &a3)) {
+ if (parseargline(str, &a1, &a2, &a2_end, &a3)) {
return apr_pstrcat(cmd->pool, "RewriteRule: bad argument line '", str,
"'", NULL);
}
- /* arg3: optional flags field */
newrule->forced_mimetype = NULL;
newrule->forced_handler = NULL;
newrule->forced_responsecode = HTTP_MOVED_TEMPORARILY;
@@ -3770,6 +3827,9 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
newrule->cookie = NULL;
newrule->skip = 0;
newrule->maxrounds = REWRITE_MAX_ROUNDS;
+ newrule->escapes = newrule->noescapes = NULL;
+
+ /* arg3: optional flags field */
if (a3 != NULL) {
if ((err = cmd_parseflagfield(cmd->pool, newrule, a3,
cmd_rewriterule_setflag)) != NULL) {
@@ -3803,6 +3863,25 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
newrule->flags |= RULEFLAG_NOSUB;
}
+ if (*(a2_end-1) == '?') {
+ /* a literal ? at the end of the unsubstituted rewrite rule */
+ if (newrule->flags & RULEFLAG_QSAPPEND) {
+ /* with QSA, splitout_queryargs will safely handle it if RULEFLAG_QSLAST is set */
+ newrule->flags |= RULEFLAG_QSLAST;
+ }
+ else {
+ /* avoid getting a query string via inadvertent capture */
+ newrule->flags |= RULEFLAG_QSNONE;
+ /* trailing ? has done its job, but splitout_queryargs will not chop it off */
+ *(a2_end-1) = '\0';
+ }
+ }
+ else if (newrule->flags & RULEFLAG_QSDISCARD) {
+ if (NULL == ap_strchr(newrule->output, '?')) {
+ newrule->flags |= RULEFLAG_QSNONE;
+ }
+ }
+
/* now, if the server or per-dir config holds an
* array of RewriteCond entries, we take it for us
* and clear the array
@@ -4090,7 +4169,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
}
/* Additionally we strip the physical path from the url to match
- * it independent from the underlaying filesystem.
+ * it independent from the underlying filesystem.
*/
if (!is_proxyreq && strlen(ctx->uri) >= dirlen &&
!strncmp(ctx->uri, ctx->perdir, dirlen)) {
@@ -4208,9 +4287,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
r->path_info = NULL;
}
- splitout_queryargs(r, p->flags & RULEFLAG_QSAPPEND,
- p->flags & RULEFLAG_QSDISCARD,
- p->flags & RULEFLAG_QSLAST);
+ splitout_queryargs(r, p->flags);
/* Add the previously stripped per-directory location prefix, unless
* (1) it's an absolute URL path and
@@ -4516,9 +4593,6 @@ static int post_config(apr_pool_t *p,
}
}
- rewrite_ssl_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
- rewrite_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
-
return OK;
}
@@ -4692,8 +4766,25 @@ static int hook_uri2file(request_rec *r)
}
if (rulestatus) {
- unsigned skip;
- apr_size_t flen;
+ apr_size_t flen = r->filename ? strlen(r->filename) : 0;
+ unsigned skip_absolute = flen ? is_absolute_uri(r->filename, NULL) : 0;
+ int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0);
+ int will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
+
+ if (r->args
+ && !will_escape
+ && *(ap_scan_vchar_obstext(r->args))) {
+ /*
+ * We have a raw control character or a ' ' in r->args.
+ * Correct encoding was missed.
+ * Correct encoding was missed and we're not going to escape
+ * it before returning.
+ */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410)
+ "Rewritten query string contains control "
+ "characters or spaces");
+ return HTTP_FORBIDDEN;
+ }
if (ACTION_STATUS == rulestatus) {
int n = r->status;
@@ -4702,8 +4793,7 @@ static int hook_uri2file(request_rec *r)
return n;
}
- flen = r->filename ? strlen(r->filename) : 0;
- if (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
+ if (to_proxyreq) {
/* it should be go on as an internal proxy request */
/* check if the proxy module is enabled, so
@@ -4745,7 +4835,7 @@ static int hook_uri2file(request_rec *r)
r->filename));
return OK;
}
- else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) {
+ else if (skip_absolute > 0) {
int n;
/* it was finally rewritten to a remote URL */
@@ -4753,7 +4843,7 @@ static int hook_uri2file(request_rec *r)
if (rulestatus != ACTION_NOESCAPE) {
rewritelog((r, 1, NULL, "escaping %s for redirect",
r->filename));
- r->filename = escape_absolute_uri(r->pool, r->filename, skip);
+ r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute);
}
/* append the QUERY_STRING part */
@@ -4977,7 +5067,26 @@ static int hook_fixup(request_rec *r)
*/
rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory);
if (rulestatus) {
- unsigned skip;
+ unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
+ int to_proxyreq = 0;
+ int will_escape = 0;
+
+ l = strlen(r->filename);
+ to_proxyreq = l > 6 && strncmp(r->filename, "proxy:", 6) == 0;
+ will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
+
+ if (r->args
+ && !will_escape
+ && *(ap_scan_vchar_obstext(r->args))) {
+ /*
+ * We have a raw control character or a ' ' in r->args.
+ * Correct encoding was missed.
+ */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10411)
+ "Rewritten query string contains control "
+ "characters or spaces");
+ return HTTP_FORBIDDEN;
+ }
if (ACTION_STATUS == rulestatus) {
int n = r->status;
@@ -4986,8 +5095,7 @@ static int hook_fixup(request_rec *r)
return n;
}
- l = strlen(r->filename);
- if (l > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
+ if (to_proxyreq) {
/* it should go on as an internal proxy request */
/* make sure the QUERY_STRING and
@@ -5011,7 +5119,7 @@ static int hook_fixup(request_rec *r)
"%s [OK]", r->filename));
return OK;
}
- else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) {
+ else if (skip_absolute > 0) {
/* it was finally rewritten to a remote URL */
/* because we are in a per-dir context
@@ -5020,7 +5128,7 @@ static int hook_fixup(request_rec *r)
*/
if (dconf->baseurl != NULL) {
/* skip 'scheme://' */
- cp = r->filename + skip;
+ cp = r->filename + skip_absolute;
if ((cp = ap_strchr(cp, '/')) != NULL && *(++cp)) {
rewritelog((r, 2, dconf->directory,
@@ -5065,7 +5173,7 @@ static int hook_fixup(request_rec *r)
if (rulestatus != ACTION_NOESCAPE) {
rewritelog((r, 1, dconf->directory, "escaping %s for redirect",
r->filename));
- r->filename = escape_absolute_uri(r->pool, r->filename, skip);
+ r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute);
}
/* append the QUERY_STRING part */
diff --git a/modules/mappers/mod_rewrite.mak b/modules/mappers/mod_rewrite.mak
index 3b08cab..860dd8b 100644
--- a/modules/mappers/mod_rewrite.mak
+++ b/modules/mappers/mod_rewrite.mak
@@ -62,7 +62,7 @@ CLEAN :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
-CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../database" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_rewrite_src" /FD /c
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../database" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../server" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_rewrite_src" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
@@ -166,7 +166,7 @@ CLEAN :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
-CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../database" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_rewrite_src" /FD /EHsc /c
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../database" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../server" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_rewrite_src" /FD /EHsc /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
diff --git a/modules/mappers/mod_speling.c b/modules/mappers/mod_speling.c
index 3e97423..2ed65eb 100644
--- a/modules/mappers/mod_speling.c
+++ b/modules/mappers/mod_speling.c
@@ -22,8 +22,6 @@
#define APR_WANT_STRFUNC
#include "apr_want.h"
-#define WANT_BASENAME_MATCH
-
#include "httpd.h"
#include "http_core.h"
#include "http_config.h"
@@ -59,7 +57,8 @@ module AP_MODULE_DECLARE_DATA speling_module;
typedef struct {
int enabled;
- int case_only;
+ int check_case_only;
+ int check_basename_match;
} spconfig;
/*
@@ -76,7 +75,8 @@ static void *mkconfig(apr_pool_t *p)
spconfig *cfg = apr_pcalloc(p, sizeof(spconfig));
cfg->enabled = 0;
- cfg->case_only = 0;
+ cfg->check_case_only = 0;
+ cfg->check_basename_match = 1;
return cfg;
}
@@ -107,8 +107,11 @@ static const command_rec speling_cmds[] =
(void*)APR_OFFSETOF(spconfig, enabled), OR_OPTIONS,
"whether or not to fix miscapitalized/misspelled requests"),
AP_INIT_FLAG("CheckCaseOnly", ap_set_flag_slot,
- (void*)APR_OFFSETOF(spconfig, case_only), OR_OPTIONS,
+ (void*)APR_OFFSETOF(spconfig, check_case_only), OR_OPTIONS,
"whether or not to fix only miscapitalized requests"),
+ AP_INIT_FLAG("CheckBasenameMatch", ap_set_flag_slot,
+ (void*)APR_OFFSETOF(spconfig, check_basename_match), OR_OPTIONS,
+ "whether or not to fix files with the same base name"),
{ NULL }
};
@@ -302,7 +305,7 @@ static int check_speling(request_rec *r)
* simple typing errors are checked next (like, e.g.,
* missing/extra/transposed char)
*/
- else if ((cfg->case_only == 0)
+ else if ((cfg->check_case_only == 0)
&& ((q = spdist(bad, dirent.name)) != SP_VERYDIFFERENT)) {
misspelled_file *sp_new;
@@ -316,22 +319,14 @@ static int check_speling(request_rec *r)
* requests. It is of questionable use to continue looking for
* files with the same base name, but potentially of totally wrong
* type (index.html <-> index.db).
- * I would propose to not set the WANT_BASENAME_MATCH define.
- * 08-Aug-1997 <Martin.Kraemer@Mch.SNI.De>
*
- * However, Alexei replied giving some reasons to add it anyway:
- * > Oh, by the way, I remembered why having the
- * > extension-stripping-and-matching stuff is a good idea:
- * >
- * > If you're using MultiViews, and have a file named foobar.html,
- * > which you refer to as "foobar", and someone tried to access
- * > "Foobar", mod_speling won't find it, because it won't find
- * > anything matching that spelling. With the extension-munging,
- * > it would locate "foobar.html". Not perfect, but I ran into
- * > that problem when I first wrote the module.
+ * If you're using MultiViews, and have a file named foobar.html,
+ * which you refer to as "foobar", and someone tried to access
+ * "Foobar", without CheckBasenameMatch, mod_speling won't find it,
+ * because it won't find anything matching that spelling.
+ * With the extension-munging, it would locate "foobar.html".
*/
- else {
-#ifdef WANT_BASENAME_MATCH
+ else if (cfg->check_basename_match == 1) {
/*
* Okay... we didn't find anything. Now we take out the hard-core
* power tools. There are several cases here. Someone might have
@@ -356,7 +351,6 @@ static int check_speling(request_rec *r)
sp_new->name = apr_pstrdup(r->pool, dirent.name);
sp_new->quality = SP_VERYDIFFERENT;
}
-#endif
}
}
apr_dir_close(dir);
@@ -425,6 +419,7 @@ static int check_speling(request_rec *r)
if (apr_pool_create(&sub_pool, p) != APR_SUCCESS)
return DECLINED;
+ apr_pool_tag(sub_pool, "speling_sub");
t = apr_array_make(sub_pool, candidates->nelts * 8 + 8,
sizeof(char *));
diff --git a/modules/mappers/mod_vhost_alias.c b/modules/mappers/mod_vhost_alias.c
index 0b61694..b1e5bfb 100644
--- a/modules/mappers/mod_vhost_alias.c
+++ b/modules/mappers/mod_vhost_alias.c
@@ -152,7 +152,7 @@ static const char *vhost_alias_set(cmd_parms *cmd, void *dummy, const char *map)
}
if (!ap_os_is_path_absolute(cmd->pool, map)) {
- if (strcasecmp(map, "none")) {
+ if (ap_cstr_casecmp(map, "none")) {
return "format string must be an absolute path, or 'none'";
}
*pmap = NULL;