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);