Return-Path: X-Original-To: apmail-httpd-cvs-archive@www.apache.org Delivered-To: apmail-httpd-cvs-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 25ACE11567 for ; Thu, 3 Apr 2014 21:53:50 +0000 (UTC) Received: (qmail 87508 invoked by uid 500); 3 Apr 2014 21:53:47 -0000 Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 87430 invoked by uid 500); 3 Apr 2014 21:53:47 -0000 Mailing-List: contact cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 87284 invoked by uid 99); 3 Apr 2014 21:53:39 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 03 Apr 2014 21:53:39 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 03 Apr 2014 21:53:37 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 9A0FE238889B; Thu, 3 Apr 2014 21:53:14 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1584417 - in /httpd/httpd/trunk: docs/manual/rewrite/flags.xml modules/mappers/mod_rewrite.c Date: Thu, 03 Apr 2014 21:53:14 -0000 To: cvs@httpd.apache.org From: covener@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140403215314.9A0FE238889B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: covener Date: Thu Apr 3 21:53:14 2014 New Revision: 1584417 URL: http://svn.apache.org/r1584417 Log: allow users to workaround the over-agressive backreference escaping by selecting the characters to escape. Modified: httpd/httpd/trunk/docs/manual/rewrite/flags.xml httpd/httpd/trunk/modules/mappers/mod_rewrite.c Modified: httpd/httpd/trunk/docs/manual/rewrite/flags.xml URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/rewrite/flags.xml?rev=1584417&r1=1584416&r2=1584417&view=diff ============================================================================== --- httpd/httpd/trunk/docs/manual/rewrite/flags.xml (original) +++ httpd/httpd/trunk/docs/manual/rewrite/flags.xml Thu Apr 3 21:53:14 2014 @@ -67,8 +67,9 @@ of how you might use them.

B (escape backreferences)

The [B] flag instructs RewriteRule to escape non-alphanumeric -characters before applying the transformation. -

+characters before applying the transformation.

+

In 2.4.10 and later, you can limit the escaping to specific characters +in backreferences by listing them: [B=#?;]

mod_rewrite has to unescape URLs before mapping them, so backreferences are unescaped at the time they are applied. @@ -95,6 +96,9 @@ returns a 404 if it sees one.

This escaping is particularly necessary in a proxy situation, when the backend may break if presented with an unescaped URL.

+

An alternative to this flag is using a RewriteCond to capture against %{THE_REQUEST} which will capture +strings in the encoded form.

C|chain Modified: httpd/httpd/trunk/modules/mappers/mod_rewrite.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/mappers/mod_rewrite.c?rev=1584417&r1=1584416&r2=1584417&view=diff ============================================================================== --- httpd/httpd/trunk/modules/mappers/mod_rewrite.c (original) +++ httpd/httpd/trunk/modules/mappers/mod_rewrite.c Thu Apr 3 21:53:14 2014 @@ -319,6 +319,7 @@ typedef struct { data_item *cookie; /* added cookies */ int skip; /* number of next rules to skip */ int maxrounds; /* limit on number of loops with N flag */ + char *escapes; /* specific backref escapes */ } rewriterule_entry; typedef struct { @@ -419,7 +420,7 @@ static const char *rewritemap_mutex_type /* Optional functions imported from mod_ssl when loaded: */ static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *rewrite_ssl_lookup = NULL; static APR_OPTIONAL_FN_TYPE(ssl_is_https) *rewrite_is_https = NULL; -static char *escape_uri(apr_pool_t *p, const char *path); +static char *escape_uri(apr_pool_t *p, const char *path, const char *escapeme); /* * +-------------------------------------------------------+ @@ -631,21 +632,36 @@ static APR_INLINE unsigned char *c2x(uns * Escapes a uri in a similar way as php's urlencode does. * Based on ap_os_escape_path in server/util.c */ -static char *escape_uri(apr_pool_t *p, const char *path) { +static char *escape_uri(apr_pool_t *p, const char *path, const char *escapeme) { char *copy = apr_palloc(p, 3 * strlen(path) + 3); const unsigned char *s = (const unsigned char *)path; unsigned char *d = (unsigned char *)copy; unsigned c; while ((c = *s)) { - if (apr_isalnum(c) || c == '_') { - *d++ = c; - } - else if (c == ' ') { - *d++ = '+'; + if (!escapeme) { + if (apr_isalnum(c) || c == '_') { + *d++ = c; + } + else if (c == ' ') { + *d++ = '+'; + } + else { + d = c2x(c, '%', d); + } } - else { - d = c2x(c, '%', d); + else { + const char *esc = escapeme; + while (*esc) { + if (c == *esc) { + d = c2x(c, '%', d); + break; + } + ++esc; + } + if (!*esc) { + *d++ = c; + } } ++s; } @@ -2368,7 +2384,7 @@ static char *do_expand(char *input, rewr /* escape the backreference */ char *tmp2, *tmp; tmp = apr_pstrmemdup(pool, bri->source + bri->regmatch[n].rm_so, span); - tmp2 = escape_uri(pool, tmp); + tmp2 = escape_uri(pool, tmp, entry->escapes); rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'", tmp, tmp2)); @@ -3415,6 +3431,9 @@ static const char *cmd_rewriterule_setfl case 'B': if (!*key || !strcasecmp(key, "ackrefescaping")) { cfg->flags |= RULEFLAG_ESCAPEBACKREF; + if (val && *val) { + cfg->escapes = val; + } } else { ++error;