From: Eric Covener Date: Wed, 9 Mar 2016 15:13:04 +0000 (+0000) Subject: Merge r1734125 from trunk: X-Git-Tag: 2.4.19~84 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=53658568dd5d8a3d8731d2c4ce41d8335f3b05ae;p=apache Merge r1734125 from trunk: mod_rewrite: Add QSL|qslast flag to allow rewrites to files with literal question marks in their names. PR 58777. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1734259 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 3765e5d056..b2166c00ad 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.4.19 + *) mod_rewrite: Add QSL|qslast flag to allow rewrites to files with + literal question marks in their names. PR 58777. [Eric Covener] + *) event: use pre_connection hook to properly initialize connection state for slave connections. use protocol_switch hook to initialize server config early based on SNI selected vhost. diff --git a/STATUS b/STATUS index 95a3a1fece..1b4fc28aa9 100644 --- a/STATUS +++ b/STATUS @@ -129,13 +129,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: 2.4.x patch: trunk patch works (modulo CHANGES) +1: minfrin, jim, ylavic - *) mod_rewrite: Add QSL flag as a way to allow rewrites to files with question - marks in their names. PR58777 - trunk patch: http://svn.apache.org/r1734125 - 2.4.x patch: trunk works (modulo CHANGES and compat in docs) - +1 covener, jim, ylavic - - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/docs/manual/mod/mod_rewrite.xml b/docs/manual/mod/mod_rewrite.xml index 70942b100c..dc3a8dd80f 100644 --- a/docs/manual/mod/mod_rewrite.xml +++ b/docs/manual/mod/mod_rewrite.xml @@ -1365,6 +1365,15 @@ cannot use $N in the substitution string! details ... + + qslast|QSL + Interpret the last (right-most) question mark as the query string + delimeter, instead of the first (left-most) as normally used. + Available in 2.4.19 and later. + details + ... + + redirect|R[=code] Forces an external redirect, optionally with the specified diff --git a/docs/manual/rewrite/flags.xml b/docs/manual/rewrite/flags.xml index c716a781e5..e38b5d8ac5 100644 --- a/docs/manual/rewrite/flags.xml +++ b/docs/manual/rewrite/flags.xml @@ -628,6 +628,23 @@ URI. +
QSL|qslast +

+By default, the first (left-most) question mark in the substitution +delimits the path from the query string. Using the [QSL] flag instructs +RewriteRule to instead split +the two components using the last (right-most) question mark.

+ +

+This is useful when mapping to files that have literal question marks in +their filename. If no query string is used in the substitution, +a question mark can be appended to it in combination with this flag.

+ +

This flag is available in version 2.4.19 and later.

+ +
+ +
R|redirect

Use of the [R] flag causes a HTTP redirect to be issued to the browser. diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index c8667bfff6..5d3cffeb94 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -166,6 +166,7 @@ static const char* really_last_key = "rewrite_really_last"; #define RULEFLAG_DISCARDPATHINFO (1<<15) #define RULEFLAG_QSDISCARD (1<<16) #define RULEFLAG_END (1<<17) +#define RULEFLAG_QSLAST (1<<19) /* return code of the rewrite rule * the result may be escaped - or not @@ -724,7 +725,8 @@ 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) +static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard, + int qslast) { char *q; int split; @@ -743,7 +745,8 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard) rewritelog((r, 2, NULL, "discarding query string")); } - q = ap_strchr(r->filename, '?'); + q = qslast ? ap_strrchr(r->filename, '?') : ap_strchr(r->filename, '?'); + if (q != NULL) { char *olduri; apr_size_t len; @@ -751,7 +754,9 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard) olduri = apr_pstrdup(r->pool, r->filename); *q++ = '\0'; if (qsappend) { - r->args = apr_pstrcat(r->pool, q, "&", r->args, NULL); + if (*q) { + r->args = apr_pstrcat(r->pool, q, "&" , r->args, NULL); + } } else { r->args = apr_pstrdup(r->pool, q); @@ -3584,6 +3589,9 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg, } else if ( !strcasecmp(key, "SD") || !strcasecmp(key, "sdiscard") ) { /* qsdiscard */ cfg->flags |= RULEFLAG_QSDISCARD; + } else if ( !strcasecmp(key, "SL") + || !strcasecmp(key, "slast") ) { /* qslast */ + cfg->flags |= RULEFLAG_QSLAST; } else { ++error; @@ -4136,7 +4144,9 @@ 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); + splitout_queryargs(r, p->flags & RULEFLAG_QSAPPEND, + p->flags & RULEFLAG_QSDISCARD, + p->flags & RULEFLAG_QSLAST); /* Add the previously stripped per-directory location prefix, unless * (1) it's an absolute URL path and