httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Rief, Jacob" <Jacob.R...@TIScover.com>
Subject [PATCH] mod_rewrite. Additional RewriteMap: dso (to run a dynamic shared object instead of an external mapping program)
Date Mon, 23 Apr 2001 10:05:40 GMT
Hello,
while I was running a programm which did the external Rewrite-Mapping by
consulting
a LDAP directory service, I encounterd the following problem:
Somtimes when the LDAP server hangs, all of the httpd-processes which have
to consult
the external mapping programm will hang too.
To get arround this problem I added the following patch to mod_rewrite:
Instead of
having an external program communicating with the httpd-process through a
pipe,
it would be an alternative to use a dynamic shared object which runs inside
the
httpd's-address space.
Such a dynamic shared object can communicate through a singe function call
which I named 'rewrite_lookup_map'. This function takes three parameters,
a const char* for the key, a char* for the mapping result, and the string
length of the result buffer, currently 2048. The function should return
zero on failure and one on success.

Have a look at this example, it just maps lowercase chars to upercase
and vice versa.

----- example.c -----
int rewrite_lookup_map(const char* key, char* result, int size)
{
	int i;
	const char* c;

	i = 0;
	for (c = key; c; c++) {
		if (*c>='A' && *c<='Z') {
			result[i] = *c|32;
		} else if (*c>='a' && *c<='z') {
			result[i] = *c&223;
		} else {
			result[i] = *c;
		}
		i++;
		if (i==size-1)
			return 0;
	}
	result[i] = '\0';
	return 1;
}
----- example.c -----

You may build this example program by compiling it as dso:
> cc -c example -o example.o
> ld -shared example.o -o example.so

Put the following lines into Your httpd.conf:

----- httpd.conf -----
...
RewriteEngine On
RewriteMap togglecase dso:example.so
RewriteRule ^(.*)$ ${togglecase:$1}
...
----- httpd.conf -----

and restart the server. This will toggle the case
of Your URL's. This also avoids RewriteLock directive
for external rewrite programs. In order to initialise the
module You may add the function _init() to Your external
rewrite program, but consult 'man dlopen' for details.

Here is the patch for apache-1.3.19, apply it with 
> cd apache_1.3.19
> patch -p1 < apache_1.3.19.rewrite-dso.patch

---------------------- apache_1.3.19.rewrite-dso.patch
----------------------
diff -ur apache_1.3.19/src/modules/standard/mod_rewrite.c
apache_1.3.19.rewrite-dso/src/modules/standard/mod_rewrite.c
--- apache_1.3.19/src/modules/standard/mod_rewrite.c	Thu Feb  1 05:12:26
2001
+++ apache_1.3.19.rewrite-dso/src/modules/standard/mod_rewrite.c	Sun
Apr 22 19:41:40 2001
@@ -461,6 +461,7 @@
 
     new->name = a1;
     new->func = NULL;
+    new->dsomapfunc = NULL;
     if (strncmp(a2, "txt:", 4) == 0) {
         new->type      = MAPTYPE_TXT;
         new->datafile  = a2+4;
@@ -486,6 +487,11 @@
         new->datafile = a2+4;
         new->checkfile = a2+4;
     }
+    else if (strncmp(a2, "dso:", 4) == 0) {
+        new->type = MAPTYPE_DSO;
+        new->datafile = a2+4;
+        new->checkfile = a2+4;
+    }
     else if (strncmp(a2, "int:", 4) == 0) {
         new->type      = MAPTYPE_INT;
         new->datafile  = NULL;
@@ -2722,6 +2728,18 @@
                                s->name, key);
                 }
             }
