You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2007/10/29 14:08:45 UTC
svn commit: r589615 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS
docs/manual/mod/mod_rewrite.xml modules/mappers/mod_rewrite.c
Author: jim
Date: Mon Oct 29 06:08:43 2007
New Revision: 589615
URL: http://svn.apache.org/viewvc?rev=589615&view=rev
Log:
Merge r573831, r589343 from trunk:
Add option to escape backreferences in RewriteRule.
PR 34602 and PR 39746
Patch by Guenther Gsenger
Update r573831 to avoid duplicating URL-escaping code.
Ref. http://www.mail-archive.com/dev@httpd.apache.org/msg38532.html
Submitted by: niq
Reviewed by: jim
Modified:
httpd/httpd/branches/2.2.x/CHANGES
httpd/httpd/branches/2.2.x/STATUS
httpd/httpd/branches/2.2.x/docs/manual/mod/mod_rewrite.xml
httpd/httpd/branches/2.2.x/modules/mappers/mod_rewrite.c
Modified: httpd/httpd/branches/2.2.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?rev=589615&r1=589614&r2=589615&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.2.x/CHANGES [utf-8] Mon Oct 29 06:08:43 2007
@@ -1,5 +1,8 @@
- -*- coding: utf-8 -*-
+ -*- coding: utf-8 -*-
Changes with Apache 2.2.7
+
+ *) mod_rewrite: Add option to suppress URL unescaping
+ PR 34602 [Guenther Gsenger <guenther.gsenger gmail.com>]
*) mpm_winnt: Eliminate wait_for_many_objects. Allows the clean
shutdown of the server when the MaxClients is higher then 257,
Modified: httpd/httpd/branches/2.2.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/STATUS?rev=589615&r1=589614&r2=589615&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/STATUS (original)
+++ httpd/httpd/branches/2.2.x/STATUS Mon Oct 29 06:08:43 2007
@@ -79,12 +79,6 @@
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- * mod_rewrite: Add option to suppress URL unescaping
- PR 34602
- http://svn.apache.org/viewvc?view=rev&revision=573831
- http://svn.apache.org/viewvc?view=rev&revision=589343
- +1: niq, rpluem, jim
-
* HTTP protocol: Add "DefaultType none" option.
PR 13986 and PR 16139
http://svn.apache.org/viewvc?view=rev&revision=579991 (code)
Modified: httpd/httpd/branches/2.2.x/docs/manual/mod/mod_rewrite.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/docs/manual/mod/mod_rewrite.xml?rev=589615&r1=589614&r2=589615&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/docs/manual/mod/mod_rewrite.xml (original)
+++ httpd/httpd/branches/2.2.x/docs/manual/mod/mod_rewrite.xml Mon Oct 29 06:08:43 2007
@@ -1223,6 +1223,21 @@
brackets, of any of the following flags: </p>
<dl>
+ <dt>'<code>B</code>' (escape backreferences)</dt>
+ <dd><p>Apache has to unescape URLs before mapping them,
+ so backreferences will be unescaped at the time they are applied.
+ Using the B flag, non-alphanumeric characters in backreferences
+ will be escaped. For example, consider the rule:</p>
+ <pre><code> RewriteRule RewriteRule ^(.*)$ index.php?show=$1 </code></pre>
+ <p>This will map <code>/C++</code> to <code>index.php?show=C++</code>.
+ But it will also map <code>/C%2b%2b</code> to
+ <code>index.php?show=C++</code>, because the <code>%2b</code>
+ has been unescaped. With the B flag, it will instead map to
+ <code>index.php?show=>/C%2b%2b</code>.</p>
+ <p>This escaping is particularly necessary in a proxy situation,
+ when the backend may break if presented with an unescaped URL.</p>
+ </dd>
+
<dt>'<code>chain|C</code>'
(chained with next rule)</dt><dd>
This flag chains the current rule with the next rule
@@ -1236,8 +1251,7 @@
when you let an external redirect happen (where the
``<code>.www</code>'' part should not occur!).</dd>
- <dt>
- '<code>cookie|CO=</code><em>NAME</em>:<em>VAL</em>:<em>domain</em>[:<em>lifetime</em>[:<em>path</em>]]'
+ <dt>'<code>cookie|CO=</code><em>NAME</em>:<em>VAL</em>:<em>domain</em>[:<em>lifetime</em>[:<em>path</em>]]'
(set cookie)</dt><dd>
This sets a cookie in the client's browser. The cookie's name
is specified by <em>NAME</em> and the value is
Modified: httpd/httpd/branches/2.2.x/modules/mappers/mod_rewrite.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/mappers/mod_rewrite.c?rev=589615&r1=589614&r2=589615&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/mappers/mod_rewrite.c (original)
+++ httpd/httpd/branches/2.2.x/modules/mappers/mod_rewrite.c Mon Oct 29 06:08:43 2007
@@ -145,6 +145,7 @@
#define RULEFLAG_NOESCAPE 1<<11
#define RULEFLAG_NOSUB 1<<12
#define RULEFLAG_STATUS 1<<13
+#define RULEFLAG_ESCAPEBACKREF 1<<14
/* return code of the rewrite rule
* the result may be escaped - or not
@@ -2079,7 +2080,7 @@
* are interpreted by a later expansion, producing results that
* were not intended by the administrator.
*/
-static char *do_expand(char *input, rewrite_ctx *ctx)
+static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
{
result_list *result, *current;
result_list sresult[SMALL_EXPANSION];
@@ -2191,10 +2192,10 @@
}
/* reuse of key variable as result */
- key = lookup_map(ctx->r, map, do_expand(key, ctx));
+ key = lookup_map(ctx->r, map, do_expand(key, ctx, entry));
if (!key && dflt && *dflt) {
- key = do_expand(dflt, ctx);
+ key = do_expand(dflt, ctx, entry);
}
if (key) {
@@ -2218,9 +2219,22 @@
if (bri->source && n < AP_MAX_REG_MATCH
&& bri->regmatch[n].rm_eo > bri->regmatch[n].rm_so) {
span = bri->regmatch[n].rm_eo - bri->regmatch[n].rm_so;
+ if (entry && (entry->flags & RULEFLAG_ESCAPEBACKREF)) {
+ /* escape the backreference */
+ char *tmp2, *tmp;
+ tmp = apr_pstrndup(pool, bri->source + bri->regmatch[n].rm_so, span);
+ tmp2 = ap_escape_path_segment(pool, tmp);
+ rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
+ tmp, tmp2));
- current->len = span;
- current->string = bri->source + bri->regmatch[n].rm_so;
+ current->len = span = strlen(tmp2);
+ current->string = tmp2;
+ }
+ else {
+ current->len = span;
+ current->string = bri->source + bri->regmatch[n].rm_so;
+ }
+
outlen += span;
}
@@ -2280,7 +2294,7 @@
char *name, *val;
while (env) {
- name = do_expand(env->data, ctx);
+ name = do_expand(env->data, ctx, NULL);
if ((val = ap_strchr(name, ':')) != NULL) {
*val++ = '\0';
@@ -2369,7 +2383,7 @@
static void do_expand_cookie(data_item *cookie, rewrite_ctx *ctx)
{
while (cookie) {
- add_cookie(ctx->r, do_expand(cookie->data, ctx));
+ add_cookie(ctx->r, do_expand(cookie->data, ctx, NULL));
cookie = cookie->next;
}
@@ -3149,6 +3163,15 @@
int error = 0;
switch (*key++) {
+ case 'b':
+ case 'B':
+ if (!*key || !strcasecmp(key, "ackrefescaping")) {
+ cfg->flags |= RULEFLAG_ESCAPEBACKREF;
+ }
+ else {
+ ++error;
+ }
+ break;
case 'c':
case 'C':
if (!*key || !strcasecmp(key, "hain")) { /* chain */
@@ -3350,7 +3373,6 @@
++error;
}
break;
-
default:
++error;
break;
@@ -3486,7 +3508,7 @@
*/
static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx)
{
- char *input = do_expand(p->input, ctx);
+ char *input = do_expand(p->input, ctx, NULL);
apr_finfo_t sb;
request_rec *rsub, *r = ctx->r;
ap_regmatch_t regmatch[AP_MAX_REG_MATCH];
@@ -3609,7 +3631,7 @@
char *expanded;
if (p->forced_mimetype) {
- expanded = do_expand(p->forced_mimetype, ctx);
+ expanded = do_expand(p->forced_mimetype, ctx, p);
if (*expanded) {
ap_str_tolower(expanded);
@@ -3623,7 +3645,7 @@
}
if (p->forced_handler) {
- expanded = do_expand(p->forced_handler, ctx);
+ expanded = do_expand(p->forced_handler, ctx, p);
if (*expanded) {
ap_str_tolower(expanded);
@@ -3755,7 +3777,7 @@
/* expand the result */
if (!(p->flags & RULEFLAG_NOSUB)) {
- newuri = do_expand(p->output, ctx);
+ newuri = do_expand(p->output, ctx, p);
rewritelog((r, 2, ctx->perdir, "rewrite '%s' -> '%s'", ctx->uri,
newuri));
}
@@ -3802,6 +3824,7 @@
* ourself).
*/
if (p->flags & RULEFLAG_PROXY) {
+ /* PR#39746: Escaping things here gets repeated in mod_proxy */
fully_qualify_uri(r);
rewritelog((r, 2, ctx->perdir, "forcing proxy-throughput with %s",