You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Paul J. Reder" <re...@raleigh.ibm.com> on 1999/12/31 04:15:08 UTC

[Patch] Merge mod_rewrite 1.3 changes into mod_rewrite 2.0 port

The following patch is the promised merge of 1.3 tree changes into
the 2.0 port of mod_rewrite. This patch requires my most recent
patch,  submitted a couple days ago, to port mod_rewrite to 2.0/APR.

After the previous patch and then this patch are applied, mod_rewrite
should be in synch between the 1.3 tree and the 2.0 tree.

Any future changes should probably be applied to both trees.

Sorry these aren't CVS diffs. I waited a long time for the previous 
patch to be processed. I wanted to get this work done before any more
changes occurred, and so that I could move on to other work. I can regen
this patch from CVS if required, after the first patch is applied.

-- 
Paul J. Reder
------------------------------------------------------------
"Remember, Information is not knowledge; Knowledge is not Wisdom;
Wisdom is not truth; Truth is not beauty; Beauty is not love;
Love is not music; Music is the best." -- Frank Zappa

--- mod_rewrite_pre13_port.c	Wed Dec 29 17:08:14 1999
+++ mod_rewrite.c	Thu Dec 30 21:41:41 1999
@@ -102,7 +102,9 @@
 #endif
 
 #ifndef NO_WRITEV
+#ifndef NETWARE
 #include <sys/types.h>
+#endif
 #include <sys/uio.h>
 #endif
 
