Author: rjung Date: Sat Dec 20 16:47:18 2014 New Revision: 1647017 URL: http://svn.apache.org/r1647017 Log: Add option to control handling of multiple adjacent slashes in mount and unmount.
New default is collapsing the slashes only in unmount. Before this change, adjacent slashes were never collapsed, so most mounts and unmounts didn't match for URLs with multiple adjacent slashes. Configuration is done via new JkOption for Apache (values "CollapseSlashesAll", "CollapseSlashesNone" or "CollapseSlashesUnmount") and via property "collapse_slashes" for IIS (values "all", "none", "unmount"). Modified: tomcat/jk/trunk/native/apache-1.3/mod_jk.c tomcat/jk/trunk/native/apache-2.0/mod_jk.c tomcat/jk/trunk/native/common/jk_global.h tomcat/jk/trunk/native/common/jk_uri_worker_map.c tomcat/jk/trunk/native/common/jk_uri_worker_map.h tomcat/jk/trunk/native/common/jk_util.c tomcat/jk/trunk/native/common/jk_util.h tomcat/jk/trunk/native/iis/jk_isapi_plugin.c tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml Modified: tomcat/jk/trunk/native/apache-1.3/mod_jk.c URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/apache-1.3/mod_jk.c?rev=1647017&r1=1647016&r2=1647017&view=diff ============================================================================== --- tomcat/jk/trunk/native/apache-1.3/mod_jk.c (original) +++ tomcat/jk/trunk/native/apache-1.3/mod_jk.c Sat Dec 20 16:47:18 2014 @@ -2097,9 +2097,11 @@ const char *jk_set_options(cmd_parms * c mask = 0; - if (action == '-' && !strncasecmp(w, "ForwardURI", strlen("ForwardURI"))) + if (action == '-' && + (!strncasecmp(w, "ForwardURI", strlen("ForwardURI")) || + !strncasecmp(w, "CollapseSlashes", strlen("CollapseSlashes")))) return ap_pstrcat(cmd->pool, "JkOptions: Illegal option '-", w, - "': ForwardURI* options can not be disabled", NULL); + "': option can not be disabled", NULL); if (!strcasecmp(w, "ForwardURICompat")) { opt = JK_OPT_FWDURICOMPAT; @@ -2117,6 +2119,18 @@ const char *jk_set_options(cmd_parms * c opt = JK_OPT_FWDURIPROXY; mask = JK_OPT_FWDURIMASK; } + else if (!strcasecmp(w, "CollapseSlashesAll")) { + opt = JK_OPT_COLLAPSEALL; + mask = JK_OPT_COLLAPSEMASK; + } + else if (!strcasecmp(w, "CollapseSlashesNone")) { + opt = JK_OPT_COLLAPSENONE; + mask = JK_OPT_COLLAPSEMASK; + } + else if (!strcasecmp(w, "CollapseSlashesUnmount")) { + opt = JK_OPT_COLLAPSEUNMOUNT; + mask = JK_OPT_COLLAPSEMASK; + } else if (!strcasecmp(w, "ForwardDirectories")) { opt = JK_OPT_FWDDIRS; } @@ -2789,6 +2803,10 @@ static void *merge_jk_config(ap_pool * p overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_FWDURIMASK; else overrides->options |= (base->options & ~base->exclude_options); + if (overrides->options & JK_OPT_COLLAPSEMASK) + overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_COLLAPSEMASK; + else + overrides->options |= (base->options & ~base->exclude_options); if (base->envvars) { if (overrides->envvars && overrides->envvars_has_own) { @@ -3009,6 +3027,8 @@ static void jk_init(server_rec * s, ap_p uri_worker_map_switch(sconf->uw_map, sconf->log); uri_worker_map_load(sconf->uw_map, sconf->log); } + if (conf->options & JK_OPT_COLLAPSEMASK) + sconf->uw_map->collapse_slashes = conf->options & JK_OPT_COLLAPSEMASK; } else { if (sconf->mountcopy == JK_TRUE) { Modified: tomcat/jk/trunk/native/apache-2.0/mod_jk.c URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/apache-2.0/mod_jk.c?rev=1647017&r1=1647016&r2=1647017&view=diff ============================================================================== --- tomcat/jk/trunk/native/apache-2.0/mod_jk.c (original) +++ tomcat/jk/trunk/native/apache-2.0/mod_jk.c Sat Dec 20 16:47:18 2014 @@ -2204,9 +2204,11 @@ static const char *jk_set_options(cmd_pa mask = 0; - if (action == '-' && !strncasecmp(w, "ForwardURI", strlen("ForwardURI"))) + if (action == '-' && + (!strncasecmp(w, "ForwardURI", strlen("ForwardURI")) || + !strncasecmp(w, "CollapseSlashes", strlen("CollapseSlashes")))) return apr_pstrcat(cmd->pool, "JkOptions: Illegal option '-", w, - "': ForwardURI* options can not be disabled", NULL); + "': option can not be disabled", NULL); if (!strcasecmp(w, "ForwardURICompat")) { opt = JK_OPT_FWDURICOMPAT; @@ -2224,6 +2226,18 @@ static const char *jk_set_options(cmd_pa opt = JK_OPT_FWDURIPROXY; mask = JK_OPT_FWDURIMASK; } + else if (!strcasecmp(w, "CollapseSlashesAll")) { + opt = JK_OPT_COLLAPSEALL; + mask = JK_OPT_COLLAPSEMASK; + } + else if (!strcasecmp(w, "CollapseSlashesNone")) { + opt = JK_OPT_COLLAPSENONE; + mask = JK_OPT_COLLAPSEMASK; + } + else if (!strcasecmp(w, "CollapseSlashesUnmount")) { + opt = JK_OPT_COLLAPSEUNMOUNT; + mask = JK_OPT_COLLAPSEMASK; + } else if (!strcasecmp(w, "ForwardDirectories")) { opt = JK_OPT_FWDDIRS; } @@ -3024,6 +3038,10 @@ static void *merge_jk_config(apr_pool_t overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_FWDURIMASK; else overrides->options |= (base->options & ~base->exclude_options); + if (overrides->options & JK_OPT_COLLAPSEMASK) + overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_COLLAPSEMASK; + else + overrides->options |= (base->options & ~base->exclude_options); if (base->envvars) { if (overrides->envvars && overrides->envvars_has_own) { @@ -3501,6 +3519,8 @@ static int jk_post_config(apr_pool_t * p uri_worker_map_switch(sconf->uw_map, sconf->log); uri_worker_map_load(sconf->uw_map, sconf->log); } + if (conf->options & JK_OPT_COLLAPSEMASK) + sconf->uw_map->collapse_slashes = conf->options & JK_OPT_COLLAPSEMASK; } else { if (sconf->mountcopy == JK_TRUE) { Modified: tomcat/jk/trunk/native/common/jk_global.h URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_global.h?rev=1647017&r1=1647016&r2=1647017&view=diff ============================================================================== --- tomcat/jk/trunk/native/common/jk_global.h (original) +++ tomcat/jk/trunk/native/common/jk_global.h Sat Dec 20 16:47:18 2014 @@ -272,8 +272,12 @@ extern "C" /* Forward physical tcp peer address instead of * client address as provided e.g. by httpd mod_remoteip. */ #define JK_OPT_FWDPHYSICAL 0x0800 +#define JK_OPT_COLLAPSEMASK 0x7000 +#define JK_OPT_COLLAPSEALL 0x1000 +#define JK_OPT_COLLAPSENONE 0x2000 +#define JK_OPT_COLLAPSEUNMOUNT 0x4000 -#define JK_OPT_DEFAULT (JK_OPT_FWDURIDEFAULT | JK_OPT_FWDKEYSIZE) +#define JK_OPT_DEFAULT (JK_OPT_FWDURIDEFAULT | JK_OPT_FWDKEYSIZE | JK_OPT_COLLAPSEUNMOUNT) /* Check for EBCDIC systems */ Modified: tomcat/jk/trunk/native/common/jk_uri_worker_map.c URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_uri_worker_map.c?rev=1647017&r1=1647016&r2=1647017&view=diff ============================================================================== --- tomcat/jk/trunk/native/common/jk_uri_worker_map.c (original) +++ tomcat/jk/trunk/native/common/jk_uri_worker_map.c Sat Dec 20 16:47:18 2014 @@ -176,9 +176,10 @@ static void uri_worker_map_dump(jk_uri_w int i, off; if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "uri map dump %s: id=%d, index=%d file='%s' reject_unsafe=%d " - "reload=%d modified=%d checked=%d", + "collapse_slashes=%d reload=%d modified=%d checked=%d", reason, uw_map->id, uw_map->index, STRNULL_FOR_NULL(uw_map->fname), - uw_map->reject_unsafe, uw_map->reload, uw_map->modified, uw_map->checked); + uw_map->reject_unsafe, uw_map->collapse_slashes, + uw_map->reload, uw_map->modified, uw_map->checked); } for (i = 0; i <= 1; i++) { jk_log(l, JK_LOG_DEBUG, "generation %d: size=%d nosize=%d capacity=%d", @@ -244,6 +245,7 @@ int uri_worker_map_alloc(jk_uri_worker_m uw_map->index = 0; uw_map->fname = NULL; uw_map->reject_unsafe = 0; + uw_map->collapse_slashes = JK_COLLAPSE_DEFAULT; uw_map->reload = JK_URIMAP_DEF_RELOAD; uw_map->modified = 0; uw_map->checked = 0; @@ -697,48 +699,42 @@ void parse_rule_extensions(char *rule, r else if (!strncmp(param, JK_UWMAP_EXTENSION_ACTIVE, strlen(JK_UWMAP_EXTENSION_ACTIVE))) { if (extensions->active) jk_log(l, JK_LOG_WARNING, - "rule extension '%s' only allowed once", - JK_UWMAP_EXTENSION_ACTIVE); + "rule extension '" JK_UWMAP_EXTENSION_ACTIVE "' only allowed once"); else extensions->active = param + strlen(JK_UWMAP_EXTENSION_ACTIVE); } else if (!strncmp(param, JK_UWMAP_EXTENSION_DISABLED, strlen(JK_UWMAP_EXTENSION_DISABLED))) { if (extensions->disabled) jk_log(l, JK_LOG_WARNING, - "rule extension '%s' only allowed once", - JK_UWMAP_EXTENSION_DISABLED); + "rule extension '" JK_UWMAP_EXTENSION_DISABLED "' only allowed once"); else extensions->disabled = param + strlen(JK_UWMAP_EXTENSION_DISABLED); } else if (!strncmp(param, JK_UWMAP_EXTENSION_STOPPED, strlen(JK_UWMAP_EXTENSION_STOPPED))) { if (extensions->stopped) jk_log(l, JK_LOG_WARNING, - "rule extension '%s' only allowed once", - JK_UWMAP_EXTENSION_STOPPED); + "rule extension '" JK_UWMAP_EXTENSION_STOPPED "' only allowed once"); else extensions->stopped = param + strlen(JK_UWMAP_EXTENSION_STOPPED); } else if (!strncmp(param, JK_UWMAP_EXTENSION_FAIL_ON_STATUS, strlen(JK_UWMAP_EXTENSION_FAIL_ON_STATUS))) { if (extensions->fail_on_status_str) jk_log(l, JK_LOG_WARNING, - "rule extension '%s' only allowed once", - JK_UWMAP_EXTENSION_FAIL_ON_STATUS); + "rule extension '" JK_UWMAP_EXTENSION_FAIL_ON_STATUS "' only allowed once"); else extensions->fail_on_status_str = param + strlen(JK_UWMAP_EXTENSION_FAIL_ON_STATUS); } else if (!strncmp(param, JK_UWMAP_EXTENSION_SESSION_COOKIE, strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE))) { if (extensions->session_cookie) jk_log(l, JK_LOG_WARNING, - "extension '%s' in uri worker map only allowed once", - JK_UWMAP_EXTENSION_SESSION_COOKIE); + "extension '" JK_UWMAP_EXTENSION_SESSION_COOKIE "' in uri worker map only allowed once"); else extensions->session_cookie = param + strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE); } else if (!strncmp(param, JK_UWMAP_EXTENSION_SESSION_PATH, strlen(JK_UWMAP_EXTENSION_SESSION_PATH))) { if (extensions->session_path) jk_log(l, JK_LOG_WARNING, - "extension '%s' in uri worker map only allowed once", - JK_UWMAP_EXTENSION_SESSION_PATH); + "extension '" JK_UWMAP_EXTENSION_SESSION_PATH "' in uri worker map only allowed once"); else { // Check if the session identifier starts with semicolon. if (!strcmp(param, JK_UWMAP_EXTENSION_SESSION_PATH)) { @@ -755,8 +751,7 @@ void parse_rule_extensions(char *rule, r else if (!strncmp(param, JK_UWMAP_EXTENSION_SET_SESSION_COOKIE, strlen(JK_UWMAP_EXTENSION_SET_SESSION_COOKIE))) { if (extensions->set_session_cookie) jk_log(l, JK_LOG_WARNING, - "extension '%s' in uri worker map only allowed once", - JK_UWMAP_EXTENSION_SET_SESSION_COOKIE); + "extension '" JK_UWMAP_EXTENSION_SET_SESSION_COOKIE "' in uri worker map only allowed once"); else { int val = atoi(param + strlen(JK_UWMAP_EXTENSION_SET_SESSION_COOKIE)); if (val) { @@ -770,8 +765,7 @@ void parse_rule_extensions(char *rule, r else if (!strncmp(param, JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH, strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH))) { if (extensions->session_cookie_path) jk_log(l, JK_LOG_WARNING, - "extension '%s' in uri worker map only allowed once", - JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH); + "extension '" JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH "' in uri worker map only allowed once"); else extensions->session_cookie_path = param + strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH); } @@ -1073,12 +1067,12 @@ static int is_nomatch(jk_uri_worker_map_ const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, const char *uri, const char *vhost, rule_extension_t **extensions, - int *index, - jk_logger_t *l) + int *index, jk_logger_t *l) { unsigned int i; unsigned int vhost_len; int reject_unsafe; + int collapse_slashes; int rv = -1; char url[JK_MAX_URI_LEN+1]; @@ -1116,10 +1110,8 @@ const char *map_uri_to_worker_ext(jk_uri return NULL; } } - /* Make the copy of the provided uri and strip - * everything after the first ';' char. - */ reject_unsafe = uw_map->reject_unsafe; + collapse_slashes = uw_map->collapse_slashes; vhost_len = 0; /* * In case we got a vhost, we prepend a slash @@ -1147,6 +1139,9 @@ const char *map_uri_to_worker_ext(jk_uri } vhost_len += off; } + /* Make the copy of the provided uri and strip + * everything after the first ';' char. + */ for (i = 0; i < strlen(uri); i++) { if (i == JK_MAX_URI_LEN) { jk_log(l, JK_LOG_WARNING, @@ -1174,6 +1169,12 @@ const char *map_uri_to_worker_ext(jk_uri jk_log(l, JK_LOG_DEBUG, "Found session identifier '%s' in url '%s'", url_rewrite, uri); } + if (collapse_slashes == JK_COLLAPSE_ALL) { + /* Remove multiple slashes + * No need to copy url, because it is local and + * the unchanged url is no longer needed */ + jk_no2slash(url); + } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Attempting to map URI '%s' from %d maps", url, IND_THIS(uw_map->size)); @@ -1185,6 +1186,13 @@ const char *map_uri_to_worker_ext(jk_uri /* In case we found a match, check for the unmounts. */ if (rv >= 0 && IND_THIS(uw_map->nosize)) { + if (collapse_slashes == JK_COLLAPSE_UNMOUNT) { + /* Remove multiple slashes when looking for + * unmount to prevent trivial unmount bypass attack. + * No need to copy url, because it is local and + * the unchanged url is no longer needed */ + jk_no2slash(url); + } /* Again first including vhost. */ int rc = is_nomatch(uw_map, url, rv, l); /* If no unmount was found, try without vhost. */ Modified: tomcat/jk/trunk/native/common/jk_uri_worker_map.h URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_uri_worker_map.h?rev=1647017&r1=1647016&r2=1647017&view=diff ============================================================================== --- tomcat/jk/trunk/native/common/jk_uri_worker_map.h (original) +++ tomcat/jk/trunk/native/common/jk_uri_worker_map.h Sat Dec 20 16:47:18 2014 @@ -58,6 +58,11 @@ extern "C" #define MATCH_TYPE_STOPPED 0x4000 */ +#define JK_COLLAPSE_ALL 0x0001 +#define JK_COLLAPSE_NONE 0x0002 +#define JK_COLLAPSE_UNMOUNT 0x0003 +#define JK_COLLAPSE_DEFAULT JK_COLLAPSE_UNMOUNT + #define SOURCE_TYPE_WORKERDEF 0x0001 #define SOURCE_TYPE_JKMOUNT 0x0002 #define SOURCE_TYPE_URIMAP 0x0003 @@ -168,6 +173,8 @@ struct jk_uri_worker_map JK_CRIT_SEC cs; /* should we forward potentially unsafe URLs */ int reject_unsafe; + /* how to handle multiple adjacent slashes in URLs */ + int collapse_slashes; /* uriworkermap filename */ const char *fname; /* uriworkermap reload check interval */ Modified: tomcat/jk/trunk/native/common/jk_util.c URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_util.c?rev=1647017&r1=1647016&r2=1647017&view=diff ============================================================================== --- tomcat/jk/trunk/native/common/jk_util.c (original) +++ tomcat/jk/trunk/native/common/jk_util.c Sat Dec 20 16:47:18 2014 @@ -2123,6 +2123,25 @@ int jk_wildchar_match(const char *str, c return (str[x] != '\0'); } +void jk_no2slash(char *name) +{ + char *d, *s; + + s = d = name; + + while (*s) { + if ((*d++ = *s) == '/') { + do { + ++s; + } while (*s == '/'); + } + else { + ++s; + } + } + *d = '\0'; +} + #ifdef _MT_CODE_PTHREAD jk_pthread_t jk_gettid() { Modified: tomcat/jk/trunk/native/common/jk_util.h URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_util.h?rev=1647017&r1=1647016&r2=1647017&view=diff ============================================================================== --- tomcat/jk/trunk/native/common/jk_util.h (original) +++ tomcat/jk/trunk/native/common/jk_util.h Sat Dec 20 16:47:18 2014 @@ -244,6 +244,8 @@ int is_http_status_fail(unsigned int htt int jk_wildchar_match(const char *str, const char *exp, int icase); +void jk_no2slash(char *name); + #define TC32_BRIDGE_TYPE 32 #define TC33_BRIDGE_TYPE 33 #define TC40_BRIDGE_TYPE 40 Modified: tomcat/jk/trunk/native/iis/jk_isapi_plugin.c URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/iis/jk_isapi_plugin.c?rev=1647017&r1=1647016&r2=1647017&view=diff ============================================================================== --- tomcat/jk/trunk/native/iis/jk_isapi_plugin.c (original) +++ tomcat/jk/trunk/native/iis/jk_isapi_plugin.c Sat Dec 20 16:47:18 2014 @@ -117,23 +117,27 @@ static char HTTP_WORKER_HEADER_INDEX[RES #define W3SVC_REGISTRY_KEY "SYSTEM\\CurrentControlSet\\Services\\W3SVC\\Parameters" #define EXTENSION_URI_TAG "extension_uri" -#define URI_SELECT_TAG "uri_select" -#define URI_SELECT_PARSED_VERB "parsed" -#define URI_SELECT_UNPARSED_VERB "unparsed" -#define URI_SELECT_ESCAPED_VERB "escaped" -#define URI_SELECT_PROXY_VERB "proxy" -#define URI_REWRITE_TAG "rewrite_rule_file" -#define SHM_SIZE_TAG "shm_size" -#define WORKER_MOUNT_RELOAD_TAG "worker_mount_reload" -#define STRIP_SESSION_TAG "strip_session" -#define AUTH_COMPLETE_TAG "auth_complete" -#define REJECT_UNSAFE_TAG "reject_unsafe" -#define WATCHDOG_INTERVAL_TAG "watchdog_interval" -#define ENABLE_CHUNKED_ENCODING_TAG "enable_chunked_encoding" -#define ERROR_PAGE_TAG "error_page" +#define URI_SELECT_TAG "uri_select" +#define URI_SELECT_PARSED_VERB "parsed" +#define URI_SELECT_UNPARSED_VERB "unparsed" +#define URI_SELECT_ESCAPED_VERB "escaped" +#define URI_SELECT_PROXY_VERB "proxy" +#define URI_REWRITE_TAG "rewrite_rule_file" +#define SHM_SIZE_TAG "shm_size" +#define WORKER_MOUNT_RELOAD_TAG "worker_mount_reload" +#define STRIP_SESSION_TAG "strip_session" +#define AUTH_COMPLETE_TAG "auth_complete" +#define REJECT_UNSAFE_TAG "reject_unsafe" +#define COLLAPSE_SLASHES_TAG "collapse_slashes" +#define COLLAPSE_SLASHES_ALL_VERB "all" +#define COLLAPSE_SLASHES_NONE_VERB "none" +#define COLLAPSE_SLASHES_UNMOUNT_VERB "unmount" +#define WATCHDOG_INTERVAL_TAG "watchdog_interval" +#define ENABLE_CHUNKED_ENCODING_TAG "enable_chunked_encoding" +#define ERROR_PAGE_TAG "error_page" -#define LOG_ROTATION_TIME_TAG "log_rotationtime" -#define LOG_FILESIZE_TAG "log_filesize" +#define LOG_ROTATION_TIME_TAG "log_rotationtime" +#define LOG_FILESIZE_TAG "log_filesize" /* HTTP standard headers */ #define TRANSFER_ENCODING_CHUNKED_HEADER_COMPLETE "Transfer-Encoding: chunked" @@ -500,6 +504,7 @@ static int strip_session = 0; static int use_auth_notification_flags = 1; static int chunked_encoding_enabled = JK_FALSE; static int reject_unsafe = 0; +static int collapse_slashes = JK_COLLAPSE_DEFAULT; static volatile int watchdog_interval = 0; static HANDLE watchdog_handle = NULL; static char error_page_buf[INTERNET_MAX_URL_LENGTH] = {0}; @@ -2790,6 +2795,7 @@ static int init_jk(char *serverName) uw_map->reject_unsafe = 1; else uw_map->reject_unsafe = 0; + uw_map->collapse_slashes = collapse_slashes; uw_map->reload = worker_mount_reload; if (worker_mount_file[0]) { uw_map->fname = worker_mount_file; @@ -2919,6 +2925,17 @@ int parse_uri_select(const char *uri_sel return -1; } +int parse_collapse_slashes(const char *collapse_slashes) +{ + if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_ALL_VERB)) + return JK_OPT_COLLAPSEALL; + if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_NONE_VERB)) + return JK_OPT_COLLAPSENONE; + if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_UNMOUNT_VERB)) + return JK_OPT_COLLAPSEUNMOUNT; + return -1; +} + static int read_registry_init_data(void) { char tmpbuf[MAX_PATH]; @@ -3016,7 +3033,18 @@ static int read_registry_init_data(void) uri_select_option = opt; } else { - goto cleanup; + jk_log(logger, JK_LOG_ERROR, "Invalid value '%s' for configuration item '" + URI_SELECT_TAG "'", tmpbuf); + } + } + if (get_config_parameter(src, COLLAPSE_SLASHES_TAG, tmpbuf, sizeof(tmpbuf))) { + int opt = parse_collapse_slashes(tmpbuf); + if (opt >= 0) { + collapse_slashes = opt; + } + else { + jk_log(logger, JK_LOG_ERROR, "Invalid value '%s' for configuration item '" + COLLAPSE_SLASHES_TAG "'", tmpbuf); } } shm_config_size = get_config_int(src, SHM_SIZE_TAG, -1); Modified: tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml?rev=1647017&r1=1647016&r2=1647017&view=diff ============================================================================== --- tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml (original) +++ tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml Sat Dec 20 16:47:18 2014 @@ -78,6 +78,14 @@ Apache: Copy log notes instead of using references to prevent access to memory from closed pool. (rjung) </fix> + <add> + Add option to control handling of multiple adjacent slashes in + mount and unmount. New default is collapsing the slashes only in + unmount. Configuration is done via new JkOption for Apache + ("CollapseSlashesAll", "CollapseSlashesNone" or + "CollapseSlashesUnmount") and via property "collapse_slashes" for IIS + (values "all", "none", "unmount"). (rjung) + </add> </changelog> </subsection> </section> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org