summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorEric Covener <covener@apache.org>2017-06-16 17:13:03 +0200
committerEric Covener <covener@apache.org>2017-06-16 17:13:03 +0200
commit4fa0f6c103ae53d2cb5988303b99da35cf7d9dc9 (patch)
tree55375a4253fa836b152820279efba020cb885308 /modules
parentQuiet spurious gcc warning in ap_parse_form_data ("'escaped_char[0]' may be (diff)
downloadapache2-4fa0f6c103ae53d2cb5988303b99da35cf7d9dc9.tar.xz
apache2-4fa0f6c103ae53d2cb5988303b99da35cf7d9dc9.zip
add RewriteOptions LongURLOptimization
Variable expansion in RewriteCond causes strings to be duplicated out of r->pool. If the variables are long and many conditions are evaluated, r->pool can get seriously bloated. Clear the memory used for variable expansion for each set of conditons once the set of conditions fails to match. edit: revised in 1799261 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1798938 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r--modules/mappers/mod_rewrite.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 67d692a71b..55a7b32cb8 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -203,6 +203,7 @@ static const char* really_last_key = "rewrite_really_last";
#define OPTION_IGNORE_INHERIT (1<<8)
#define OPTION_IGNORE_CONTEXT_INFO (1<<9)
#define OPTION_LEGACY_PREFIX_DOCROOT (1<<10)
+#define OPTION_LONGOPT (1<<11)
#ifndef RAND_MAX
#define RAND_MAX 32767
@@ -397,6 +398,7 @@ typedef struct {
char *perdir;
backrefinfo briRR;
backrefinfo briRC;
+ apr_pool_t *temp_pool;
} rewrite_ctx;
/*
@@ -2286,14 +2288,13 @@ static APR_INLINE char *find_char_in_curlies(char *s, int c)
* are interpreted by a later expansion, producing results that
* were not intended by the administrator.
*/
-static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
+static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry, apr_pool_t *pool)
{
result_list *result, *current;
result_list sresult[SMALL_EXPANSION];
unsigned spc = 0;
apr_size_t span, inputlen, outlen;
char *p, *c;
- apr_pool_t *pool = ctx->r->pool;
span = strcspn(input, "\\$%");
inputlen = strlen(input);
@@ -2398,10 +2399,10 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
}
/* reuse of key variable as result */
- key = lookup_map(ctx->r, map, do_expand(key, ctx, entry));
+ key = lookup_map(ctx->r, map, do_expand(key, ctx, entry, pool));
if (!key && dflt && *dflt) {
- key = do_expand(dflt, ctx, entry);
+ key = do_expand(dflt, ctx, entry, pool);
}
if (key) {
@@ -2499,7 +2500,7 @@ static void do_expand_env(data_item *env, rewrite_ctx *ctx)
char *name, *val;
while (env) {
- name = do_expand(env->data, ctx, NULL);
+ name = do_expand(env->data, ctx, NULL, ctx->r->pool);
if (*name == '!') {
name++;
apr_table_unset(ctx->r->subprocess_env, name);
@@ -2626,7 +2627,7 @@ static void add_cookie(request_rec *r, char *s)
static void do_expand_cookie(data_item *cookie, rewrite_ctx *ctx)
{
while (cookie) {
- add_cookie(ctx->r, do_expand(cookie->data, ctx, NULL));
+ add_cookie(ctx->r, do_expand(cookie->data, ctx, NULL, ctx->r->pool));
cookie = cookie->next;
}
@@ -3037,6 +3038,9 @@ static const char *cmd_rewriteoptions(cmd_parms *cmd,
else if (!strcasecmp(w, "legacyprefixdocroot")) {
options |= OPTION_LEGACY_PREFIX_DOCROOT;
}
+ else if (!strcasecmp(w, "LongURLOptimization")) {
+ options |= OPTION_LONGOPT;
+ }
else {
return apr_pstrcat(cmd->pool, "RewriteOptions: unknown option '",
w, "'", NULL);
@@ -3867,7 +3871,7 @@ static APR_INLINE int compare_lexicography(char *a, char *b)
/*
* Apply a single rewriteCond
*/
-static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx)
+static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx, apr_pool_t *pool)
{
char *input = NULL;
apr_finfo_t sb;
@@ -3877,7 +3881,7 @@ static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx)
int basis;
if (p->ptype != CONDPAT_AP_EXPR)
- input = do_expand(p->input, ctx, NULL);
+ input = do_expand(p->input, ctx, NULL, pool);
switch (p->ptype) {
case CONDPAT_FILE_EXISTS:
@@ -4041,7 +4045,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
char *expanded;
if (p->forced_mimetype) {
- expanded = do_expand(p->forced_mimetype, ctx, p);
+ expanded = do_expand(p->forced_mimetype, ctx, p, ctx->r->pool);
if (*expanded) {
ap_str_tolower(expanded);
@@ -4055,7 +4059,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
}
if (p->forced_handler) {
- expanded = do_expand(p->forced_handler, ctx, p);
+ expanded = do_expand(p->forced_handler, ctx, p, ctx->r->pool);
if (*expanded) {
ap_str_tolower(expanded);
@@ -4152,7 +4156,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
for (i = 0; i < rewriteconds->nelts; ++i) {
rewritecond_entry *c = &conds[i];
- rc = apply_rewrite_cond(c, ctx);
+ rc = apply_rewrite_cond(c, ctx, ctx->temp_pool ? ctx->temp_pool : r->pool);
/*
* Reset vary_this if the novary flag is set for this condition.
*/
@@ -4174,6 +4178,9 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
}
}
else if (!rc) {
+ if (ctx->temp_pool) {
+ apr_pool_clear(ctx->temp_pool);
+ }
return 0;
}
@@ -4191,7 +4198,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
/* expand the result */
if (!(p->flags & RULEFLAG_NOSUB)) {
- newuri = do_expand(p->output, ctx, p);
+ newuri = do_expand(p->output, ctx, p, ctx->r->pool);
rewritelog((r, 2, ctx->perdir, "rewrite '%s' -> '%s'", ctx->uri,
newuri));
}
@@ -4329,11 +4336,20 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules,
int s;
rewrite_ctx *ctx;
int round = 1;
+ rewrite_server_conf *sconf = ap_get_module_config(
+ r->server->module_config, &rewrite_module);
ctx = apr_palloc(r->pool, sizeof(*ctx));
ctx->perdir = perdir;
ctx->r = r;
+ if (sconf->options & OPTION_LONGOPT) {
+ apr_pool_create(&(ctx->temp_pool), r->pool);
+ }
+ else {
+ ctx->temp_pool = NULL;
+ }
+
/*
* Iterate over all existing rules
*/