mod_rewrite.c revision 9ede6357edc9aff1fb2f7edebefab473673298aa
** _ __ ___ ___ __| | _ __ _____ ___ __(_) |_ ___ ** | '_ ` _ \ / _ \ / _` | | '__/ _ \ \ /\ / / '__| | __/ _ \ ** | | | | | | (_) | (_| | | | | __/\ V V /| | | | || __/ ** |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___| ** This module uses a rule-based rewriting engine (based on a ** regular-expression parser) to rewrite requested URLs on the fly. ** It supports an unlimited number of additional rule conditions (which can ** operate on a lot of variables, even on HTTP headers) for granular ** matching and even external database lookups (either via plain text ** tables, DBM hash files or even external processes) for advanced URL ** It operates on the full URLs (including the PATH_INFO part) both in ** per-server context (httpd.conf) and per-dir context (.htaccess) and even ** can generate QUERY_STRING parts on result. The rewriting result finally ** can lead to internal subprocessing, external request redirection or even ** to internal proxy throughput. ** This module was originally written in April 1996 and ** gifted exclusively to the The Apache Group in July 1997 by ** +-------------------------------------------------------+ ** | static module configuration ** +-------------------------------------------------------+ ** Our interface to the Apache server kernel: ** o Runtime logic of a request is as following: ** while(request or subrequest) ** foreach(stage #0...#9) ** o the order of modules at (**) is the inverted order as ** given in the "Configuration" file, i.e. the last module ** specified is the first one called for each hook! ** The core module is always the last! ** o there are two different types of result checking and ** for hook #0,#1,#4,#5,#6,#8: ** hook run loop stops on first modules which gives ** back a result != DECLINED, i.e. it usually returns OK ** which says "OK, module has handled this _stage_" and for #1 ** this have not to mean "Ok, the filename is now valid". ** all hooks are run, independend of result ** o at the last stage, the core module always ** - says "BAD_REQUEST" if r->filename does not begin with "/" ** - prefix URL with document_root or replaced server_root ** with document_root and sets r->filename ** - always return a "OK" independed if the file really exists /* The section for the Configure script: * MODULE-DEFINITION-START if [ "x$found_dbm" = "x1" ]; then echo " enabling DBM support for mod_rewrite" echo " disabling DBM support for mod_rewrite" echo " (perhaps you need to add -ldbm, -lndbm or -lgdbm to EXTRA_LIBS)" CFLAGS="$CFLAGS -DNO_DBM_REWRITEMAP" /* the ap_table_t of commands we provide */ "On or Off to enable or disable (default) the whole rewriting engine" },
"List of option strings to set" },
"the base URL of the per-directory context" },
"an input string and a to be applied regexp-pattern" },
"an URL-applied regexp-pattern and a substitution URL" },
"a mapname and a filename" },
"the filename of a lockfile used for inter-process synchronization"},
"the filename of the rewriting logfile" },
"the level of the rewriting logfile verbosity " "(0=none, 1=std, .., 9=max)" },
/* the ap_table_t of content handlers we provide */ /* the main config structure */ /* whether proxy module is available or not */ ** +-------------------------------------------------------+ ** | configuration directive handling ** +-------------------------------------------------------+ ** per-server configuration structure handling * local directives override * and anything else is inherited * local directives override * and anything else gets defaults ** per-directory configuration structure handling /* make sure it has a trailing slash */ ** the configuration commands else /* is per-directory command */ {
else {
/* is per-directory command */ return ap_pstrcat(p,
"RewriteOptions: unknown option '",
"because no NDBM support is compiled in");
else if (
strcmp(
a2+
4,
"toupper") == 0) {
else if (
strcmp(
a2+
4,
"unescape") == 0) {
"RewriteMap: map file or program not found:",
return "RewriteBase: only valid in per-directory config files";
return "RewriteBase: empty URL not allowed";
return "RewriteBase: argument is not a valid URL";
/* make a new entry in the internal temporary rewrite rule list */ else {
/* is per-directory command */ /* parse the argument line ourself */ /* arg1: the input string */ /* arg3: optional flags field (this have to be first parsed, because we need to know if the regex should be compiled with ICASE!) */ try to compile the regexp to test if is ok */ /* now be careful: Under the POSIX regex library we can compile the pattern for case insensitive matching, under the old V8 library we have to do it self via a hack */ "RewriteCond: cannot compile regular expression '",
return "RewriteCond: bad flag delimiters";
for ( ; (*
cp ==
' ' || *
cp ==
'\t') && *
cp !=
'\0';
cp++)
for ( ; (*(
cp2-
1) ==
' ' || *(
cp2-
1) ==
'\t');
cp2--)
/* make a new entry in the internal rewrite rule list */ else {
/* is per-directory command */ /* parse the argument line ourself */ /* arg3: optional flags field */ * try to compile the regexp to test if is ok "RewriteRule: cannot compile regular expression '",
/* arg2: the output string * replace the $<N> by \<n> which is needed by the currently * used Regular Expression library /* now, if the server or per-dir config holds an * array of RewriteCond entries, we take it for us else {
/* is per-directory command */ return "RewriteRule: bad flag delimiters";
for ( ; (*
cp ==
' ' || *
cp ==
'\t') && *
cp !=
'\0';
cp++)
for ( ; (*(
cp2-
1) ==
' ' || *(
cp2-
1) ==
'\t');
cp2--)
return "RewriteRule: invalid HTTP response code " return "RewriteRule: too many environment flags 'E'";
** Global Module Initialization ** [called from read_config() after all ** config commands were already called] /* check if proxy module is available */ /* create the rewriting lockfile in the parent */ /* step through the servers and * - open each rewriting logfile * - open the RewriteMap prg:xxx programs ** Per-Child Module Initialization ** [called after a child process is spawned] /* open the rewriting lockfile */ /* create the lookup cache */ ** +-------------------------------------------------------+ ** +-------------------------------------------------------+ ** [used for the rewriting engine triggered by ** the per-server 'RewriteRule' directives] * retrieve the config structures * only do something under runtime if the engine is really enabled, * else return immediately! * check for the ugly API case of a virtual host section where no * mod_rewrite directives exists. In this situation we became no chance * by the API to setup our default per-server config so we have to * on-the-fly assume we have the default config. But because the default * config has a disabled rewriting engine we are lucky because can * just stop operating now. * add the SCRIPT_URL variable to the env. this is a bit complicated * due to the fact that apache uses subrequests and internal redirects * create the SCRIPT_URI variable for the env /* add the canonical URI of this URL */ /* if filename was not initially set, * we start with the requested URI rewritelog(r,
2,
"init rewrite engine with requested uri %s",
* now apply the rules ... /* it should be go on as an internal proxy request */ /* check if the proxy module is enabled, so * we can actually use it! "attempt to make remote request from mod_rewrite " "without proxy enabled: %s", r->
filename);
/* make sure the QUERY_STRING and * PATH_INFO parts get incorporated /* see proxy_http:proxy_http_canon() */ /* now make sure the request gets handled by the proxy handler */ rewritelog(r,
1,
"go-ahead with proxy request %s [OK]",
/* it was finally rewritten to a remote URL */ for ( ; *
cp !=
'/' && *
cp !=
'\0';
cp++)
/* append the QUERY_STRING part */ /* determine HTTP redirect response code */ /* now do the redirection */ /* This URLs is forced to be forbidden for the requester */ /* This URLs is forced to be gone */ * Hack because of underpowered API: passing the current * rewritten filename through to other URL-to-filename handlers * just as it were the requested URL. This is to enable * post-processing by mod_alias, etc. which always act on * r->uri! The difference here is: We do not try to /* it was finally rewritten to a local path */ /* expand "/~user" prefix */ /* the filename has to start with a slash! */ /* if there is no valid prefix, we have * to emulate the translator from the core and * prefix the filename with document_root * We cannot leave out the prefix_stat because * - when we always prefix with document_root * then no absolute path can be created, e.g. via * emulating a ScriptAlias directive, etc. * - when we always NOT prefix with document_root * then the files under document_root have to * be references directly and document_root * gets never used and will be a dummy parameter - * Under real Unix systems this is no problem, * because we only do stat() on the first directory * and this gets cached by the kernel for along time! /* always NOT have a trailing slash */ rewritelog(r,
2,
"prefixed with document_root to %s",
** [used to support the forced-MIME-type feature] /* now check if we have to force a MIME-type */ rewritelog(r,
1,
"force filename %s to have MIME-type '%s'",
** [used for the rewriting engine triggered by ** the per-directory 'RewriteRule' directives] /* if there is no per-dir config we return immediately */ /* we shouldn't do anything in subrequests */ /* if there are no real (i.e. no RewriteRule directives!) per-dir config of us, we return also immediately */ * only do something under runtime if the engine is really enabled, * for this directory, else return immediately! /* FollowSymLinks is mandatory! */ "Options FollowSymLinks or SymLinksIfOwnerMatch is off " "which implies that RewriteRule directive is forbidden: " /* FollowSymLinks is given, but the user can * still turn off the rewriting engine * 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. * now apply the rules ... /* it should go on as an internal proxy request */ /* make sure the QUERY_STRING and * PATH_INFO parts get incorporated * (r->path_info was already appended by the * rewriting engine because of the per-dir context!) /* now make sure the request gets handled by the proxy handler */ rewritelog(r,
1,
"[per-dir %s] go-ahead with proxy request " /* it was finally rewritten to a remote URL */ /* because we are in a per-dir context * first try to replace the directory with its base-URL * if there is a base-URL available "[per-dir %s] trying to replace " /* now prepare the redirect... */ for ( ; *
cp !=
'/' && *
cp !=
'\0';
cp++)
rewritelog(r,
1,
"[per-dir %s] escaping %s for redirect",
/* append the QUERY_STRING part */ /* determine HTTP redirect response code */ /* now do the redirection */ rewritelog(r,
1,
"[per-dir %s] redirect to %s [REDIRECT/%d]",
/* This URL is forced to be forbidden for the requester */ /* This URL is forced to be gone */ /* it was finally rewritten to a local path */ /* if someone used the PASSTHROUGH flag in per-dir * context we just ignore it. It is only useful /* the filename has to start with a slash! */ /* 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. rewritelog(r,
1,
"[per-dir %s] initial URL equal rewritten " "URL: %s [IGNORING REWRITE]",
/* 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 * context. If not then treat the result as a "[per-dir %s] trying to replace prefix %s with %s",
/* if no explicit base-URL exists we assume * that the directory prefix is also a valid URL * for this webserver and only try to remove the * document_root if it is prefix /* always NOT have a trailing slash */ "[per-dir %s] strip document_root " /* now initiate the internal redirect */ rewritelog(r,
1,
"[per-dir %s] internal redirect with %s " ** [used for redirect support] /* just make sure that we are really meant! */ /* now do the internal redirect */ /* and return gracefully */ ** +-------------------------------------------------------+ ** | the rewriting engine ** +-------------------------------------------------------+ * Apply a complete rule set, * i.e. a list of rewrite rules * Iterate over all existing rules * Ignore this rule on subrequests if we are explicitly * asked to do so or this is a proxy-throughput or a * Apply the current rule. * Indicate a change if this was not a match-only rule. * Pass-Through Feature (`RewriteRule .. .. [PT]'): * Because the Apache 1.x API is very limited we * need this hack to pass the rewritten URL to other * modules like mod_alias, mod_userdir, etc. rewritelog(r,
2,
"forcing '%s' to get passed through " "to next API URI-to-filename handler", r->
filename);
* Rule has the "forbidden" flag set which means that * we stop processing and indicate this to the caller. * Rule has the "gone" flag set which means that * we stop processing and indicate this to the caller. * Stop processing also on proxy pass-through and * last-rule and new-round flags. * On "new-round" flag we just start from the top of * the rewriting ruleset again. * If we are forced to skip N next rules, do it now. * If current rule is chained with next rule(s), * skip all this next rule(s) * Apply a single(!) rewrite rule * Add (perhaps splitted away) PATH_INFO postfix to URL to * make sure we really match against the complete URL. rewritelog(r,
3,
"[per-dir %s] add path info postfix: %s -> %s%s",
* On per-directory context (.htaccess) strip the location * prefix from the URL to make sure patterns apply only to * the local part. Additionally indicate this special * threatment in the logfile. rewritelog(r,
3,
"[per-dir %s] strip per-dir prefix: %s -> %s",
* Try to match the URI against the RewriteRule pattern * and exit immeddiately if it didn't apply. rewritelog(r,
3,
"applying pattern '%s' to uri '%s'",
rewritelog(r,
3,
"[per-dir %s] applying pattern '%s' to uri '%s'",
* Else create the RewriteRule `regsubinfo' structure which * holds the substitution information. /* empty info on negative patterns */ * Initiallally create the RewriteCond backrefinfo with * empty backrefinfo, i.e. not subst parts * (this one is adjusted inside apply_rewrite_cond() later!!) * Ok, we already know the pattern has matched, but we now * additionally have to check for all existing preconditions * (RewriteCond) which have to be also true. We do this at * this very late stage to avoid unnessesary checks which * would slow down the rewriting engine!! /* One condition is false, but another can be * still true, so we have to continue... /* One true condition is enough in "or" case, so * skip the other conditions which are "ornext" * The "AND" case, i.e. no "or" flag, * so a single failure means total failure. /* if any condition fails the complete rule fails */ * Regardless of what we do next, we've found a match. Check to see * if any of the request header fields were involved, and add them * to the Vary field of the response. * If this is a pure matching rule (`RewriteRule <pat> -') * we stop processing and return immediately. The only thing * we have not to forget are the environment variables * (`RewriteRule <pat> - [E=...]') for (i = 0; p->
env[i] !=
NULL; i++) {
/* 2. expand $N (i.e. backrefs to RewriteRule pattern) */ /* 3. expand %N (i.e. backrefs to latest RewriteCond pattern) */ /* 4. expand %{...} (i.e. variables) */ /* 5. expand ${...} (RewriteMap lookups) */ /* and add the variable to Apache's structures */ /* In the per-server context we can force the MIME-type * the correct way by notifying our MIME-type hook handler * to do the job when the MIME-type API stage is reached. rewritelog(r,
2,
"remember %s to have MIME-type '%s'",
/* In per-directory context we operate in the Fixup API hook * which is after the MIME-type hook, so our MIME-type handler * has no chance to set r->content_type. And because we are * in the situation where no substitution takes place no * sub-request will happen (which could solve the * restriction). As a workaround we do it ourself now * immediately although this is not strictly API-conforming. * But it's the only chance we have... rewritelog(r,
1,
"[per-dir %s] force %s to have MIME-type " * Ok, now we finally know all patterns have matched and * that there is something to replace, so we create the * substitution URL string in `newuri'. /* 1. take the output string */ /* 2. expand $N (i.e. backrefs to RewriteRule pattern) */ /* 3. expand %N (i.e. backrefs to latest RewriteCond pattern) */ /* 4. expand %{...} (i.e. variables) */ /* 5. expand ${...} (RewriteMap lookups) */ /* and log the result... */ * Additionally do expansion for the environment variable * strings (`RewriteRule .. .. [E=<string>]'). for (i = 0; p->
env[i] !=
NULL; i++) {
/* 2. expand $N (i.e. backrefs to RewriteRule pattern) */ /* 3. expand %N (i.e. backrefs to latest RewriteCond pattern) */ /* 4. expand %{...} (i.e. variables) */ /* 5. expand ${...} (RewriteMap lookups) */ /* and add the variable to Apache's structures */ * Now replace API's knowledge of the current URI: * Replace r->filename with the new URI string and split out * an on-the-fly generated QUERY_STRING part into r->args * Again add the previously stripped per-directory location * prefix if the new URI is not a new one for this * location, i.e. if it's not starting with either a slash * or a fully qualified URL scheme. rewritelog(r,
3,
"[per-dir %s] add per-dir prefix: %s -> %s%s",
* If this rule is forced for proxy throughput * (`RewriteRule ... ... [P]') then emulate mod_proxy's * URL-to-filename handler to be sure mod_proxy is triggered * for this URL later in the Apache API. But make sure it is * a fully-qualified URL. (If not it is qualified with rewritelog(r,
2,
"[per-dir %s] forcing proxy-throughput with %s",
* If this rule is explicitly forced for HTTP redirection * (`RewriteRule .. .. [R]') then force an external HTTP * redirect. But make sure it is a fully-qualified URL. (If * not it is qualified with ourself). "explicitly forcing redirect with %s", r->
filename);
"[per-dir %s] explicitly forcing redirect with %s",
* Special Rewriting Feature: Self-Reduction * We reduce the URL by stripping a possible * http[s]://<ourhost>[:<port>] prefix, i.e. a prefix which * corresponds to ourself. This is to simplify rewrite maps * and to avoid recursion, etc. When this prefix is not a * coincidence then the user has to use [R] explicitly (see * If this rule is still implicitly forced for HTTP * redirection (`RewriteRule .. <scheme>://...') then * directly force an external HTTP redirect. "implicitly forcing redirect (rc=%d) with %s",
rewritelog(r,
2,
"[per-dir %s] implicitly forcing redirect " * Now we are sure it is not a fully qualified URL. But * there is still one special case left: A local rewrite in * per-directory context, i.e. a substitution URL which does * not start with a slash. Here we add again the initially * stripped per-directory prefix. rewritelog(r,
3,
"[per-dir %s] add per-dir prefix: %s -> %s%s",
* Finally we had to remember if a MIME-type should be * forced for this URL (`RewriteRule .. .. [T=<type>]') * Later in the API processing phase this is forced by our * MIME API-hook function. This time its no problem even for * the per-directory context (where the MIME-type hook was * already processed) because a sub-request happens ;-) rewritelog(r,
2,
"remember %s to have MIME-type '%s'",
"[per-dir %s] remember %s to have MIME-type '%s'",
* Puuhhhhhhhh... WHAT COMPLICATED STUFF ;_) * But now we're done for this particular rule. * Construct the string we match against /* 2. expand $N (i.e. backrefs to RewriteRule pattern) */ /* 3. expand %N (i.e. backrefs to latest RewriteCond pattern) */ /* 4. expand %{...} (i.e. variables) */ /* 5. expand ${...} (RewriteMap lookups) */ /* avoid infinite subrequest recursion */ && ( r->
main ==
NULL /* - either not in a subrequest */ || ( r->
main->
uri !=
NULL /* - or in a subrequest... */ && r->
uri !=
NULL /* ...and URIs aren't NULL... */ /* run a URI-based subrequest */ /* URI exists for any result up to 3xx, redirects allowed */ /* cleanup by destroying the subrequest */ /* avoid infinite subrequest recursion */ && ( r->
main ==
NULL /* - either not in a subrequest */ || ( r->
main->
uri !=
NULL /* - or in a subrequest... */ && r->
uri !=
NULL /* ...and URIs aren't NULL... */ /* process a file-based subrequest: * this differs from -U in that no path translation is done. /* file exists for any result up to 2xx, no redirects */ /* double-check that file exists since default result is 200 */ rewritelog(r,
5,
"RewriteCond file (-F) check: path=%s " /* cleanup by destroying the subrequest */ /* it is really a regexp pattern, so apply it */ /* if it isn't a negated pattern and really matched we update the passed-through regex subst info structure */ /* if this is a non-matching regexp, just negate the result */ rewritelog(r,
4,
"RewriteCond: input='%s' pattern='%s%s' => %s",
/* end just return the result */ ** +-------------------------------------------------------+ ** | URL transformation functions ** +-------------------------------------------------------+ ** split out a QUERY_STRING part from ** the current URI string ** strip 'http[s]://ourhost/' from URI /* there was really a rewrite to a remote path */ /* cut the hostname and port out of the URI */ for (; *
cp !=
'\0' && *
cp !=
'/';
cp++)
/* now check whether we could reduce it to a local path... */ /* this is our host, so only the URL remains */ ** add 'http[s]://ourhost[:ourport]/' to URI ** if URI is still not fully qualified ** Expand the %0-%9 or $0-$9 regex backreferences /* 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))) {
else if (
buf[i] ==
'&') {
else if (c !=
'$' &&
buf[i] ==
'$' && (
buf[i+
1] >=
'0' &&
buf[i+
1] <=
'9')) {
else if (
buf[i] == c && (
buf[i+
1] >=
'0' &&
buf[i+
1] <=
'9')) {
/* now apply the standard regex substitution function */ /* restore the original $N and & backrefs */ for (i = 0;
buf[i] !=
'\0' && i <
nbuf; i++) {
else if (
buf[i] ==
'\002') {
** Expand tilde-paths (/~user) through /* cut out the username */ for (j = 0, i =
2; j <
sizeof(
user)-
1 /* lookup username in systems passwd file */ /* ok, user was found, so expand the ~user string */ /* only ~user has to be expanded */ ** mapfile expansion support ** i.e. expansion of MAP lookup directives ** ${<mapname>:<key>} in RewriteRule rhs /* missing delimiter -> take it as plain text */ 0, r,
"insufficient space in " "expand_map_lookups, aborting");
0, r,
"insufficient space in " "expand_map_lookups, aborting");
0, r,
"insufficient space in " "expand_map_lookups, aborting");
** +-------------------------------------------------------+ ** | DBM hashfile support ** +-------------------------------------------------------+ /* get map configuration */ "mod_rewrite: can't access text RewriteMap " rewritelog(r,
6,
"cache lookup FAILED, forcing new " rewritelog(r,
5,
"map lookup OK: map=%s key=%s[txt] " rewritelog(r,
5,
"map lookup FAILED: map=%s[txt] " rewritelog(r,
5,
"cache lookup OK: map=%s[txt] key=%s " "mod_rewrite: can't access DBM RewriteMap " rewritelog(r,
1,
"can't open DBM RewriteMap file, " "cache lookup FAILED, forcing new map lookup");
rewritelog(r,
5,
"map lookup OK: map=%s[dbm] key=%s " rewritelog(r,
5,
"map lookup FAILED: map=%s[dbm] " rewritelog(r,
5,
"cache lookup OK: map=%s[dbm] key=%s " rewritelog(r,
5,
"map lookup OK: map=%s key=%s -> val=%s",
rewritelog(r,
5,
"map lookup FAILED: map=%s key=%s",
rewritelog(r,
5,
"map lookup OK: map=%s key=%s -> val=%s",
rewritelog(r,
5,
"map lookup FAILED: map=%s key=%s",
"mod_rewrite: can't access text RewriteMap " rewritelog(r,
6,
"cache lookup FAILED, forcing new " rewritelog(r,
5,
"map lookup OK: map=%s key=%s[txt] " rewritelog(r,
5,
"map lookup FAILED: map=%s[txt] " rewritelog(r,
5,
"cache lookup OK: map=%s[txt] key=%s " continue;
/* ignore comments */ continue;
/* ignore lines that start with a space, tab, CR, or LF */ continue;
/* key does not match... */ /* found a matching key; now extract and return the value */ continue;
/* no value... */ /* when `RewriteEngine off' was used in the per-server * context then the rewritemap-programs were not spawned. * In this case using such a map (usually in per-dir context) * is useless because it is not available. /* write out the request key */ /* read in the response value */ /* currently we just let the function convert the key to a corresponding value */ /* 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. /* count number of distinct values */ for (n =
1, i = 0;
value[i] !=
'\0'; i++) {
/* when only one value we have no option to choose */ /* else randomly select one */ for (n =
1, i = 0;
value[i] !=
'\0'; i++) {
for (i = 0;
buf[i] !=
'\0' &&
buf[i] !=
'|'; i++)
** +-------------------------------------------------------+ ** | rewriting logfile support ** +-------------------------------------------------------+ return;
/* virtual log shared w/ main server */ "mod_rewrite: could not open reliable pipe " "mod_rewrite: could not open RewriteLog " "%s %s [%s/sid#%lx][rid#%lx/%s%s] (%d) %s\n",
str1,
(
unsigned long)(r->
server), (
unsigned long)r,
** +-------------------------------------------------------+ ** | rewriting lockfile support ** +-------------------------------------------------------+ /* only operate if a lockfile is used */ /* fixup the path, especially for rewritelock_remove() */ /* create the lockfile */ "mod_rewrite: Parent could not create RewriteLock " /* make sure the childs have access to this file */ if (
geteuid() == 0
/* is superuser */)
/* only operate if a lockfile is used */ /* open the lockfile (once per child) to get a unique fd */ "mod_rewrite: Child could not open RewriteLock " /* only operate if a lockfile is used */ /* remove the lockfile */ ** +-------------------------------------------------------+ ** +-------------------------------------------------------+ /* If the engine isn't turned on, * don't even try to do anything. "mod_rewrite: could not fork child for " "RewriteMap process. %d",
rc);
/* Something bad happened, give up and go away. */ ** +-------------------------------------------------------+ ** | environment variable support ** +-------------------------------------------------------+ /* all other headers from which we are still not know about */ else if (
strcasecmp(
var,
"THE_REQUEST") == 0) {
/* non-standard */ else if (
strcasecmp(
var,
"REQUEST_URI") == 0) {
/* non-standard */ /* internal server stuff */ else if (
strcasecmp(
var,
"SERVER_ADDR") == 0) {
/* non-standard */ else if (
strcasecmp(
var,
"API_VERSION") == 0) {
/* non-standard */ /* underlaying Unix system stuff */ "%02d%02d%02d%02d%02d%02d%02d", (
tm->
tm_year /
100) +
19,
/* all other env-variables from the parent Apache process */ /* first try the internal Apache notes structure */ /* second try the internal Apache env structure */ /* third try the external OS env */ /* filename is safe to use */ \
/* - and we're either not in a subrequest */ \
/* - or in a subrequest where paths are non-NULL... */ \
/* ...and sub and main paths differ */ \
/* process a file-based subrequest */ \
/* now recursively lookup the variable in the sub_req */ \
/* copy it up to our scope before we destroy sub_req's ap_context_t */ \
/* cleanup by destroying the subrequest */ \
rewritelog(r,
5,
"lookahead: path=%s var=%s -> val=%s", \
/* return ourself to prevent re-pstrdup */ \
/* look-ahead for parameter through URI-based sub-request */ /* look-ahead for parameter through file-based sub-request */ /* Win32 has a rather different view of file ownerships. For now, just forget it */ #
endif /* ndef WIN32 && NETWARE*/** +-------------------------------------------------------+ ** +-------------------------------------------------------+ for (p=
key; *p !=
'\0'; ++p) {
n = n *
53711 +
134561 + (
unsigned)(*p &
0xff);
/* first try to edit an existing entry */ /* create a needed new list */ /* create the new entry */ /* not reached, but when it is no problem... */ ** +-------------------------------------------------------+ ** +-------------------------------------------------------+ /* first create a match string which always has a trailing slash */ /* now compare the prefix */ /* and now add the base-URL as replacement prefix */ ** own command line parser which don't have the '\\' problem for ( ; *
cp ==
' ' || *
cp ==
'\t'; ) { \
for ( ; *
cp !=
'\0';
cp++) { \
|| (*
cp ==
'\\' && (*(
cp+
1) ==
' ' || *(
cp+
1) ==
'\t'))) { \
/* determine first argument */ /* determine second argument */ /* again check if there are only two arguments */ /* determine second argument */ ** stat() for only the prefix of a path /* Lock the first byte, always, assume we want to append and seek to the end afterwards */ "mod_rewrite: failed to lock file descriptor");
"mod_rewrite: failed to unlock file descriptor");
for (i = 0; i <
n1; i++) {