*/
-/*
-** mod_rewrite.c -- The Main Module Code
-** _ _ _
+/* _ _ _
** _ __ ___ ___ __| | _ __ _____ ___ __(_) |_ ___
** | '_ ` _ \ / _ \ / _` | | '__/ _ \ \ /\ / / '__| | __/ _ \
** | | | | | | (_) | (_| | | | | __/\ V V /| | | | || __/
** |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___|
** |_____|
**
-** URL Rewriting Module, Version 3.0.6 (15-Jun-1997)
+** URL Rewriting Module
**
** This module uses a rule-based rewriting engine (based on a
** regular-expression parser) to rewrite requested URLs on the fly.
** can lead to internal subprocessing, external request redirection or even
** to internal proxy throughput.
**
-** The documentation and latest release can be found on
-** http://www.engelschall.com/sw/mod_rewrite/
-**
-** Copyright (c) 1996-1997 Ralf S. Engelschall, All rights reserved.
+** This module was originally written in April 1996 and
+** gifted exclusively to the The Apache Group in July 1997 by
**
-** Written for The Apache Group by
** Ralf S. Engelschall
** rse@engelschall.com
** www.engelschall.com
};
/* the cache */
-cache *cachep;
+static cache *cachep;
/* whether proxy module is available or not */
static int proxy_available;
char *prefix;
int l;
int n;
+ char *ofilename;
dconf = (rewrite_perdir_conf *)get_module_config(r->per_dir_config, &rewrite_module);
return DECLINED;
}
+ /*
+ * remember the current filename before rewriting for later check
+ * to prevent deadlooping because of internal redirects
+ * on final URL/filename which can be equal to the inital one.
+ */
+ ofilename = r->filename;
+
/*
* now apply the rules ...
*/
if (r->filename[0] != '/')
return BAD_REQUEST;
+ /* Check for deadlooping:
+ * At this point we KNOW that at least one rewriting
+ * rule was applied, but when the resulting URL is
+ * the same as the initial URL, we are not allowed to
+ * use the following internal redirection stuff because
+ * this would lead to a deadloop.
+ */
+ if (strcmp(r->filename, ofilename) == 0) {
+ rewritelog(r, 1, "[per-dir %s] initial URL equal rewritten URL: %s [IGNORING REWRITE]", dconf->directory, r->filename);
+ return OK;
+ }
+
/* if there is a valid base-URL then substitute
the per-dir prefix with this base-URL if the
current filename still is inside this per-dir
return 0; /* if any condition fails this complete rule fails */
/* if this is a pure matching rule we return immediately */
- if (strcmp(output, "-") == 0)
+ if (strcmp(output, "-") == 0) {
+ /* but before we set the env variables... */
+ for (i = 0; p->env[i] != NULL; i++) {
+ strncpy(env2, p->env[i], sizeof(env2)-1);
+ EOS_PARANOIA(env2);
+ strncpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch), sizeof(env)-1); /* substitute in output */
+ EOS_PARANOIA(env);
+ add_env_variable(r, env);
+ }
return 2;
+ }
/* if this is a forced proxy request ... */
if (p->flags & RULEFLAG_PROXY) {
return 1;
}
- /* if this is a implicit redirect in a per-dir rule */
+ /* if this is an implicit redirect in a per-dir rule */
i = strlen(output);
if (perdir != NULL
&& ( (i > 7 && strncmp(output, "http://", 7) == 0)
return 1;
}
- /* add the previously stripped perdir prefix
- if the new URI is not a new one (i.e.
- prefixed by a slash which means that is
- no for this per-dir context) */
+ /* add again the previously stripped perdir prefix if the new
+ URI is not a new one (i.e. prefixed by a slash which means
+ that it is not for this per-dir context) */
if (prefixstrip && output[0] != '/') {
rewritelog(r, 3, "[per-dir %s] add per-dir prefix: %s -> %s%s", perdir, output, perdir, output);
output = pstrcat(r->pool, perdir, output, NULL);
and the current URL still is not a fully qualified one we
finally prefix it with http[s]://<ourname> explicitly */
if (flags & RULEFLAG_FORCEREDIRECT) {
+ r->status = p->forced_responsecode;
if ( !(strlen(r->filename) > 7 &&
strncmp(r->filename, "http://", 7) == 0)
&& !(strlen(r->filename) > 8 &&
else
rewritelog(r, 2, "[per-dir %s] prepare forced redirect %s -> %s", perdir, r->filename, newuri);
r->filename = pstrdup(r->pool, newuri);
- r->status = p->forced_responsecode;
return 1;
}
}
if (p->flags & CONDFLAG_NOTMATCH)
rc = !rc;
- rewritelog(r, 4, "RewriteCond: input='%s' pattern='%s' => %s", input, p->pattern, rc ? "matched" : "not-matched");
+ rewritelog(r, 4, "RewriteCond: input='%s' pattern='%s%s' => %s",
+ input, (p->flags & CONDFLAG_NOTMATCH ? "!" : ""),
+ p->pattern, rc ? "matched" : "not-matched");
/* end just return the result */
return rc;
r->args = pstrcat(r->pool, q, "&", r->args, NULL);
else
r->args = pstrdup(r->pool, q);
- if (r->args[strlen(r->args)-1] == '&')
- r->args[strlen(r->args)-1] = '\0';
- rewritelog(r, 3, "split uri=%s -> uri=%s, args=%s", olduri, r->filename, r->args);
+ if (strlen(r->args) == 0) {
+ r->args = NULL;
+ rewritelog(r, 3, "split uri=%s -> uri=%s, args=<none>", olduri, r->filename);
+ }
+ else {
+ if (r->args[strlen(r->args)-1] == '&')
+ r->args[strlen(r->args)-1] = '\0';
+ rewritelog(r, 3, "split uri=%s -> uri=%s, args=%s", olduri, r->filename, r->args);
+ }
}
return;
}
int i;
/* lock the channel */
+#ifdef USE_PIPE_LOCKING
fd_lock(fpin);
+#endif
/* write out the request key */
write(fpin, key, strlen(key));
buf[i] = '\0';
/* unlock the channel */
+#ifdef USE_PIPE_LOCKING
fd_unlock(fpin);
+#endif
if (strcasecmp(buf, "NULL") == 0)
return NULL;
rewrite_server_conf *conf;
char *fname;
FILE *fp;
- static int rewritelog_flags = ( O_WRONLY|O_APPEND|O_CREAT );
- static mode_t rewritelog_mode = ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH );
+ int rewritelog_flags = ( O_WRONLY|O_APPEND|O_CREAT );
+ mode_t rewritelog_mode = ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH );
conf = get_module_config(s->module_config, &rewrite_module);
rewrite_server_conf *conf;
conn_rec *connect;
char *str1;
- static char str2[HUGE_STRING_LEN];
- static char str3[HUGE_STRING_LEN];
- static char type[20];
- static char redir[20];
+ char str2[512];
+ char str3[1024];
+ char type[20];
+ char redir[20];
va_list ap;
int i;
request_rec *req;
char *ruser;
+ const char *rhost;
va_start(ap, text);
conf = get_module_config(r->server->module_config, &rewrite_module);
ruser = "\"\"";
}
- str1 = pstrcat(r->pool, get_remote_host(connect, r->server->module_config, REMOTE_NAME), " ",
+ rhost = get_remote_host(connect, r->server->module_config, REMOTE_NAME);
+ if (rhost == NULL)
+ rhost = "UNKNOWN-HOST";
+
+ str1 = pstrcat(r->pool, rhost, " ",
(connect->remote_logname != NULL ? connect->remote_logname : "-"), " ",
ruser, NULL);
ap_vsnprintf(str2, sizeof(str2), text, ap);
else
strcpy(type, "subreq");
- for (i = 0, req = r->prev; req != NULL; req = req->prev)
- ;
+ for (i = 0, req = r; req->prev != NULL; req = req->prev)
+ i++;
if (i == 0)
redir[0] = '\0';
else
static int is_proxy_available(server_rec *s)
{
- extern module *preloaded_modules[];
- command_rec *c;
- int n;
-
- for (n = 0; preloaded_modules[n] != NULL; n++) {
- for (c = preloaded_modules[n]->cmds; c && c->name; ++c) {
- if (strcmp(c->name, "ProxyRequests") == 0) {
- return 1;
- }
- }
- }
- return 0;
+ return (find_linked_module("mod_proxy") != NULL);
}
**
*/
-int compare_lexicography(char *cpNum1, char *cpNum2)
+static int compare_lexicography(char *cpNum1, char *cpNum2)
{
int i;
int n1, n2;