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/19 15:01:08 UTC
cvs commit: apache-1.3/src/modules/standard mod_rewrite.c mod_rewrite.h
nd 2003/03/19 06:01:08
Modified: src CHANGES
src/modules/standard mod_rewrite.c mod_rewrite.h
Log:
backport from 2.x:
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).
PR: 17462
Reviewed by: Will Rowe, Ian Holsman
Revision Changes Path
1.1884 +5 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.1883
retrieving revision 1.1884
diff -u -r1.1883 -r1.1884
--- CHANGES 28 Feb 2003 13:36:03 -0000 1.1883
+++ CHANGES 19 Mar 2003 14:01:05 -0000 1.1884
@@ -1,5 +1,10 @@
Changes with Apache 1.3.28
+ *) backport from 2.x series: 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]
+
*) Use the correct locations of srm.conf and access.conf when tailoring
the httpd.conf during the install process. PR 9446.
[Stanislav Brabec <ut...@penguin.cz>]
1.183 +107 -22 apache-1.3/src/modules/standard/mod_rewrite.c
Index: mod_rewrite.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_rewrite.c,v
retrieving revision 1.182
retrieving revision 1.183
diff -u -r1.182 -r1.183
--- mod_rewrite.c 27 Feb 2003 03:47:37 -0000 1.182
+++ mod_rewrite.c 19 Mar 2003 14:01:07 -0000 1.183
@@ -252,6 +252,7 @@
a->rewriteconds = ap_make_array(p, 2, sizeof(rewritecond_entry));
a->rewriterules = ap_make_array(p, 2, sizeof(rewriterule_entry));
a->server = s;
+ a->redirect_limit = 0; /* unset (use default) */
return (void *)a;
}
@@ -267,6 +268,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) {
/*
@@ -323,6 +327,7 @@
a->baseurl = NULL;
a->rewriteconds = ap_make_array(p, 2, sizeof(rewritecond_entry));
a->rewriterules = ap_make_array(p, 2, sizeof(rewriterule_entry));
+ a->redirect_limit = 0; /* unset (use server config) */
if (path == NULL) {
a->directory = NULL;
@@ -353,6 +358,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 = ap_append_arrays(p, overrides->rewriteconds,
@@ -395,36 +403,50 @@
}
static const char *cmd_rewriteoptions(cmd_parms *cmd,
- rewrite_perdir_conf *dconf, char *option)
+ void *in_dconf, const char *option)
{
- rewrite_server_conf *sconf;
- const char *err;
+ int options = 0, limit = 0;
+ char *w;
- sconf = (rewrite_server_conf *)
- 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 ap_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(pool *p, int *options,
- char *name)
-{
- if (strcasecmp(name, "inherit") == 0) {
- *options |= OPTION_INHERIT;
+ conf->options |= options;
+ conf->redirect_limit = limit;
}
- else {
- return ap_pstrcat(p, "RewriteOptions: unknown option '",
- name, "'\n", NULL);
+ else { /* is per-directory command */
+ rewrite_perdir_conf *conf = in_dconf;
+
+ conf->options |= options;
+ conf->redirect_limit = limit;
}
+
return NULL;
}
@@ -1598,12 +1620,75 @@
return DECLINED;
}
+ if (is_redirect_limit_exceeded(r)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 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(ap_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 = ap_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|APLOG_NOERRNO, 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.84 +15 -4 apache-1.3/src/modules/standard/mod_rewrite.h
Index: mod_rewrite.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_rewrite.h,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -r1.83 -r1.84
--- mod_rewrite.h 3 Feb 2003 17:13:29 -0000 1.83
+++ mod_rewrite.h 19 Mar 2003 14:01:08 -0000 1.84
@@ -255,6 +255,9 @@
#define MAX_NMATCH 10
+/* default maximum number of internal redirects */
+#define REWRITE_REDIRECT_LIMIT 10
+
/*
**
** our private data structures we handle with
@@ -309,6 +312,7 @@
array_header *rewriteconds; /* the RewriteCond entries (temporary) */
array_header *rewriterules; /* the RewriteRule entries */
server_rec *server; /* the corresponding server indicator */
+ int redirect_limit; /* maximum number of internal redirects */
} rewrite_server_conf;
@@ -322,8 +326,16 @@
array_header *rewriterules; /* the RewriteRule entries */
char *directory; /* the directory where it applies */
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 table with LRU functionality
@@ -376,10 +388,8 @@
static const char *cmd_rewriteengine(cmd_parms *cmd,
rewrite_perdir_conf *dconf, int flag);
static const char *cmd_rewriteoptions(cmd_parms *cmd,
- rewrite_perdir_conf *dconf,
- char *option);
-static const char *cmd_rewriteoptions_setoption(pool *p, int *options,
- char *name);
+ void *in_dconf,
+ const char *option);
static const char *cmd_rewritelog (cmd_parms *cmd, void *dconf, char *a1);
static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1);
static const char *cmd_rewritemap (cmd_parms *cmd, void *dconf, char *a1,
@@ -489,6 +499,7 @@
static int prefix_stat(const char *path, struct stat *sb);
static void add_env_variable(request_rec *r, char *s);
static int subreq_ok(request_rec *r);
+static int is_redirect_limit_exceeded(request_rec *r);
/* File locking */
static void fd_lock(request_rec *r, int fd);