You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by nd...@apache.org on 2003/03/01 19:35:51 UTC
cvs commit: httpd-2.0/modules/mappers mod_rewrite.c mod_rewrite.h
nd 2003/03/01 10:35:51
Modified: . CHANGES
modules/mappers mod_rewrite.c mod_rewrite.h
Log:
Prevent endless loops of internal redirects in mod_rewrite by
aborting after exceeding a limit of internal redirects. The
limit defaults to 10 and can be changed using the RewriteOptions
directive with the new MaxRedirects=n argument.
(The latter required some restructuring of the RewriteOptions
evaluation code).
(Documentation patch follows asap)
PR: 17462
Revision Changes Path
1.1098 +6 -1 httpd-2.0/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/httpd-2.0/CHANGES,v
retrieving revision 1.1097
retrieving revision 1.1098
diff -u -r1.1097 -r1.1098
--- CHANGES 28 Feb 2003 13:47:11 -0000 1.1097
+++ CHANGES 1 Mar 2003 18:35:50 -0000 1.1098
@@ -2,12 +2,17 @@
[Remove entries to the current 2.0 section below, when backported]
+ *) Prevent endless loops of internal redirects in mod_rewrite by
+ aborting after exceeding a limit of internal redirects. The
+ limit defaults to 10 and can be changed using the RewriteOptions
+ directive. PR 17462. [Andr� Malo]
+
*) mod_rewrite: Fix some problems reporting errors with mapping
programs (RewriteMap prg:/something). [Jeff Trawick]
*) Win32: Avoid busy wait (consuming all the CPU idle cycles) when
all worker threads are busy.
- [Igor Nazarenko <ig...@hotmail.com>]
+ [Igor Nazarenko <ig...@hotmail.com>]
*) When using Redirect in directory context, append requested query
string if there's no one supplied by configuration. PR 10961.
1.148 +106 -21 httpd-2.0/modules/mappers/mod_rewrite.c
Index: mod_rewrite.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/mappers/mod_rewrite.c,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -r1.147 -r1.148
--- mod_rewrite.c 28 Feb 2003 13:13:39 -0000 1.147
+++ mod_rewrite.c 1 Mar 2003 18:35:50 -0000 1.148
@@ -206,6 +206,7 @@
a->rewriteconds = apr_array_make(p, 2, sizeof(rewritecond_entry));
a->rewriterules = apr_array_make(p, 2, sizeof(rewriterule_entry));
a->server = s;
+ a->redirect_limit = 0; /* unset (use default) */
return (void *)a;
}
@@ -222,6 +223,9 @@
a->state = overrides->state;
a->options = overrides->options;
a->server = overrides->server;
+ a->redirect_limit = overrides->redirect_limit
+ ? overrides->redirect_limit
+ : base->redirect_limit;
if (a->options & OPTION_INHERIT) {
/*
@@ -278,6 +282,7 @@
a->baseurl = NULL;
a->rewriteconds = apr_array_make(p, 2, sizeof(rewritecond_entry));
a->rewriterules = apr_array_make(p, 2, sizeof(rewriterule_entry));
+ a->redirect_limit = 0; /* unset (use server config) */
if (path == NULL) {
a->directory = NULL;
@@ -308,6 +313,9 @@
a->options = overrides->options;
a->directory = overrides->directory;
a->baseurl = overrides->baseurl;
+ a->redirect_limit = overrides->redirect_limit
+ ? overrides->redirect_limit
+ : base->redirect_limit;
if (a->options & OPTION_INHERIT) {
a->rewriteconds = apr_array_append(p, overrides->rewriteconds,
@@ -351,34 +359,48 @@
static const char *cmd_rewriteoptions(cmd_parms *cmd,
void *in_dconf, const char *option)
{
- rewrite_perdir_conf *dconf = in_dconf;
- rewrite_server_conf *sconf;
- const char *err;
+ int options = 0, limit = 0;
+ char *w;
- sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
+ while (*option) {
+ w = ap_getword_conf(cmd->pool, &option);
- if (cmd->path == NULL) { /* is server command */
- err = cmd_rewriteoptions_setoption(cmd->pool,
- &(sconf->options), option);
- }
- else { /* is per-directory command */
- err = cmd_rewriteoptions_setoption(cmd->pool,
- &(dconf->options), option);
+ if (!strcasecmp(w, "inherit")) {
+ options |= OPTION_INHERIT;
+ }
+ else if (!strncasecmp(w, "MaxRedirects=", 13)) {
+ limit = atoi(&w[13]);
+ if (limit <= 0) {
+ return "RewriteOptions: MaxRedirects takes a number greater "
+ "than zero.";
+ }
+ }
+ else if (!strcasecmp(w, "MaxRedirects")) { /* be nice */
+ return "RewriteOptions: MaxRedirects has the format MaxRedirects"
+ "=n.";
+ }
+ else {
+ return apr_pstrcat(cmd->pool, "RewriteOptions: unknown option '",
+ w, "'", NULL);
+ }
}
- return err;
-}
+ /* put it into the appropriate config */
+ if (cmd->path == NULL) { /* is server command */
+ rewrite_server_conf *conf =
+ ap_get_module_config(cmd->server->module_config,
+ &rewrite_module);
-static const char *cmd_rewriteoptions_setoption(apr_pool_t *p, int *options,
- const char *name)
-{
- if (strcasecmp(name, "inherit") == 0) {
- *options |= OPTION_INHERIT;
+ conf->options |= options;
+ conf->redirect_limit = limit;
}
- else {
- return apr_pstrcat(p, "RewriteOptions: unknown option '",
- name, "'", NULL);
+ else { /* is per-directory command */
+ rewrite_perdir_conf *conf = in_dconf;
+
+ conf->options |= options;
+ conf->redirect_limit = limit;
}
+
return NULL;
}
@@ -1656,12 +1678,75 @@
return DECLINED;
}
+ if (is_redirect_limit_exceeded(r)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "mod_rewrite: maximum number of internal redirects "
+ "reached. Assuming configuration error. Use "
+ "'RewriteOptions MaxRedirects' to increase the limit "
+ "if neccessary.");
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
/* now do the internal redirect */
ap_internal_redirect(apr_pstrcat(r->pool, r->filename+9,
r->args ? "?" : NULL, r->args, NULL), r);
/* and return gracefully */
return OK;
+}
+
+/*
+ * check whether redirect limit is reached
+ */
+static int is_redirect_limit_exceeded(request_rec *r)
+{
+ request_rec *top = r;
+ rewrite_request_conf *reqc;
+ rewrite_perdir_conf *dconf;
+
+ /* we store it in the top request */
+ while (top->main) {
+ top = top->main;
+ }
+ while (top->prev) {
+ top = top->prev;
+ }
+
+ /* fetch our config */
+ reqc = (rewrite_request_conf *) ap_get_module_config(top->request_config,
+ &rewrite_module);
+
+ /* no config there? create one. */
+ if (!reqc) {
+ rewrite_server_conf *sconf;
+
+ reqc = apr_palloc(top->pool, sizeof(rewrite_request_conf));
+ sconf = ap_get_module_config(r->server->module_config, &rewrite_module);
+
+ reqc->redirects = 0;
+ reqc->redirect_limit = sconf->redirect_limit
+ ? sconf->redirect_limit
+ : REWRITE_REDIRECT_LIMIT;
+
+ /* associate it with this request */
+ ap_set_module_config(top->request_config, &rewrite_module, reqc);
+ }
+
+ /* allow to change the limit during redirects. */
+ dconf = (rewrite_perdir_conf *)ap_get_module_config(r->per_dir_config,
+ &rewrite_module);
+
+ /* 0 == unset; take server conf ... */
+ if (dconf->redirect_limit) {
+ reqc->redirect_limit = dconf->redirect_limit;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "mod_rewrite's internal redirect status: %d/%d.",
+ reqc->redirects, reqc->redirect_limit);
+
+ /* and now give the caller a hint */
+ return (reqc->redirects++ >= reqc->redirect_limit);
}
1.43 +13 -2 httpd-2.0/modules/mappers/mod_rewrite.h
Index: mod_rewrite.h
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/mappers/mod_rewrite.h,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -r1.42 -r1.43
--- mod_rewrite.h 27 Feb 2003 02:50:04 -0000 1.42
+++ mod_rewrite.h 1 Mar 2003 18:35:50 -0000 1.43
@@ -212,6 +212,8 @@
#define MAX_NMATCH 10
+/* default maximum number of internal redirects */
+#define REWRITE_REDIRECT_LIMIT 10
/*
@@ -271,6 +273,7 @@
apr_array_header_t *rewriteconds; /* the RewriteCond entries (temporary) */
apr_array_header_t *rewriterules; /* the RewriteRule entries */
server_rec *server; /* the corresponding server indicator */
+ int redirect_limit; /* maximum number of internal redirects */
} rewrite_server_conf;
@@ -284,9 +287,18 @@
apr_array_header_t *rewriterules; /* the RewriteRule entries */
char *directory; /* the directory where it applies */
const char *baseurl; /* the base-URL where it applies */
+ int redirect_limit; /* maximum number of internal redirects */
} rewrite_perdir_conf;
+ /* the per-request configuration
+ */
+typedef struct {
+ int redirects; /* current number of redirects */
+ int redirect_limit; /* maximum number of redirects */
+} rewrite_request_conf;
+
+
/* the cache structures,
* a 4-way hash apr_table_t with LRU functionality
*/
@@ -343,8 +355,6 @@
static const char *cmd_rewriteoptions(cmd_parms *cmd,
void *dconf,
const char *option);
-static const char *cmd_rewriteoptions_setoption(apr_pool_t *p, int *options,
- const char *name);
static const char *cmd_rewritelog (cmd_parms *cmd, void *dconf, const char *a1);
static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, const char *a1);
static const char *cmd_rewritemap (cmd_parms *cmd, void *dconf,
@@ -467,6 +477,7 @@
static void add_env_variable(request_rec *r, char *s);
static void add_cookie(request_rec *r, char *s);
static int subreq_ok(request_rec *r);
+static int is_redirect_limit_exceeded(request_rec *r);
/* Lexicographic Comparison */
static int compare_lexicography(char *cpNum1, char *cpNum2);