You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by co...@apache.org on 2016/03/08 20:18:15 UTC

svn commit: r1734125 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_rewrite.xml docs/manual/rewrite/flags.xml modules/mappers/mod_rewrite.c

Author: covener
Date: Tue Mar  8 19:18:15 2016
New Revision: 1734125

URL: http://svn.apache.org/viewvc?rev=1734125&view=rev
Log:
mod_rewrite: Add QSL|qslast flag to allow rewrites to files with 
literal question marks in their names. 

PR 58777. 



Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml
    httpd/httpd/trunk/docs/manual/rewrite/flags.xml
    httpd/httpd/trunk/modules/mappers/mod_rewrite.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1734125&r1=1734124&r2=1734125&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Tue Mar  8 19:18:15 2016
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_rewrite: Add QSL|qslast flag to allow rewrites to files with 
+     literal question marks in their names. PR 58777. [Eric Covener]
+
   *) core: Split ap_create_request() from ap_read_request(). [Graham Leggett]
 
   *) mod_ssl: Don't lose track of the SSL context if the ssl_run_pre_handshake()

Modified: httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml?rev=1734125&r1=1734124&r2=1734125&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml Tue Mar  8 19:18:15 2016
@@ -1365,6 +1365,14 @@ cannot use <code>$N</code> in the substi
         ...</a></em></td>
     </tr>
     <tr>
+        <td>qslast|QSA</td>
+        <td>Interpret the last (right-most) question mark as the query string
+            delimeter, instead of the first (left-most) as normally used.  
+        <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
         HTTP status code. <em><a

Modified: httpd/httpd/trunk/docs/manual/rewrite/flags.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/rewrite/flags.xml?rev=1734125&r1=1734124&r2=1734125&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/rewrite/flags.xml (original)
+++ httpd/httpd/trunk/docs/manual/rewrite/flags.xml Tue Mar  8 19:18:15 2016
@@ -641,6 +641,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.5.0 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.

Modified: httpd/httpd/trunk/modules/mappers/mod_rewrite.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/mappers/mod_rewrite.c?rev=1734125&r1=1734124&r2=1734125&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/mappers/mod_rewrite.c (original)
+++ httpd/httpd/trunk/modules/mappers/mod_rewrite.c Tue Mar  8 19:18:15 2016
@@ -171,6 +171,7 @@ static const char* really_last_key = "re
 #define RULEFLAG_QSDISCARD          (1<<16)
 #define RULEFLAG_END                (1<<17)
 #define RULEFLAG_ESCAPENOPLUS       (1<<18)
+#define RULEFLAG_QSLAST             (1<<19)
 
 /* return code of the rewrite rule
  * the result may be escaped - or not
@@ -752,7 +753,8 @@ static char *escape_absolute_uri(apr_poo
  * 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;
@@ -771,7 +773,8 @@ static void splitout_queryargs(request_r
         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;
@@ -779,7 +782,9 @@ static void splitout_queryargs(request_r
         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);
@@ -3638,6 +3643,9 @@ static const char *cmd_rewriterule_setfl
         } 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;
@@ -4191,7 +4199,9 @@ static int apply_rewrite_rule(rewriterul
         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