diff options
author | Eric Covener <covener@apache.org> | 2019-03-17 15:41:10 +0100 |
---|---|---|
committer | Eric Covener <covener@apache.org> | 2019-03-17 15:41:10 +0100 |
commit | 807a365d9111c366e5314f2b3572501322feb489 (patch) | |
tree | e90d86459287015dac0dccc43809c2df80d8941f | |
parent | Update compatibility notes for mod_socache_redis (diff) | |
download | apache2-807a365d9111c366e5314f2b3572501322feb489.tar.xz apache2-807a365d9111c366e5314f2b3572501322feb489.zip |
Merge consecutive slashes in the URL by default
opt-out w/ `MergeSlashes OFF`.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1855705 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | docs/manual/mod/core.xml | 26 | ||||
-rw-r--r-- | include/ap_mmn.h | 4 | ||||
-rw-r--r-- | include/http_core.h | 1 | ||||
-rw-r--r-- | include/httpd.h | 15 | ||||
-rw-r--r-- | server/core.c | 7 | ||||
-rw-r--r-- | server/request.c | 25 | ||||
-rw-r--r-- | server/util.c | 10 |
8 files changed, 69 insertions, 22 deletions
@@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.1 + *) Merge consecutive slashes in URL's. Opt-out with `MergeSlashes OFF`. + [Eric Covener] + *) mod_proxy/ssl: Cleanup per-request SSL configuration anytime a backend connection is recycled/reused to avoid a possible crash with some SSLProxy configurations in <Location> or <Proxy> context. PR 63256. [Yann Ylavic] diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml index f1516a3517..ac428dfe4b 100644 --- a/docs/manual/mod/core.xml +++ b/docs/manual/mod/core.xml @@ -5332,4 +5332,30 @@ as if 'QualifyRedirectURL ON' was configured.</compatibility> </usage> </directivesynopsis> +<directivesynopsis> +<name>MergeSlashes</name> +<description>Controls whether the server merges consecutive slashes in URLs. +</description> +<syntax>MergeSlashes ON|OFF</syntax> +<default>MergeSlashes ON</default> +<contextlist><context>server config</context><context>virtual host</context> +</contextlist> +<compatibility>Added in 2.5.1</compatibility> + +<usage> + <p>By default, the server merges (or collapses) multiple consecutive slash + ('/') characters in the path component of the request URL.</p> + + <p>When mapping URL's to the filesystem, these multiple slashes are not + significant. However, URL's handled other ways, such as by CGI or proxy, + might prefer to retain the significance of multiple consecutive slashes. + In these cases <directive>MergeSlashes</directive> can be set to + <em>OFF</em> to retain the multiple consecutive slashes. In these + configurations, regular expressions used in the configuration file that match + the path component of the URL (<directive>LocationMatch</directive>, + <directive>RewriteRule</directive>, ...) need to take into account multiple + consecutive slashes.</p> +</usage> +</directivesynopsis> + </modulesynopsis> diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 7d400b3db6..5a479c075e 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -610,6 +610,8 @@ * 20180906.2 (2.5.1-dev) Add ap_state_dir_relative() * 20180906.3 (2.5.1-dev) Add ap_dir_nofnmatch() and ap_dir_fnmatch(). * 20191203.1 (2.5.1-dev) Axe bucket number from struct process_score + * 20191203.2 (2.5.1-dev) Add ap_no2slash_ex() and merge_slashes to + * core_server_conf. */ #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */ @@ -617,7 +619,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20191203 #endif -#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/http_core.h b/include/http_core.h index fe3836fb34..00aeaa7800 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -771,6 +771,7 @@ typedef struct { apr_size_t flush_max_threshold; apr_int32_t flush_max_pipelined; unsigned int strict_host_check; + unsigned int merge_slashes; } core_server_config; /* for AddOutputFiltersByType in core.c */ diff --git a/include/httpd.h b/include/httpd.h index 0005e0cf8a..1c6a242a89 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -1750,11 +1750,22 @@ AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes); AP_DECLARE(int) ap_unescape_urlencoded(char *query); /** - * Convert all double slashes to single slashes - * @param name The string to convert + * Convert all double slashes to single slashes, except where significant + * to the filesystem on the current platform. + * @param name The string to convert, assumed to be a filesystem path */ AP_DECLARE(void) ap_no2slash(char *name) AP_FN_ATTR_NONNULL_ALL; +/** + * Convert all double slashes to single slashes, except where significant + * to the filesystem on the current platform. + * @param name The string to convert + * @param is_fs_path if set to 0, the significance of any double-slashes is + * ignored. + */ +AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path) + AP_FN_ATTR_NONNULL_ALL; + /** * Remove all ./ and xx/../ substrings from a file name. Also remove diff --git a/server/core.c b/server/core.c index 98197d85e9..ceb7dd6bb8 100644 --- a/server/core.c +++ b/server/core.c @@ -528,6 +528,7 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s) conf->protocols_honor_order = -1; conf->async_filter = 0; conf->strict_host_check= AP_CORE_CONFIG_UNSET; + conf->merge_slashes = AP_CORE_CONFIG_UNSET; return (void *)conf; } @@ -628,6 +629,7 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) : base->strict_host_check; AP_CORE_MERGE_FLAG(strict_host_check, conf, base, virt); + AP_CORE_MERGE_FLAG(merge_slashes, conf, base, virt); return conf; } @@ -4922,6 +4924,11 @@ AP_INIT_TAKE1("ProtocolsHonorOrder", set_protocols_honor_order, NULL, RSRC_CONF, AP_INIT_TAKE1("AsyncFilter", set_async_filter, NULL, RSRC_CONF, "'network', 'connection' (default) or 'request' to limit the " "types of filters that support asynchronous handling"), +AP_INIT_FLAG("MergeSlashes", set_core_server_flag, + (void *)APR_OFFSETOF(core_server_config, merge_slashes), + RSRC_CONF, + "Controls whether consecutive slashes in the URI path are merged"), + { NULL } }; diff --git a/server/request.c b/server/request.c index 70812fed59..052e20b3dd 100644 --- a/server/request.c +++ b/server/request.c @@ -167,6 +167,8 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) int file_req = (r->main && r->filename); int access_status; core_dir_config *d; + core_server_config *sconf = + ap_get_core_module_config(r->server->module_config); /* Ignore embedded %2F's in path for proxy requests */ if (!r->proxyreq && r->parsed_uri.path) { @@ -191,6 +193,10 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) } ap_getparents(r->uri); /* OK --- shrinking transformations... */ + if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { + ap_no2slash(r->uri); + ap_no2slash(r->parsed_uri.path); + } /* All file subrequests are a huge pain... they cannot bubble through the * next several steps. Only file subrequests are allowed an empty uri, @@ -1415,20 +1421,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r); cached = (cache->cached != NULL); - - /* Location and LocationMatch differ on their behaviour w.r.t. multiple - * slashes. Location matches multiple slashes with a single slash, - * LocationMatch doesn't. An exception, for backwards brokenness is - * absoluteURIs... in which case neither match multiple slashes. - */ - if (r->uri[0] != '/') { - entry_uri = r->uri; - } - else { - char *uri = apr_pstrdup(r->pool, r->uri); - ap_no2slash(uri); - entry_uri = uri; - } + entry_uri = r->uri; /* If we have an cache->cached location that matches r->uri, * and the vhost's list of locations hasn't changed, we can skip @@ -1495,7 +1488,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t)); } - if (ap_regexec(entry_core->r, r->uri, nmatch, pmatch, 0)) { + if (ap_regexec(entry_core->r, entry_uri, nmatch, pmatch, 0)) { continue; } @@ -1505,7 +1498,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) apr_table_setn(r->subprocess_env, ((const char **)entry_core->refs->elts)[i], apr_pstrndup(r->pool, - r->uri + pmatch[i].rm_so, + entry_uri + pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so)); } } diff --git a/server/util.c b/server/util.c index 3693bfbff1..89c5abef80 100644 --- a/server/util.c +++ b/server/util.c @@ -568,16 +568,16 @@ AP_DECLARE(void) ap_getparents(char *name) name[l] = '\0'; } } - -AP_DECLARE(void) ap_no2slash(char *name) +AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path) { + char *d, *s; s = d = name; #ifdef HAVE_UNC_PATHS /* Check for UNC names. Leave leading two slashes. */ - if (s[0] == '/' && s[1] == '/') + if (is_fs_path && s[0] == '/' && s[1] == '/') *d++ = *s++; #endif @@ -594,6 +594,10 @@ AP_DECLARE(void) ap_no2slash(char *name) *d = '\0'; } +AP_DECLARE(void) ap_no2slash(char *name) +{ + ap_no2slash_ex(name, 1); +} /* * copy at most n leading directories of s into d |