akosut      96/08/16 16:18:05

  Modified:    src       mod_rewrite.c mod_rewrite.h
  Log:
  Update mod_rewrite
  
  Submitted by: Ralf S. Engelschall
  
  Revision  Changes    Path
  1.2       +209 -94   apache/src/mod_rewrite.c
  
  Index: mod_rewrite.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_rewrite.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -C3 -r1.1 -r1.2
  *** mod_rewrite.c     1996/08/14 17:45:15     1.1
  --- mod_rewrite.c     1996/08/16 23:18:02     1.2
  ***************
  *** 340,350 ****
    {
        rewrite_server_conf *sconf;
        rewritemap_entry *new;
    
        sconf = (rewrite_server_conf 
*)get_module_config(cmd->server->module_config, &rewrite_module);
        new = push_array(sconf->rewritemaps);
        new->name = a1;
  !     new->file = a2;
    
        return NULL;
    }
  --- 340,372 ----
    {
        rewrite_server_conf *sconf;
        rewritemap_entry *new;
  +     struct stat st;
    
        sconf = (rewrite_server_conf 
*)get_module_config(cmd->server->module_config, &rewrite_module);
        new = push_array(sconf->rewritemaps);
  + 
        new->name = a1;
  !     if (strncmp(a2, "txt:", 4) == 0) {
  !         new->file = a2+4;
  !         new->type = MAPTYPE_TXT;
  !     }
  !     else if (strncmp(a2, "dbm:", 4) == 0) {
  !         new->file = a2+4;
  !         new->type = MAPTYPE_DBM;
  !     }
  !     else if (strncmp(a2, "prg:", 4) == 0) {
  !         new->file = a2+4;
  !         new->type = MAPTYPE_PRG;
  !     }
  !     else {
  !         new->file = a2;
  !         new->type = MAPTYPE_TXT;
  !     }
  !     new->fpin  = 0;
  !     new->fpout = 0;
  ! 
  !     if (stat(new->file, &st) == -1)
  !         return pstrcat(cmd->pool, "RewriteMap: map file or program not 
found:", new->file, NULL);
    
        return NULL;
    }
  ***************
  *** 658,663 ****
  --- 680,689 ----
                 || strcasecmp(key, "S") == 0   ) {
            cfg->skip = atoi(val);
        }
  +     else if (   strcasecmp(key, "forbidden") == 0
  +              || strcasecmp(key, "F") == 0   ) {
  +         cfg->flags |= RULEFLAG_FORBIDDEN;
  +     }
        else {
            return pstrcat(p, "RewriteRule: unknown flag '", key, "'\n", NULL);
        }
  ***************
  *** 676,684 ****
    static void init_module(server_rec *s, pool *p)
    {
        /* step through the servers and
  !        open eachs rewriting logfile */
  !     for (; s; s = s->next)
            open_rewritelog(s, p);
    
        /* create the lookup cache */
        cachep = init_cache(p);
  --- 702,713 ----
    static void init_module(server_rec *s, pool *p)
    {
        /* step through the servers and
  !        - open eachs rewriting logfile 
  !        - open the RewriteMap prg:xxx programs */
  !     for (; s; s = s->next) {
            open_rewritelog(s, p);
  +         run_rewritemap_programs(s, p);
  +     }
    
        /* create the lookup cache */
        cachep = init_cache(p);
  ***************
  *** 820,825 ****
  --- 849,859 ----
                rewritelog(r, 1, "redirect to %s [REDIRECT]", r->filename);
                return REDIRECT;
            }
  +         else if (strlen(r->filename) > 10 &&
  +                  strncmp(r->filename, "forbidden:", 10) == 0) {
  +             /* This URLs is forced to be forbidden for the requester */
  +             return FORBIDDEN; 
  +         }
            else if (strlen(r->filename) > 12 &&
                     strncmp(r->filename, "passthrough:", 12) == 0) {
                /* Hack because of underpowered API: passing the current
  ***************
  *** 1023,1028 ****
  --- 1057,1067 ----
                rewritelog(r, 1, "[per-dir %s] redirect to %s [REDIRECT]", 
dconf->directory, r->filename);
                return REDIRECT;
            }
  +         else if (strlen(r->filename) > 10 &&
  +                  strncmp(r->filename, "forbidden:", 10) == 0) {
  +             /* This URLs is forced to be forbidden for the requester */
  +             return FORBIDDEN; 
  +         }
            else {
                /* it was finally rewritten to a local path */
    
  ***************
  *** 1131,1137 ****
        for (i = 0; i < rewriterules->nelts; i++) {
            p = &entries[i];
    
  !         /* ignore this rule if we are explicitly asked to do so
               or this is a proxy throughput or a forced redirect rule */
            if (r->main != NULL &&
                (p->flags & RULEFLAG_IGNOREONSUBREQ ||
  --- 1170,1176 ----
        for (i = 0; i < rewriterules->nelts; i++) {
            p = &entries[i];
    
  !         /* ignore this rule on subrequests if we are explicitly asked to do 
so
               or this is a proxy throughput or a forced redirect rule */
            if (r->main != NULL &&
                (p->flags & RULEFLAG_IGNOREONSUBREQ ||
  ***************
  *** 1150,1155 ****
  --- 1189,1200 ----
                    changed = 1;
                    break;
                }
  +             if (p->flags & RULEFLAG_FORBIDDEN) {
  +                 rewritelog(r, 2, "forcing '%s' to be forbidden", 
r->filename);
  +                 r->filename = pstrcat(r->pool, "forbidden:", r->filename, 
NULL);
  +                 changed = 1;
  +                 break;
  +             }
                if (p->flags & RULEFLAG_PROXY) 
                    break;
                if (p->flags & RULEFLAG_LASTRULE) 
  ***************
  *** 1333,1339 ****
            /* split out on-the-fly generated QUERY_STRING '....?xxxxx&xxxx...' 
*/
            splitout_queryargs(r);
    
  !         /* if a MIME-type should be later forced for this URL, then remeber 
this */
            if (p->forced_mimetype != NULL) {
                table_set(r->notes, REWRITE_FORCED_MIMETYPE_NOTEVAR, 
p->forced_mimetype);
                if (perdir == NULL)
  --- 1378,1384 ----
            /* split out on-the-fly generated QUERY_STRING '....?xxxxx&xxxx...' 
*/
            splitout_queryargs(r);
    
  !         /* if a MIME-type should be later forced for this URL, then 
remember this */
            if (p->forced_mimetype != NULL) {
                table_set(r->notes, REWRITE_FORCED_MIMETYPE_NOTEVAR, 
p->forced_mimetype);
                if (perdir == NULL)
  ***************
  *** 1692,1698 ****
        char *value;
        struct stat st;
        int i;
  -     int rc;
    
        /* get map configuration */
        sconf = r->server->module_config;
  --- 1737,1742 ----
  ***************
  *** 1703,1770 ****
        for (i = 0; i < rewritemaps->nelts; i++) {
            s = &entries[i];
            if (strcmp(s->name, name) == 0) {
  !             if (strlen(s->file) > 4 && strncmp(s->file, "txt:", 4) == 0) {
  !                 rc = stat(s->file+4, &st);
  !                 if (rc == 0) {
  !                     value = get_cache_string(cachep, s->file, CACHEMODE_TS, 
st.st_mtime, key);
  !                     if (value == NULL) {
  !                         rewritelog(r, 6, "cache lookup FAILED, forcing new 
map lookup");
  !                         if ((value = lookup_map_txtfile(r, s->file+4, key)) 
!= NULL) {
  !                             rewritelog(r, 5, "map lookup OK: map=%s key=%s 
-> val=%s", s->file+4, key, value);
  !                             set_cache_string(cachep, s->file, CACHEMODE_TS, 
st.st_mtime, key, value);
  !                             return value;
  !                         }
  !                         else {
  !                             rewritelog(r, 5, "map lookup FAILED: map=%s 
key=%s", s->file+4, key);
  !                         }
                        }
                        else {
  !                         rewritelog(r, 5, "cache lookup OK: res=%s key=%s -> 
val=%s", s->file, key, value);
                        }
                    }
                }
  !             else if (strlen(s->file) > 4 && strncmp(s->file, "dbm:", 4) == 
0) {
    #if SUPPORT_DBM_REWRITEMAP
  !                 rc = stat(s->file+4, &st);
  !                 if (rc == 0) {
  !                     value = get_cache_string(cachep, s->file, CACHEMODE_TS, 
st.st_mtime, key);
  !                     if (value == NULL) {
  !                         rewritelog(r, 6, "cache lookup FAILED, forcing new 
map lookup");
  !                         if ((value = lookup_map_dbmfile(r, s->file+4, key)) 
!= NULL) {
  !                             rewritelog(r, 5, "map lookup OK: map=%s key=%s 
-> val=%s", s->file+4, key, value);
  !                             set_cache_string(cachep, s->file, CACHEMODE_TS, 
st.st_mtime, key, value);
  !                             return value;
  !                         }
  !                         else {
  !                             rewritelog(r, 5, "map lookup FAILED: map=%s 
key=%s", s->file+4, key);
  !                         }
                        }
                        else {
  !                         rewritelog(r, 5, "cache lookup OK: res=%s key=%s -> 
val=%s", s->file, key, value);
                        }
                    }
    #else
                    return NULL;
    #endif
                }
  !             else {
  !                 rc = stat(s->file+4, &st);
  !                 if (rc == 0) {
  !                     value = get_cache_string(cachep, s->file, CACHEMODE_TS, 
st.st_mtime, key);
  !                     if (value == NULL) {
  !                         rewritelog(r, 6, "cache lookup FAILED, forcing new 
map lookup");
  !                         if ((value = lookup_map_txtfile(r, s->file, key)) 
!= NULL) {
  !                             rewritelog(r, 5, "map lookup OK: map=%s key=%s 
-> val=%s", s->file, key, value);
  !                             set_cache_string(cachep, s->file, CACHEMODE_TS, 
st.st_mtime, key, value);
  !                             return value;
  !                         }
  !                         else {
  !                             rewritelog(r, 5, "map lookup FAILED: map=%s 
key=%s", s->file, key);
  !                         }
  !                     }
  !                     else {
  !                         rewritelog(r, 5, "cache lookup OK: res=%s key=%s -> 
val=%s", s->file, key, value);
  !                     }
                    }
                }
            }
  --- 1747,1799 ----
        for (i = 0; i < rewritemaps->nelts; i++) {
            s = &entries[i];
            if (strcmp(s->name, name) == 0) {
  !             if (s->type == MAPTYPE_TXT) {
  !                 stat(s->file, &st); /* existence was checked at startup! */
  !                 value = get_cache_string(cachep, s->file, CACHEMODE_TS, 
st.st_mtime, key);
  !                 if (value == NULL) {
  !                     rewritelog(r, 6, "cache lookup FAILED, forcing new map 
lookup");
  !                     if ((value = lookup_map_txtfile(r, s->file, key)) != 
NULL) {
  !                         rewritelog(r, 5, "map lookup OK: map=%s key=%s -> 
val=%s", s->file, key, value);
  !                         set_cache_string(cachep, s->file, CACHEMODE_TS, 
st.st_mtime, key, value);
  !                         return value;
                        }
                        else {
  !                         rewritelog(r, 5, "map lookup FAILED: map=%s 
key=%s", s->file, key);
                        }
                    }
  +                 else {
  +                     rewritelog(r, 5, "cache lookup OK: res=%s key=%s -> 
val=%s", s->file, key, value);
  +                 }
                }
  !             else if (s->type == MAPTYPE_DBM) {
    #if SUPPORT_DBM_REWRITEMAP
  !                 stat(s->file, &st); /* existence was checked at startup! */
  !                 value = get_cache_string(cachep, s->file, CACHEMODE_TS, 
st.st_mtime, key);
  !                 if (value == NULL) {
  !                     rewritelog(r, 6, "cache lookup FAILED, forcing new map 
lookup");
  !                     if ((value = lookup_map_dbmfile(r, s->file, key)) != 
NULL) {
  !                         rewritelog(r, 5, "map lookup OK: map=%s key=%s -> 
val=%s", s->file, key, value);
  !                         set_cache_string(cachep, s->file, CACHEMODE_TS, 
st.st_mtime, key, value);
  !                         return value;
                        }
                        else {
  !                         rewritelog(r, 5, "map lookup FAILED: map=%s 
key=%s", s->file, key);
                        }
                    }
  +                 else {
  +                     rewritelog(r, 5, "cache lookup OK: res=%s key=%s -> 
val=%s", s->file, key, value);
  +                 }
    #else
                    return NULL;
    #endif
                }
  !             else if (s->type == MAPTYPE_PRG) {
  !                 if ((value = lookup_map_program(r, s->fpin, s->fpout, key)) 
!= NULL) {
  !                     rewritelog(r, 5, "map lookup OK: map=%s key=%s -> 
val=%s", s->file, key, value);
  !                     return value;
  !                 }
  !                 else {
  !                     rewritelog(r, 5, "map lookup FAILED: map=%s key=%s", 
s->file, key);
                    }
                }
            }
  ***************
  *** 1861,1866 ****
  --- 1890,1920 ----
    }
    #endif
    
  + static char *lookup_map_program(request_rec *r, int fpin, int fpout, char 
*key)
  + {
  +     static char buf[MAX_STRING_LEN];
  +     char c;
  +     int i;
  + 
  +     /* write out the request key */
  +     sprintf(buf, "%s\n", key);
  +     write(fpin, buf, strlen(buf));
  + 
  +     /* read in the response value */
  +     i = 0;
  +     while (read(fpout, &c, 1) == 1) {
  +         if (c == '\n')
  +             break;
  +         buf[i++] = c;
  +     }
  +     buf[i] = '\0';
  + 
  +     if (strcasecmp(buf, "NULL") == 0)
  +         return NULL;
  +     else
  +         return pstrdup(r->pool, buf);
  + }
  + 
    
    
    
  ***************
  *** 1908,1913 ****
  --- 1962,1968 ----
                exit(1);
            }
        }
  +     return;
    }
    
    /* Child process code for 'RewriteLog "|..."' */
  ***************
  *** 1997,2002 ****
  --- 2052,2115 ----
    /*
    ** +-------------------------------------------------------+
    ** |                                                       |
  + ** |                  program map support
  + ** |                                                       |
  + ** +-------------------------------------------------------+
  + */
  + 
  + static void run_rewritemap_programs(server_rec *s, pool *p)
  + {
  +     rewrite_server_conf *conf;
  +     char *fname;
  +     FILE *fpin;
  +     FILE *fpout;
  +     array_header *rewritemaps;
  +     rewritemap_entry *entries;
  +     rewritemap_entry *map;
  +     int i;
  +     int rc;
  +   
  +     conf = get_module_config(s->module_config, &rewrite_module);
  + 
  +     rewritemaps = conf->rewritemaps;
  +     entries = (rewritemap_entry *)rewritemaps->elts;
  +     for (i = 0; i < rewritemaps->nelts; i++) {
  +         map = &entries[i];
  +         if (map->type != MAPTYPE_PRG)
  +             continue;
  +         if (map->file == NULL    ||
  +             *(map->file) == '\0' ||
  +             map->fpin > 0        ||
  +             map->fpout > 0         )
  +             continue;
  +         fname = server_root_relative(p, map->file);
  +         fpin = NULL;
  +         fpout = NULL;
  +         rc = spawn_child(p, rewritemap_program_child, (void *)map->file, 
kill_after_timeout, &fpin, &fpout);
  +         if (rc == 0 || fpin == NULL || fpout == NULL) {
  +             fprintf (stderr, "mod_rewrite: could not fork child for 
RewriteMap process\n");
  +             exit (1);
  +         }
  +         map->fpin  = fileno(fpin);
  +         map->fpout = fileno(fpout);
  +     }
  +     return;
  + }
  + 
  + /* Child process code */
  + static void rewritemap_program_child(void *cmd)
  + {
  +     cleanup_for_exec();
  +     signal(SIGHUP, SIG_IGN);
  +     execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
  +     exit(1);
  + }
  + 
  + 
  + 
  + /*
  + ** +-------------------------------------------------------+
  + ** |                                                       |
    ** |             environment variable support
    ** |                                                       |
    ** +-------------------------------------------------------+
  ***************
  *** 2138,2147 ****
            sprintf(resultbuf, "%d", MODULE_MAGIC_NUMBER);
            result = resultbuf;
        }
  -     else if (strcasecmp(var, "PATH") == 0) {
  -         if ((result = getenv("PATH")) == NULL)
  -             result = DEFAULT_PATH;
  -     }
    
        /* underlaying Unix system stuff */
        else if (strcasecmp(var, "TIME_YEAR") == 0) {
  --- 2251,2256 ----
  ***************
  *** 2173,2178 ****
  --- 2282,2293 ----
        else if (strcasecmp(var, "TIME_WDAY") == 0) {
            MKTIMESTR("%d", tm_wday)
        }
  + 
  +     /* all other env-variables from the parent Apache process */
  +     else if (strlen(var) > 4 && strncasecmp(var, "ENV:", 4) == 0) {
  +         result = getenv(var+4);
  +     }
  + 
        /* uptime, load average, etc. .. */
    
        if (result == NULL)
  ***************
  *** 2382,2449 ****
    static int parseargline(char *str, char **a1, char **a2, char **a3)
    {
        char *cp;
    
  !     /*  strip whitespaces */
  !     for (cp = str; *cp != '\0' && (*cp == ' ' || *cp == '\t'); cp++)
  !         ;
    
        /*  determine first argument */
        *a1 = cp;
  !     for ( ; *cp != '\0'; cp++) {
  !         if (*cp == '\\' && *(cp+1) == ' ') {
  !             cp++;
  !             continue;
  !         }
  !         if (*cp == ' ' || *cp == '\t')
  !             break;
  !     }
        if (*cp == '\0')
            return 1;
        *cp++ = '\0';
    
  !     /*  strip whitespaces */
  !     for ( ; *cp != '\0' && (*cp == ' ' || *cp == '\t'); cp++)
  !         ;
    
        /*  determine second argument */
        *a2 = cp;
  !     for ( ; *cp != '\0'; cp++) {
  !         if (*cp == '\\' && *(cp+1) == ' ') {
  !             cp++;
  !             continue;
  !         }
  !         if (*cp == ' ' || *cp == '\t')
  !             break;
  !     }
  ! 
        if (*cp == '\0') {
  -         /* there were only two args */
            *cp++ = '\0';
            *a3 = NULL;
            return 0;
        }
        *cp++ = '\0';
  !     /*  strip whitespaces */
  !     for ( ; *cp != '\0' && (*cp == ' ' || *cp == '\t'); cp++)
  !         ;
        /* again check if there are only two arguments */
        if (*cp == '\0') {
            *cp++ = '\0';
            *a3 = NULL;
            return 0;
  - 
        }
    
        /*  determine second argument */
        *a3 = cp;
  !     for ( ; *cp != '\0'; cp++) {
  !         if (*cp == '\\' && *(cp+1) == ' ') {
  !             cp++;
  !             continue;
  !         }
  !         if (*cp == ' ' || *cp == '\t')
  !             break;
  !     }
        *cp++ = '\0';
    
        return 0;
  --- 2497,2564 ----
    static int parseargline(char *str, char **a1, char **a2, char **a3)
    {
        char *cp;
  +     int isquoted;
    
  ! #define SKIP_WHITESPACE(cp) \
  !     for ( ; *cp == ' ' || *cp == '\t'; ) \
  !         cp++;
  ! 
  ! #define CHECK_QUOTATION(cp,isquoted) \
  !     isquoted = 0; \
  !     if (*cp == '"') { \
  !         isquoted = 1; \
  !         cp++; \
  !     }
  ! 
  ! #define DETERMINE_NEXTSTRING(cp,isquoted) \
  !     for ( ; *cp != '\0'; cp++) { \
  !         if (   (isquoted    && (*cp     == ' ' || *cp     == '\t')) \
  !             || (*cp == '\\' && (*(cp+1) == ' ' || *(cp+1) == '\t'))) { \
  !             cp++; \
  !             continue; \
  !         } \
  !         if (   (!isquoted && (*cp == ' ' || *cp == '\t')) \
  !             || (isquoted  && *cp == '"')                  ) \
  !             break; \
  !     } 
  ! 
  !     cp = str;
  !     SKIP_WHITESPACE(cp);
    
        /*  determine first argument */
  +     CHECK_QUOTATION(cp, isquoted);
        *a1 = cp;
  !     DETERMINE_NEXTSTRING(cp, isquoted);
        if (*cp == '\0')
            return 1;
        *cp++ = '\0';
    
  !     SKIP_WHITESPACE(cp);
    
        /*  determine second argument */
  +     CHECK_QUOTATION(cp, isquoted);
        *a2 = cp;
  !     DETERMINE_NEXTSTRING(cp, isquoted);
        if (*cp == '\0') {
            *cp++ = '\0';
            *a3 = NULL;
            return 0;
        }
        *cp++ = '\0';
  ! 
  !     SKIP_WHITESPACE(cp);
  ! 
        /* again check if there are only two arguments */
        if (*cp == '\0') {
            *cp++ = '\0';
            *a3 = NULL;
            return 0;
        }
    
        /*  determine second argument */
  +     CHECK_QUOTATION(cp, isquoted);
        *a3 = cp;
  !     DETERMINE_NEXTSTRING(cp, isquoted);
        *cp++ = '\0';
    
        return 0;
  
  
  
  1.2       +15 -2     apache/src/mod_rewrite.h
  
  Index: mod_rewrite.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_rewrite.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -C3 -r1.1 -r1.2
  *** mod_rewrite.h     1996/08/14 17:45:15     1.1
  --- mod_rewrite.h     1996/08/16 23:18:03     1.2
  ***************
  *** 123,128 ****
  --- 123,133 ----
    #define RULEFLAG_NOTMATCH           1<<6
    #define RULEFLAG_PROXY              1<<7
    #define RULEFLAG_PASSTHROUGH        1<<8
  + #define RULEFLAG_FORBIDDEN          1<<9
  + 
  + #define MAPTYPE_TXT                 1<<0
  + #define MAPTYPE_DBM                 1<<1
  + #define MAPTYPE_PRG                 1<<2
    
    #define ENGINE_DISABLED             1<<0
    #define ENGINE_ENABLED              1<<1
  ***************
  *** 142,148 ****
    
    typedef struct {
        char *name;                    /* the name of the map */
  !     char *file;                    /* the correspoindign file of the map */
    } rewritemap_entry;
    
    typedef struct {
  --- 147,156 ----
    
    typedef struct {
        char *name;                    /* the name of the map */
  !     char *file;                    /* the file of the map */
  !     int   type;                    /* the type of the map */
  !     int   fpin;                    /* in  filepointer for program maps */
  !     int   fpout;                   /* out filepointer for program maps */
    } rewritemap_entry;
    
    typedef struct {
  ***************
  *** 209,215 ****
    } cachelist;
    
    typedef struct cache {
  !     pool         *pool;
        array_header *lists;
    } cache;
    
  --- 217,223 ----
    } cachelist;
    
    typedef struct cache {
  !     pool         *pool;
        array_header *lists;
    } cache;
    
  ***************
  *** 272,283 ****
  --- 280,296 ----
    #if SUPPORT_DBM_REWRITEMAP
    static char *lookup_map_dbmfile(request_rec *r, char *file, char *key);
    #endif
  + static char *lookup_map_program(request_rec *r, int fpin, int fpout, char 
*key);
    
        /* rewriting logfile support */
    static void  open_rewritelog(server_rec *s, pool *p);
    static void  rewritelog_child(void *cmd);
    static void  rewritelog(request_rec *r, int level, char *text, ...);
    static char *current_logtime(request_rec *r);
  + 
  +     /* program map support */
  + static void  run_rewritemap_programs(server_rec *s, pool *p);
  + static void  rewritemap_program_child(void *cmd);
    
        /* env variable support */
    static void  expand_variables_inbuffer(request_rec *r, char *buf);
  
  
  

Reply via email to