@@ -1145,13 +1147,19 @@
             return OK;
         }
         else if (  (strlen(r->filename) > 7 &&
-                    strncasecmp(r->filename, "http://", 7) == 0)
+                    strncasecmp(r->filename, "http://",   7) == 0)
                 || (strlen(r->filename) > 8 &&
-                    strncasecmp(r->filename, "https://", 8) == 0)
+                    strncasecmp(r->filename, "https://",  8) == 0)
                 || (strlen(r->filename) > 9 &&
                     strncasecmp(r->filename, "gopher://", 9) == 0)
                 || (strlen(r->filename) > 6 &&
-                    strncasecmp(r->filename, "ftp://", 6) == 0)    ) {
+                    strncasecmp(r->filename, "ftp://",    6) == 0)
+                || (strlen(r->filename) > 5 &&
+                    strncasecmp(r->filename, "ldap:",     5) == 0)
+                || (strlen(r->filename) > 5 &&
+                    strncasecmp(r->filename, "news:",     5) == 0)
+                || (strlen(r->filename) > 7 &&
+                    strncasecmp(r->filename, "mailto:",   7) == 0)) {
             /* it was finally rewritten to a remote URL */
 
             /* skip 'scheme:' */
@@ -1171,8 +1179,8 @@
 
             /* append the QUERY_STRING part */
             if (r->args != NULL) {
-               r->filename = ap_pstrcat(r->pool, r->filename,
-                                        "?", r->args, NULL);
+                r->filename = ap_pstrcat(r->pool, r->filename, "?", 
+                                         ap_escape_uri(r->pool, r->args), NULL);
             }
 
             /* determine HTTP redirect response code */
@@ -1216,7 +1224,7 @@
             /* it was finally rewritten to a local path */
 
             /* expand "/~user" prefix */
-#ifndef WIN32
+#if !defined(WIN32) && !defined(NETWARE)
             r->filename = expand_tildepaths(r, r->filename);
 #endif
             rewritelog(r, 2, "local path result: %s", r->filename);
@@ -1389,9 +1397,7 @@
              * (r->path_info was already appended by the
              * rewriting engine because of the per-dir context!)
              */
-            if (r->args != NULL
-                && r->uri == r->unparsed_uri) {
-                /* see proxy_http:proxy_http_canon() */
+            if (r->args != NULL) {
                 r->filename = ap_pstrcat(r->pool, r->filename,
                                          "?", r->args, NULL);
             }
@@ -1405,13 +1411,19 @@
             return OK;
         }
         else if (  (strlen(r->filename) > 7 &&
-                    strncmp(r->filename, "http://", 7) == 0)
-                || (strlen(r->filename) > 8 &&
-                    strncmp(r->filename, "https://", 8) == 0)
+                    strncasecmp(r->filename, "http://",   7) == 0)
+                || (strlen(r->filename) > 8 &&          
+                    strncasecmp(r->filename, "https://",  8) == 0)
                 || (strlen(r->filename) > 9 &&
-                    strncmp(r->filename, "gopher://", 9) == 0)
+                    strncasecmp(r->filename, "gopher://", 9) == 0)
                 || (strlen(r->filename) > 6 &&
-                    strncmp(r->filename, "ftp://", 6) == 0)    ) {
+                    strncasecmp(r->filename, "ftp://",    6) == 0)
+                || (strlen(r->filename) > 5 &&
+                    strncasecmp(r->filename, "ldap:",     5) == 0)
+                || (strlen(r->filename) > 5 &&
+                    strncasecmp(r->filename, "news:",     5) == 0)
+                || (strlen(r->filename) > 7 &&
+                    strncasecmp(r->filename, "mailto:",   7) == 0)) {
             /* it was finally rewritten to a remote URL */
 
             /* because we are in a per-dir context
@@ -1460,8 +1472,8 @@
 
             /* append the QUERY_STRING part */
             if (r->args != NULL) {
-                r->filename = ap_pstrcat(r->pool, r->filename,
-                                         "?", r->args, NULL);
+                r->filename = ap_pstrcat(r->pool, r->filename, "?", 
+                                         ap_escape_uri(r->pool, r->args), NULL);
             }
 
             /* determine HTTP redirect response code */
@@ -2019,10 +2031,13 @@
     i = strlen(r->filename);
     if (   prefixstrip
         && !(   r->filename[0] == '/'
-             || (   (i > 7 && strncasecmp(r->filename, "http://", 7) == 0)
-                 || (i > 8 && strncasecmp(r->filename, "https://", 8) == 0)
+             || (   (i > 7 && strncasecmp(r->filename, "http://",   7) == 0)
+                 || (i > 8 && strncasecmp(r->filename, "https://",  8) == 0)
                  || (i > 9 && strncasecmp(r->filename, "gopher://", 9) == 0)
-                 || (i > 6 && strncasecmp(r->filename, "ftp://", 6) == 0)))) {
+                 || (i > 6 && strncasecmp(r->filename, "ftp://",    6) == 0)
+                 || (i > 5 && strncasecmp(r->filename, "ldap:",     5) == 0)
+                 || (i > 5 && strncasecmp(r->filename, "news:",     5) == 0)
+                 || (i > 7 && strncasecmp(r->filename, "mailto:",   7) == 0)))) {
         rewritelog(r, 3, "[per-dir %s] add per-dir prefix: %s -> %s%s",
                    perdir, r->filename, perdir, r->filename);
         r->filename = ap_pstrcat(r->pool, perdir, r->filename, NULL);
@@ -2087,10 +2102,13 @@
      *  directly force an external HTTP redirect.
      */
     i = strlen(r->filename);
-    if (   (i > 7 && strncasecmp(r->filename, "http://", 7)   == 0)
-        || (i > 8 && strncasecmp(r->filename, "https://", 8)  == 0)
+    if (   (i > 7 && strncasecmp(r->filename, "http://",   7) == 0)
+        || (i > 8 && strncasecmp(r->filename, "https://",  8) == 0)
         || (i > 9 && strncasecmp(r->filename, "gopher://", 9) == 0)
-        || (i > 6 && strncasecmp(r->filename, "ftp://", 6)    == 0)) {
+        || (i > 6 && strncasecmp(r->filename, "ftp://",    6) == 0)
+        || (i > 5 && strncasecmp(r->filename, "ldap:",     5) == 0)
+        || (i > 5 && strncasecmp(r->filename, "news:",     5) == 0)
+        || (i > 7 && strncasecmp(r->filename, "mailto:",   7) == 0) ) {
         if (perdir == NULL) {
             rewritelog(r, 2,
                        "implicitly forcing redirect (rc=%d) with %s",
@@ -2447,10 +2465,13 @@
     int port;
 
     i = strlen(r->filename);
-    if (!(   (i > 7 && strncasecmp(r->filename, "http://", 7)   == 0)
-          || (i > 8 && strncasecmp(r->filename, "https://", 8)  == 0)
+    if (!(   (i > 7 && strncasecmp(r->filename, "http://",   7) == 0)
+          || (i > 8 && strncasecmp(r->filename, "https://",  8) == 0)
           || (i > 9 && strncasecmp(r->filename, "gopher://", 9) == 0)
-          || (i > 6 && strncasecmp(r->filename, "ftp://", 6)    == 0))) {
+          || (i > 6 && strncasecmp(r->filename, "ftp://",    6) == 0)
+          || (i > 5 && strncasecmp(r->filename, "ldap:",     5) == 0)
+          || (i > 5 && strncasecmp(r->filename, "news:",     5) == 0)
+          || (i > 7 && strncasecmp(r->filename, "mailto:",   7) == 0))) {
 
         thisserver = ap_get_server_name(r);
         port = ap_get_server_port(r);
@@ -2486,34 +2507,37 @@
 static void expand_backref_inbuffer(ap_context_t *p, char *buf, int nbuf,
                                     backrefinfo *bri, char c)
 {
-    int i;
-
-    if (bri->nsub < 1) {
-        return;
-    }
+    register int i;
 
-    if (c != '$') {
-        /* safe existing $N backrefs and replace <c>N with $N backrefs */
-        for (i = 0; buf[i] != '\0' && i < nbuf; i++) {
-            if (buf[i] == '$' && (buf[i+1] >= '0' && buf[i+1] <= '9')) {
-                buf[i++] = '\001';
-            }
-            else if (buf[i] == c && (buf[i+1] >= '0' && buf[i+1] <= '9')) {
-                buf[i++] = '$';
-            }
+    /* protect existing $N and & backrefs and replace <c>N with $N backrefs */
+    for (i = 0; buf[i] != '\0' && i < nbuf; i++) {
+        if (buf[i] == '\\' && (buf[i+1] != '\0' && i < (nbuf-1))) {
+            i++; /* protect next */
+        }
+        else if (buf[i] == '&') {
+            buf[i] = '\001';
+        }
+        else if (c != '$' && buf[i] == '$' && (buf[i+1] >= '0' && buf[i+1] <= '9')) {
+            buf[i] = '\002';
+            i++; /* speedup */
+        }
+        else if (buf[i] == c && (buf[i+1] >= '0' && buf[i+1] <= '9')) {
+            buf[i] = '$';
+            i++; /* speedup */
         }
     }
 
-    /* now apply the pregsub() function */
+    /* now apply the standard regex substitution function */
     ap_cpystrn(buf, ap_pregsub(p, buf, bri->source,
-                         bri->nsub+1, bri->regmatch), nbuf);
+                               bri->nsub+1, bri->regmatch), nbuf);
 
-    if (c != '$') {
-        /* restore the original $N backrefs */
-        for (i = 0; buf[i] != '\0' && i < nbuf; i++) {
-            if (buf[i] == '\001' && (buf[i+1] >= '0' && buf[i+1] <= '9')) {
-                buf[i++] = '$';
-            }
+    /* restore the original $N and & backrefs */
+    for (i = 0; buf[i] != '\0' && i < nbuf; i++) {
+        if (buf[i] == '\001') {
+            buf[i] = '&';
+        }
+        else if (buf[i] == '\002') {
+            buf[i] = '$';
         }
     }
 }
@@ -2525,7 +2549,7 @@
 **  Unix /etc/passwd database information
 **
 */
-#ifndef WIN32
+#if !defined(WIN32) && !defined(NETWARE)
 static char *expand_tildepaths(request_rec *r, char *uri)
 {
     char user[LONG_STRING_LEN];
@@ -3051,16 +3075,14 @@
 
 static int rewrite_rand(int l, int h)
 {
-    int i;
-    char buf[50];
-
     rewrite_rand_init();
-    ap_snprintf(buf, sizeof(buf), "%.0f", 
-                (((double)(rand()%RAND_MAX)/RAND_MAX)*(h-l)));
-    i = atoi(buf)+1;
-    if (i < l) i = l;
-    if (i > h) i = h;
-    return i;
+
+    /* Get [0,1) and then scale to the appropriate range. Note that using
+     * a floating point value ensures that we use all bits of the rand()
+     * result. Doing an integer modulus would only use the lower-order bits
+     * which may not be as uniformly random.
+     */
+    return ((double)(rand() % RAND_MAX) / RAND_MAX) * (h - l + 1) + l;
 }
 
 static char *select_random_value_part(request_rec *r, char *value)
@@ -3297,7 +3319,7 @@
                      "file %s", lockname);
         exit(1);
     }
-#if !defined(OS2) && !defined(WIN32)
+#if !defined(OS2) && !defined(WIN32) && !defined(NETWARE)
     /* make sure the childs have access to this file */
     if (geteuid() == 0 /* is superuser */)
         chown(lockname, unixd_config.user_id, -1 /* no gid change */);
@@ -3732,7 +3754,7 @@
         LOOKAHEAD(ap_sub_req_lookup_file)
     }
 
-#ifndef WIN32
+#if !defined(WIN32) && !defined(NETWARE)
     /* Win32 has a rather different view of file ownerships.
        For now, just forget it */
 
@@ -3767,7 +3789,7 @@
             }
         }
     }
-#endif /* ndef WIN32 */
+#endif /* ndef WIN32 && NETWARE*/
 
     if (result == NULL) {
         return ap_pstrdup(r->pool, "");
@@ -4291,5 +4313,11 @@
     return 0;
 }
 
-
+#ifdef NETWARE
+int main(int argc, char *argv[]) 
+{
+    ExitThread(TSR_THREAD, 0);
+}
+#endif
+ 
 /*EOF*/


--- mod_rewrite_pre13_port.h	Wed Dec 29 17:08:21 1999
+++ mod_rewrite.h	Thu Dec 30 21:58:01 1999
@@ -101,7 +101,9 @@
 #include <signal.h>
 #include <errno.h>
 #include <ctype.h>
+#ifndef NETWARE
 #include <sys/types.h>
+#endif
 #include <sys/stat.h>
 
     /* Include from the Apache server ... */
@@ -157,7 +159,7 @@
 #endif
 #if !defined(USE_FCNTL) && !defined(USE_FLOCK)
 #define USE_FLOCK 1
-#if !defined(MPE) && !defined(WIN32) && !defined(__TANDEM)
+#if !defined(MPE) && !defined(WIN32) && !defined(__TANDEM) && !defined(NETWARE)
 #include <sys/file.h>
 #endif
 #ifndef LOCK_UN