mod_rewrite.c revision 4a13940dc2990df0a798718d3a3f9cf1566c2217
6666N/A/* Licensed to the Apache Software Foundation (ASF) under one or more 6666N/A * contributor license agreements. See the NOTICE file distributed with 6666N/A * this work for additional information regarding copyright ownership. 6666N/A * The ASF licenses this file to You under the Apache License, Version 2.0 6666N/A * (the "License"); you may not use this file except in compliance with 6666N/A * the License. You may obtain a copy of the License at 6666N/A * Unless required by applicable law or agreed to in writing, software 6666N/A * distributed under the License is distributed on an "AS IS" BASIS, 6666N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 6666N/A * See the License for the specific language governing permissions and 6666N/A * limitations under the License. 6666N/A * _ __ ___ ___ __| | _ __ _____ ___ __(_) |_ ___ 6666N/A * | '_ ` _ \ / _ \ / _` | | '__/ _ \ \ /\ / / '__| | __/ _ \ 6666N/A * | | | | | | (_) | (_| | | | | __/\ V V /| | | | || __/ 6666N/A * |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___| 6666N/A * This module uses a rule-based rewriting engine (based on a 6666N/A * regular-expression parser) to rewrite requested URLs on the fly. 6666N/A * It supports an unlimited number of additional rule conditions (which can 6666N/A * operate on a lot of variables, even on HTTP headers) for granular 6666N/A * matching and even external database lookups (either via plain text 6666N/A * tables, DBM hash files or even external processes) for advanced URL 6666N/A * It operates on the full URLs (including the PATH_INFO part) both in 6666N/A * can generate QUERY_STRING parts on result. The rewriting result finally 6666N/A * can lead to internal subprocessing, external request redirection or even 6666N/A * to internal proxy throughput. 6666N/A * This module was originally written in April 1996 and 6666N/A * gifted exclusively to the The Apache Software Foundation in July 1997 by /* XXX: Do we really need these headers? */ * in order to improve performance on running production systems, you * may strip all rewritelog code entirely from mod_rewrite by using the * -DREWRITELOG_DISABLED compiler option. * DO NOT USE THIS OPTION FOR PUBLIC BINARY RELEASES. Otherwise YOU are * responsible for answering all the mod_rewrite questions out there. #
else /* !REWRITELOG_DISABLED */#
endif /* REWRITELOG_DISABLED *//* remembered mime-type for [T=...] */ /* return code of the rewrite rule * the result may be escaped - or not /* max cookie size in rfc 2109 */ /* XXX: not used at all. We should do a check somewhere and/or cut the cookie */ /* max line length (incl.\n) in text rewrite maps */ /* buffer length for prg rewrite maps */ /* for better readbility */ * expansion result items on the stack to save some cycles * (5 == about 2 variables like "foo%{var}bar%{var}baz") * check that a subrequest won't cause infinite recursion * either not in a subrequest, or in a subrequest * and URIs aren't NULL and sub/main URIs differ * +-------------------------------------------------------+ * +-------------------------------------------------------+ const char *
datafile;
/* filename for map data files */ const char *
dbmtype;
/* dbm type for dbm map data files */ const char *
checkfile;
/* filename to check for map existence */ int type;
/* the type of the map */ char **
argv;
/* argv of the external rewrite map */ const char *
dbdq;
/* SQL SELECT statement for rewritemap */ const char *
checkfile2;
/* filename to check for map existence /* special pattern types for RewriteCond */ char *
input;
/* Input string of RewriteCond */ char *
pattern;
/* the RegExp pattern string */ int flags;
/* Flags which control the match */ /* single linked list for env vars and cookies */ char *
pattern;
/* the RegExp pattern string */ char *
output;
/* the Substitution string */ int flags;
/* Flags which control the substitution */ int skip;
/* number of next rules to skip */ int state;
/* the RewriteEngine state */ int options;
/* the RewriteOption state */ int state;
/* the RewriteEngine state */ int options;
/* the RewriteOption state */ char *
directory;
/* the directory where it applies */ const char *
baseurl;
/* the base-URL where it applies */ /* the (per-child) cache structures. /* cached maps contain an mtime for the whole map and live in a subpool * of the cachep->pool. That makes it easy to forget them if necessary. /* the regex structure for the * substitution of backreferences /* single linked list used for /* context structure for variable lookup and expansion * +-------------------------------------------------------+ * +-------------------------------------------------------+ /* the global module structure */ /* rewritemap int: handler function registry */ /* whether proxy module is available or not */ /* whether random seed can be reaped */ /* Optional functions imported from mod_ssl when loaded: */ * +-------------------------------------------------------+ * | rewriting logfile support * +-------------------------------------------------------+ /* - no logfile configured * - virtual log shared w/ main server "mod_rewrite: Invalid RewriteLog " "mod_rewrite: could not open reliable pipe " "to RewriteLog filter %s",
fname);
"mod_rewrite: Invalid RewriteLog " "mod_rewrite: could not open RewriteLog " r->
main ?
"subreq" :
"initial",
#
endif /* !REWRITELOG_DISABLED */ * +-------------------------------------------------------+ * | URI and path functions * +-------------------------------------------------------+ /* return number of chars of the scheme (incl. '://') * if the URI is absolute (includes a scheme etc.) * NOTE: If you add new schemes here, please have a * look at escape_absolute_uri and splitout_queryargs. * Not every scheme takes query strings and some schemes * may be handled in a special way. * XXX: we may consider a scheme registry, perhaps with * appropriate escape callbacks to allow other modules * to extend mod_rewrite at runtime. static const char c2x_table[] =
"0123456789abcdef";
#
endif /*APR_CHARSET_EBCDIC*/ * Escapes a uri in a similar way as php's urlencode does. const unsigned char *s = (
const unsigned char *)
path;
unsigned char *d = (
unsigned char *)
copy;
* escape absolute uri, which may or may not be path oriented. * So let's handle them differently. * NULL should indicate elsewhere, that something's wrong /* scheme with authority part? */ while (*
cp && *
cp !=
'/') {
/* nothing after the hostpart. ready! */ /* remember the hostname stuff */ /* special thing for ldap. * The parts are separated by question marks. From RFC 2255: * ldapurl = scheme "://" [hostport] ["/" * [dn ["?" [attributes] ["?" [scope] * ["?" [filter] ["?" extensions]]]]]] /* Nothing special here. Apply normal escaping. */ * split out a QUERY_STRING part from /* don't touch, unless it's an http or mailto URL. * See RFC 1738 and RFC 2368. r->
args =
NULL;
/* forget the query that's still flying around */ * strip 'http[s]://ourhost/' from URI /* cut the hostname and port out of the URI */ while (*
cp && *
cp !=
'/' && *
cp !=
':') {
if (*
cp ==
':') {
/* additional port given */ while (*
cp && *
cp !=
'/') {
else if (*
cp ==
'/') {
/* default port */ /* now check whether we could reduce it to a local path... */ * add 'http[s]://ourhost[:ourport]/' to URI * if URI is still not fully qualified * stat() only the first segment of a path /* let's recognize slashes only, the mod_rewrite semantics are opaque * substitute the prefix path 'match' in 'input' with 'subst' (RewriteBase) /* prefix didn't match */ * +-------------------------------------------------------+ * +-------------------------------------------------------+ /* Now we should have a valid map->entries hash, where we * We need to copy the key and the value into OUR pool, * so that we don't leave it during the r->pool cleanup. /* if this map is outdated, forget it. */ /* copy the cached value into the supplied pool, * where it belongs (r->pool usually) * +-------------------------------------------------------+ * +-------------------------------------------------------+ * General Note: key is already a fresh string, created (expanded) just * for the purpose to be passed in here. So one can modify key itself. /* count number of distinct values */ /* initialize random generator * XXX: Probably this should be wrapped into a thread mutex, * shouldn't it? Is it worth the effort? /* select a random subvalue */ /* extract it from the whole string */ if (
value) {
/* should not be NULL, but ... */ /* If the engine isn't turned on, * don't even try to do anything. "mod_rewrite: Running external rewrite maps " "without defining a RewriteLock is DANGEROUS!");
"mod_rewrite: could not start RewriteMap " * +-------------------------------------------------------+ * +-------------------------------------------------------+ /* ignore comments and lines starting with whitespaces */ /* key doesn't match - ignore. */ /* extract the value and return. */ "rewritemap: error %s querying for %s",
errmsg,
key);
/* randomise crudely amongst multiple results */ "rewritemap: error %s looking up %s",
errmsg,
key);
/* what's a fair rewritelog level for this? */ /* 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. * newlines in the key leave bytes in the pipe and cause * bad things to happen (next map lookup will use the chars * after the \n instead of the new key etc etc - in other words, * the Rewritemap falls out of sync with the requests). "apr_global_mutex_lock(rewrite_mapr_lock_acquire) " return NULL;
/* Maybe this should be fatal? */ /* write out the request key */ /* read in the response value */ /* remove eol from the buffer */ /* only partial (invalid) eol sequence -> reset the counter */ /* catch binary mode, e.g. on Win32 */ /* well, if there wasn't a newline yet, we need to read further */ "apr_global_mutex_unlock(rewrite_mapr_lock_acquire) " return NULL;
/* Maybe this should be fatal? */ /* catch the "failed" case */ /* get map configuration */ * Text file map (perhaps random) "mod_rewrite: can't access text RewriteMap file %s",
"can't open RewriteMap file, see error log"));
"cache lookup FAILED, forcing new map lookup"));
"mod_rewrite: can't access DBM RewriteMap file %s",
"mod_rewrite: can't access DBM RewriteMap " "can't open DBM RewriteMap file, see error log"));
"cache lookup FAILED, forcing new map lookup"));
rewritelog((r,
5,
NULL,
"cache lookup OK: map=%s[dbm] key=%s -> val=%s",
"cache lookup FAILED, forcing new map lookup"));
rewritelog((r,
5,
NULL,
"cache lookup OK: map=%s[SQL] key=%s, val=%s",
* lookup a HTTP header and set VARY note * lookahead helper function * Determine the correct URI path in perdir context * generic variable lookup /* fast tests for variable length variables (sic) first */ else if (
var[
4] ==
':') {
/* sigh, the user wants a file based subrequest, but * we can't do one, since we don't know what the file * path is! In this case behave like LA-U. /* well, do it the hard way */ /* can't do this above, because of the getenv call */ * +-------------------------------------------------------+ * +-------------------------------------------------------+ * Bracketed expression handling * s points after the opening bracket for (
depth =
1; *s; ++s) {
for (
depth =
1; *s; ++s) {
if (*s == c &&
depth ==
1) {
/* perform all the expansions on the input string * putting the result into a new string * for security reasons this expansion must be performed in a * single pass, otherwise an attacker can arrange for the result * of an earlier expansion to include expansion specifiers that * are interpreted by a later expansion, producing results that * were not intended by the administrator. /* well, actually something to do */ /* variable or map lookup */ * To make rewrite maps useful, the lookup key and * default values must be expanded, so we make * recursive calls to do the work. For security * reasons we must never expand a string that includes * verbatim data from the network. The recursion here * isn't a problem because the result of expansion is * only passed to lookup_map() so it cannot be * re-expanded, only re-looked-up. Another way of * looking at it is that the recursion is entirely * driven by the syntax of the nested curly brackets. /* reuse of key variable as result */ /* escape the backreference */ /* not for us, just copy it */ /* check the remainder */ * perform all the expansions on the environment variables * perform all the expansions on the cookies * TODO: use cached time similar to how logging does it * Expand tilde-paths (/~user) through Unix /etc/passwd * database information (or other OS-specific database) while (*p && *p !=
'/') {
/* reuse of user variable */ #
endif /* if APR_HAS_USER */ * +-------------------------------------------------------+ * | rewriting lockfile support * +-------------------------------------------------------+ /* only operate if a lockfile is used */ /* create the lockfile */ "mod_rewrite: Parent could not create RewriteLock " "mod_rewrite: Parent could not set permissions " "on RewriteLock; check User and Group directives");
/* only operate if a lockfile is used */ /* destroy the rewritelock */ * +-------------------------------------------------------+ * | configuration directive handling * +-------------------------------------------------------+ * own command line parser for RewriteRule and RewriteCond, * which doesn't have the '\\' problem. * (returns true on error) * XXX: what an inclined parser. Seems we have to leave it so * for backwards compat. *sigh* * determine first argument * determine second argument *
a3 =
NULL;
/* 3rd argument is optional */ *
a3 =
NULL;
/* 3rd argument is still optional */ * determine third argument * local directives override * and anything else is inherited * local directives override * and anything else gets defaults /* make sure it has a trailing slash */ else /* is per-directory command */ {
"RewriteOptions: MaxRedirects option has been " "removed in favor of the global " "LimitInternalRecursion directive and will be " /* put it into the appropriate config */ else {
/* is per-directory command */ return "RewriteMap types dbd and fastdbd require mod_dbd!";
if ((
a2[0] ==
'd') || (
a2[0] ==
'D')) {
"RewriteMap: file for map ",
a1,
/* fixup the path, especially for rewritelock_remove() */ return "RewriteBase: only valid in per-directory config files";
return "RewriteBase: empty URL not allowed";
return "RewriteBase: argument is not a valid URL";
* generic lexer for RewriteRule and RewriteCond flags. * The parser will be passed in as a function pointer * and called if a flag was found return "bad flag delimiters";
*
endp =
',';
/* for simpler parsing */ /* skip leading spaces */ /* strip trailing spaces */ /* make a new entry in the internal temporary rewrite rule list */ else {
/* is per-directory command */ /* parse the argument line ourself * a1 .. a3 are substrings of str, which is a fresh copy * of the argument line. So we can use a1 .. a3 without /* arg1: the input string */ /* arg3: optional flags field * (this has to be parsed first, because we need to * know if the regex should be compiled with ICASE!) /* determine the pattern type */ if (!
a2[
2] && *
a2 ==
'-') {
/* "" represents an empty string */ if (*++
a2 ==
'"' &&
a2[
1] ==
'"' && !
a2[
2]) {
"RewriteCond: NoCase option for non-regex pattern '%s' " "is not supported and will be ignored.",
a2);
"expression '",
a2,
"'",
NULL);
else if (((*
key ==
'O' || *
key ==
'o') && !
key[
1])
if (((*
key ==
'E' || *
key ==
'e') && !
key[
1])
else if (((*
key ==
'S' || *
key ==
's') && !
key[
1])
else if (((*
key ==
'C' || *
key ==
'c') && !
key[
1])
else if (((*
key ==
'T' || *
key ==
't') && !
key[
1])
"response code '%s' for " /* 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 */ if (*
a2 ==
'-' && !
a2[
1]) {
/* now, if the server or per-dir config holds an * array of RewriteCond entries, we take it for us else {
/* is per-directory command */ * +-------------------------------------------------------+ * +-------------------------------------------------------+ /* Lexicographic Compare */ for (i = 0; i <
lena; ++i) {
return ((
unsigned char)a[i] > (
unsigned char)b[i]) ?
1 : -
1;
* Apply a single rewriteCond /* double-check that file exists since default result is 200 */ /* it is really a regexp pattern, so apply it */ /* update briRC backref info */ rc ?
"matched" :
"not-matched"));
/* check for forced type and handler */ * Apply a single RewriteRule /* Since we want to match against the (so called) full URL, we have * to re-add the PATH_INFO postfix /* Additionally we strip the physical path from the url to match * it independent from the underlaying filesystem. /* Try to match the URI against the RewriteRule pattern * and exit immediately if it didn't apply. /* It matched, wow! Now it's time to prepare the context structure for /* 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. * Reset vary_this if the novary flag is set for this condition. /* One condition is false, but another can be still true. */ /* skip the rest of the chained OR conditions */ /* If some HTTP header was involved in the condition, remember it /* expand [E=var:val] and [CO=<cookie>] */ /* non-substitution rules ('RewriteRule <pat> -') end here. */ /* Now adjust API's knowledge about r->filename and r->args */ /* Add the previously stripped per-directory location prefix, unless * (1) it's an absolute URL path and * (2) it's a full qualified URL /* 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 /* For rules evaluated in server context, the mod_proxy fixup * hook can be relied upon to escape the URI as and when * necessary, since it occurs later. If in directory context, * the ordering of the fixup hooks is forced such that * mod_proxy comes first, so the URI must be escaped here * instead. See PR 39746, 46428, and other headaches. */ /* 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). /* 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. /* Finally remember the forced mime-type */ /* Puuhhhhhhhh... WHAT COMPLICATED STUFF ;_) * But now we're done for this particular rule. * 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. /* 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. * The rule sets the response code (implies match-only) * 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. "to next API URI-to-filename handler", r->
filename));
* 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) * +-------------------------------------------------------+ * | Module Initialization Hooks * +-------------------------------------------------------+ /* register int: rewritemap handlers */ /* check if proxy module is available */ /* step through the servers and * - open each rewriting logfile * - open the RewriteMap prg:xxx programs apr_status_t rv = 0;
/* get a rid of gcc warning (REWRITELOG_DISABLED) */ "mod_rewrite: could not init rewrite_mapr_lock_acquire" /* create the lookup cache */ "mod_rewrite: could not init map cache in child");
* +-------------------------------------------------------+ * +-------------------------------------------------------+ * [deals with RewriteRules in server context] * 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 * 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 */ /* it was finally rewritten to a remote URL */ /* append the QUERY_STRING part */ /* determine HTTP redirect response code */ /* now do the redirection */ * 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 must be either an absolute local path or an /* if there is no valid prefix, we call * 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! * [RewriteRules in directory context] /* if there is no per-dir config we return immediately */ /* if there are no real (i.e. no RewriteRule directives!) per-dir config of us, we return also immediately */ * .htaccess file is called before really entering the directory, i.e.: * Ignore such attempts, since they may lead to undefined behaviour. * only do something under runtime if the engine is really enabled, * for this directory, else return immediately! * Do the Options check after engine check, so * the user is able to explicitely turn RewriteEngine Off. /* FollowSymLinks is mandatory! */ "Options FollowSymLinks or SymLinksIfOwnerMatch is off " "which implies that RewriteRule directive is forbidden: " * 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. * also, we'll restore original r->filename if we decline this * 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 */ /* 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 "trying to replace prefix %s with %s",
/* I think, that hack needs an explanation: * mod_rewrite was written for unix systems, were * absolute file-system paths start with a slash. * URL-paths _also_ start with slashes, so they * can be easily compared with system paths. * the following assumes, that the actual url-path * may be prefixed by the current directory path and * tries to replace the system path with the RewriteBase * That assumption is true if we use a RewriteRule like * RewriteRule ^foo bar [R] * (see apply_rewrite_rule function) * However on systems that don't have a / as system * root this will never match, so we skip the / after the * (note that cp was already increased to the right value) /* now prepare the redirect... */ /* append the QUERY_STRING part */ /* determine HTTP redirect response code */ /* now do the redirection */ /* 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 must be either an absolute local path or an /* 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. " URL: %s [IGNORING REWRITE]", r->
filename));
/* 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 /* 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 /* strip trailing slash */ /* now initiate the internal redirect */ * [T=...,H=...] execution "Content-handler '%s'", r->
filename, t));
* "content" handler for internal redirects /* just make sure that we are really meant! */ /* now do the internal redirect */ /* and return gracefully */ * +-------------------------------------------------------+ * +-------------------------------------------------------+ return "RewriteLog and RewriteLogLevel are not supported by this build " "of mod_rewrite because it was compiled using the " "-DREWRITELOG_DISABLED compiler option. You have to recompile " "mod_rewrite WITHOUT this option in order to use the rewrite log.";
"On or Off to enable or disable (default) the whole " "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 " "the filename of the rewriting logfile"),
"the level of the rewriting logfile verbosity " "(0=none, 1=std, .., 9=max)"),
"[DISABLED] the filename of the rewriting logfile"),
"[DISABLED] the level of the rewriting logfile verbosity"),
/* fixup after mod_proxy, so that the proxied url will not * escaped accidentally by mod_proxy's fixup. /* make the hashtable before registering the function, so that * other modules are prevented from accessing uninitialized memory. /* the main config structure */