Commit 5253bcbe authored by Eric Covener's avatar Eric Covener
Browse files

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
parent 685f98cc
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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. 
+0 −7
Original line number Diff line number Diff line
@@ -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 ]

+9 −0
Original line number Diff line number Diff line
@@ -1365,6 +1365,15 @@ cannot use <code>$N</code> in the substitution string!
        <em><a href="../rewrite/flags.html#flag_qsd">details
        ...</a></em></td>
    </tr>
    <tr>
        <td>qslast|QSL</td>
        <td>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.
        <em><a href="../rewrite/flags.html#flag_qsl">details
        ...</a></em></td>
    </tr>
 
    <tr>
        <td>redirect|R[=<em>code</em>]</td>
        <td>Forces an external redirect, optionally with the specified
+17 −0
Original line number Diff line number Diff line
@@ -628,6 +628,23 @@ URI.

</section>

<section id="flag_qsl"><title>QSL|qslast</title>
<p>
By default, the first (left-most) question mark in the substitution
delimits the path from the query string.  Using the [QSL] flag instructs
<directive module="mod_rewrite">RewriteRule</directive> to instead split
the two components using the last (right-most) question mark.  </p>

<p>
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.  </p>

<p> This flag is available in version 2.4.19 and later.</p>

</section>


<section id="flag_r"><title>R|redirect</title>
<p>
Use of the [R] flag causes a HTTP redirect to be issued to the browser.
+14 −4
Original line number Diff line number Diff line
@@ -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,8 +754,10 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard)
        olduri = apr_pstrdup(r->pool, r->filename);
        *q++ = '\0';
        if (qsappend) {
            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