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 2017/06/16 15:13:03 UTC

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

Author: covener
Date: Fri Jun 16 15:13:03 2017
New Revision: 1798938

URL: http://svn.apache.org/viewvc?rev=1798938&view=rev
Log:
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.



Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/mod_rewrite.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=1798938&r1=1798937&r2=1798938&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Fri Jun 16 15:13:03 2017
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_rewrite: Add 'RewriteOptions LongURLOptimization' to free memory
+     from each set of unmatched rewrite conditions.
+     [Eric Covener]
+
   *) Allow the argument to <IfFile>, <IfDefine>, <IfSection>, <IfDirective>, 
      and <IfModule> to be quoted.  This is primarily for the benefit of
      <IfFile>. [Eric Covener]

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=1798938&r1=1798937&r2=1798938&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_rewrite.xml Fri Jun 16 15:13:03 2017
@@ -291,6 +291,13 @@ LogLevel alert rewrite:trace3
          URL.  Available in 2.4.26 and later.</p>
       </dd>
 
+      <dt><code>LongURLOptimization</code></dt>
+      <dd>
+      <p>This option reduces memory usage of long, unoptimized rule sets 
+         that repeatedly expand long values in RewriteCond and RewriteRule
+         variables. Available in 2.5 and later.</p>
+      </dd>
+
       </dl>
 </usage>
 

Modified: httpd/httpd/trunk/modules/mappers/mod_rewrite.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/mappers/mod_rewrite.c?rev=1798938&r1=1798937&r2=1798938&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/mappers/mod_rewrite.c (original)
+++ httpd/httpd/trunk/modules/mappers/mod_rewrite.c Fri Jun 16 15:13:03 2017
@@ -203,6 +203,7 @@ static const char* really_last_key = "re
 #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_cur
  * 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, rewr
                     }
 
                     /* 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
     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, c
 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(cm
         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_lexicograp
 /*
  * 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(rewritecon
     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_handle
     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_handle
     }
 
     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(rewriterul
     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(rewriterul
             }
         }
         else if (!rc) {
+            if (ctx->temp_pool) { 
+                apr_pool_clear(ctx->temp_pool);
+            }
             return 0;
         }
 
@@ -4191,7 +4198,7 @@ static int apply_rewrite_rule(rewriterul
 
     /* 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_re
     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
      */