+            else if (s->type == MAPTYPE_DSO) {
+                if ((value =
+                     lookup_map_dsobject(r, s->dsomapfunc, key)) != NULL) {
+                    rewritelog(r, 5, "map lookup OK: map=%s key=%s ->
val=%s",
+                               s->name, key, value);
+                    return value;
+                }
+                else {
+                    rewritelog(r, 5, "map lookup FAILED: map=%s key=%s",
+                               s->name, key);
+                }
+            }
             else if (s->type == MAPTYPE_INT) {
                 if ((value = lookup_map_internal(r, s->func, key)) != NULL)
{
                     rewritelog(r, 5, "map lookup OK: map=%s key=%s ->
val=%s",
@@ -2904,6 +2922,18 @@
     }
 }
 
+static char *lookup_map_dsobject(request_rec *r, int (*func)(char *, char
*, int), char *key)
+{
+    char buf[LONG_STRING_LEN];
+
+    if (func(key, buf, LONG_STRING_LEN) == 0) {
+        return NULL;
+    }
+    else {
+        return ap_pstrdup(r->pool, buf);
+    }
+}
+
 static char *lookup_map_internal(request_rec *r,
                                  char *(*func)(request_rec *, char *),
                                  char *key)
@@ -3304,13 +3334,20 @@
     entries = (rewritemap_entry *)rewritemaps->elts;
     for (i = 0; i < rewritemaps->nelts; i++) {
         map = &entries[i];
-        if (map->type != MAPTYPE_PRG) {
+        if (map->datafile == NULL || *(map->datafile) == '\0') {
             continue;
         }
-        if (map->datafile == NULL
-            || *(map->datafile) == '\0'
+        if (map->type == MAPTYPE_DSO) {
+            if (rewritemap_dsobject_load(s, map) == 0) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, s,
+                         "mod_rewrite: could not load external dso for "
+                         "RewriteMap process");
+                exit(1);
+            }
+        }
+        if (map->type != MAPTYPE_PRG
             || map->fpin  != -1
-            || map->fpout != -1        ) {
+            || map->fpout != -1) {
             continue;
         }
         fpin  = NULL;
@@ -3385,7 +3422,37 @@
     return(child_pid);
 }
 
+/* external mapping program loaded as dynamic shared object */
+static int rewritemap_dsobject_load(server_rec *s, rewritemap_entry *map)
+{
+#ifdef NO_DLOPEN
+    ap_log_error(APLOG_MARK, APLOG_ERR, s, 
+                 "mod_rewrite: the release is unable to handle dynamic
shared objects.");
+    exit(1);
+#else
+    char *error;
+    void *handle;
+
+    /* load the external mapping program into the address space of the
server */
+    handle = dlopen(map->datafile, RTLD_LAZY);
+    if (!handle) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, s, 
+                     "mod_rewrite: error while opening dynamic shared
object."
+                     " %s", dlerror());
+        exit(1);
+    }
 
+    /* find the addresse of the mapping interface function from the dso */
+    map->dsomapfunc = dlsym(handle, "rewrite_lookup_map");
+    if ((error = dlerror()) != NULL)  {
+        ap_log_error(APLOG_MARK, APLOG_ERR, s, 
+                     "mod_rewrite: unable to map function
rewrite_lookup_map in dynamic shared object."
+                     " %s", dlerror());
+        exit(1);
+    }
+    return 1;
+#endif
+}
 
 
 /*
diff -ur apache_1.3.19/src/modules/standard/mod_rewrite.h
apache_1.3.19.rewrite-dso/src/modules/standard/mod_rewrite.h
--- apache_1.3.19/src/modules/standard/mod_rewrite.h	Thu Jan 18 23:31:44
2001
+++ apache_1.3.19.rewrite-dso/src/modules/standard/mod_rewrite.h	Sun
Apr 22 19:41:40 2001
@@ -220,6 +220,7 @@
 #define MAPTYPE_PRG                 1<<2
 #define MAPTYPE_INT                 1<<3
 #define MAPTYPE_RND                 1<<4
+#define MAPTYPE_DSO                 1<<5
 
 #define ENGINE_DISABLED             1<<0
 #define ENGINE_ENABLED              1<<1
@@ -274,6 +275,7 @@
     int   fperr;                   /* err file pointer for program maps */
     char *(*func)(request_rec *,   /* function pointer for internal maps */
                   char *);
+    int (*dsomapfunc)(char *, char *, int);  /* function pointer for
external dso mapping function */
 } rewritemap_entry;
 
 typedef struct {
@@ -441,6 +443,8 @@
 #endif
 static char *lookup_map_program(request_rec *r, int fpin,
                                 int fpout, char *key);
+static char *lookup_map_dsobject(request_rec *r,
+                                 int (*func)(char *, char *, int), char
*key);
 static char *lookup_map_internal(request_rec *r,
                                  char *(*func)(request_rec *r, char *key),
                                  char *key);
@@ -468,6 +472,7 @@
     /* program map support */
 static void  run_rewritemap_programs(server_rec *s, pool *p);
 static int   rewritemap_program_child(void *cmd, child_info *pinfo);
+static int   rewritemap_dsobject_load(server_rec *s, rewritemap_entry
*map);
 
     /* env variable support */
 static char *lookup_variable(request_rec *r, char *var);
---------------------- apache_1.3.19.rewrite-dso.patch
----------------------

configure apache before remaking with 
> configure --with-module=so
to enable dynamic linking.

Best luck, Jacob

Mime
View raw message