You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Ralf S. Engelschall" <rs...@engelschall.com> on 1998/02/23 17:46:04 UTC
[PATCH] Fix RewriteMap programs
Fix RewriteMap programs
-----------------------
The below patch tries to fix the long-standing bug (see e.g. PR#1029) where
RewriteMap programs are broken under SunOS and FreeBSD because these systems
hate locking a pipe directly. To avoid this problem I introduce a RewriteLock
directive which when present defines a lockfile for mod_rewrite. This lockfile
then is used to synchronize the protocol between the multiple server processes
and the single rewriting map program.
I tested it now under my FreeBSD 2.1.5 box and it seems to work fine. I was
able to use a rewriting map program again and all of my parallel
ZeusBench-generated requests were correctly transformed. But it needs review
and testing by others.
Ralf S. Engelschall
rse@engelschall.com
www.engelschall.com
Index: mod_rewrite.h
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/src/modules/standard/mod_rewrite.h,v
retrieving revision 1.37
diff -u -r1.37 mod_rewrite.h
--- mod_rewrite.h 1998/02/23 08:27:39 1.37
+++ mod_rewrite.h 1998/02/23 16:00:51
@@ -136,17 +136,9 @@
#ifdef WIN32
#undef USE_FCNTL
#define USE_LOCKING
+#include <sys/locking.h>
#endif
- /* The locking support for the RewriteMap programs:
- * Locking a pipe to the child works fine under most
- * Unix derivates, but braindead SunOS 4.1.x has
- * problems with this approach...
- */
-#define USE_PIPE_LOCKING 1
-#ifdef SUNOS4
-#undef USE_PIPE_LOCKING
-#endif
/*
**
@@ -265,6 +257,8 @@
char *rewritelogfile; /* the RewriteLog filename */
int rewritelogfp; /* the RewriteLog open filepointer */
int rewriteloglevel; /* the RewriteLog level of verbosity */
+ char *rewritelockfile; /* the RewriteLock filename */
+ int rewritelockfp; /* the RewriteLock open filepointer */
array_header *rewritemaps; /* the RewriteMap entries */
array_header *rewriteconds; /* the RewriteCond entries (temporary) */
array_header *rewriterules; /* the RewriteRule entries */
@@ -339,6 +333,8 @@
static const char *cmd_rewritemap (cmd_parms *cmd, void *dconf, char *a1,
char *a2);
+static const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, char *a1);
+
static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf,
char *a1);
@@ -409,6 +405,11 @@
static void rewritelog(request_rec *r, int level, const char *text, ...)
__attribute__((format(printf,3,4)));
static char *current_logtime(request_rec *r);
+
+ /* rewritinf lockfile support */
+static void open_rewritelock(server_rec *s, pool *p);
+static void rewritelock_take(request_rec *r);
+static void rewritelock_free(request_rec *r);
/* program map support */
static void run_rewritemap_programs(server_rec *s, pool *p);
Index: mod_rewrite.c
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/src/modules/standard/mod_rewrite.c,v
retrieving revision 1.68
diff -u -r1.68 mod_rewrite.c
--- mod_rewrite.c 1998/02/23 15:18:50 1.68
+++ mod_rewrite.c 1998/02/23 16:04:32
@@ -112,9 +112,6 @@
/* now our own stuff ... */
#include "mod_rewrite.h"
-#ifdef USE_LOCKING
-#include <sys/locking.h>
-#endif
/*
@@ -172,6 +169,8 @@
"a URL-applied regexp-pattern and a substitution URL" },
{ "RewriteMap", cmd_rewritemap, NULL, RSRC_CONF, TAKE2,
"a mapname and a filename" },
+ { "RewriteLock", cmd_rewritelock, NULL, RSRC_CONF, TAKE1,
+ "the filename of a lockfile used for inter-process synchronisation"},
{ "RewriteLog", cmd_rewritelog, NULL, RSRC_CONF, TAKE1,
"the filename of the rewriting logfile" },
{ "RewriteLogLevel", cmd_rewriteloglevel, NULL, RSRC_CONF, TAKE1,
@@ -250,6 +249,8 @@
a->rewritelogfile = NULL;
a->rewritelogfp = -1;
a->rewriteloglevel = 1;
+ a->rewritelockfile = NULL;
+ a->rewritelockfp = -1;
a->rewritemaps = make_array(p, 2, sizeof(rewritemap_entry));
a->rewriteconds = make_array(p, 2, sizeof(rewritecond_entry));
a->rewriterules = make_array(p, 2, sizeof(rewriterule_entry));
@@ -272,6 +273,10 @@
a->rewritelogfp = base->rewritelogfp != -1 ?
base->rewritelogfp : overrides->rewritelogfp;
a->rewriteloglevel = overrides->rewriteloglevel;
+ a->rewritelockfile = base->rewritelockfile != NULL ?
+ base->rewritelockfile : overrides->rewritelockfile;
+ a->rewritelockfp = base->rewritelockfp != -1 ?
+ base->rewritelockfp : overrides->rewritelockfp;
if (a->options & OPTION_INHERIT) {
a->rewritemaps = append_arrays(p, overrides->rewritemaps,
@@ -490,6 +495,18 @@
return NULL;
}
+static const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, char *a1)
+{
+ rewrite_server_conf *sconf;
+
+ sconf = (rewrite_server_conf *)
+ get_module_config(cmd->server->module_config, &rewrite_module);
+
+ sconf->rewritelockfile = a1;
+
+ return NULL;
+}
+
static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf,
char *a1)
{
@@ -856,10 +873,12 @@
{
/* step through the servers and
* - open each rewriting logfile
+ * - open each rewriting lockfile
* - open the RewriteMap prg:xxx programs
*/
for (; s; s = s->next) {
open_rewritelog(s, p);
+ open_rewritelock(s, p);
run_rewritemap_programs(s, p);
}
@@ -2635,10 +2654,8 @@
char c;
int i;
- /* lock the channel */
-#ifdef USE_PIPE_LOCKING
- fd_lock(fpin);
-#endif
+ /* take the lock */
+ rewritelock_take(r);
/* write out the request key */
write(fpin, key, strlen(key));
@@ -2653,10 +2670,8 @@
}
buf[i] = '\0';
- /* unlock the channel */
-#ifdef USE_PIPE_LOCKING
- fd_unlock(fpin);
-#endif
+ /* give the lock back */
+ rewritelock_free(r);
if (strcasecmp(buf, "NULL") == 0)
return NULL;
@@ -2775,7 +2790,7 @@
if (*(conf->rewritelogfile) == '\0')
return;
if (conf->rewritelogfp > 0)
- return; /* virtual log shared w/main server */
+ return; /* virtual log shared w/ main server */
fname = server_root_relative(p, conf->rewritelogfile);
@@ -2918,6 +2933,70 @@
}
+
+
+/*
+** +-------------------------------------------------------+
+** | |
+** | rewriting lockfile support
+** | |
+** +-------------------------------------------------------+
+*/
+
+static void open_rewritelock(server_rec *s, pool *p)
+{
+ rewrite_server_conf *conf;
+ char *fname;
+ int rewritelock_flags = ( O_WRONLY|O_APPEND|O_CREAT );
+#ifdef WIN32
+ mode_t rewritelock_mode = ( _S_IREAD|_S_IWRITE );
+#else
+ mode_t rewritelock_mode = ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH );
+#endif
+
+ conf = get_module_config(s->module_config, &rewrite_module);
+
+ if (conf->rewritelockfile == NULL)
+ return;
+ if (*(conf->rewritelockfile) == '\0')
+ return;
+ if (conf->rewritelockfp > 0)
+ return; /* virtual log shared w/ main server */
+
+ fname = server_root_relative(p, conf->rewritelockfile);
+
+ if ((conf->rewritelockfp = popenf(p, fname, rewritelock_flags,
+ rewritelock_mode)) < 0) {
+ perror("open");
+ fprintf(stderr,
+ "mod_rewrite: could not open RewriteLock file %s.\n",
+ fname);
+ exit(1);
+ }
+ return;
+}
+
+static void rewritelock_take(request_rec *r)
+{
+ rewrite_server_conf *conf;
+
+ conf = get_module_config(r->server->module_config, &rewrite_module);
+
+ if (conf->rewritelockfp != -1)
+ fd_lock(conf->rewritelockfp);
+ return;
+}
+
+static void rewritelock_free(request_rec *r)
+{
+ rewrite_server_conf *conf;
+
+ conf = get_module_config(r->server->module_config, &rewrite_module);
+
+ if (conf->rewritelockfp != -1)
+ fd_unlock(conf->rewritelockfp);
+ return;
+}
/*