📄 mod_rewrite.c
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* _ _ _** _ __ ___ ___ __| | _ __ _____ ___ __(_) |_ ___** | '_ ` _ \ / _ \ / _` | | '__/ _ \ \ /\ / / '__| | __/ _ \** | | | | | | (_) | (_| | | | | __/\ V V /| | | | || __/** |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___|** |_____|**** URL Rewriting Module**** 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** substitution.**** 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**** Ralf S. Engelschall** rse@engelschall.com** www.engelschall.com*/#include "mod_rewrite.h"#ifndef NO_WRITEV#ifndef NETWARE#include <sys/types.h>#endif#include <sys/uio.h>#endif#ifdef NETWARE#include <nwsemaph.h>static LONG locking_sem = 0;#endif/*** +-------------------------------------------------------+** | |** | 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)** foreach(module) (**)** try to run hook**** 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** continue processing:** 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".** for hook #2,#3,#7,#9:** 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** or not!*/ /* The section for the Configure script: * MODULE-DEFINITION-START * Name: rewrite_module * ConfigStart . ./helpers/find-dbm-lib if [ "x$found_dbm" = "x1" ]; then echo " enabling DBM support for mod_rewrite" else 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" fi * ConfigEnd * MODULE-DEFINITION-END */ /* the table of commands we provide */static const command_rec command_table[] = { { "RewriteEngine", cmd_rewriteengine, NULL, OR_FILEINFO, FLAG, "On or Off to enable or disable (default) the whole rewriting engine" }, { "RewriteOptions", cmd_rewriteoptions, NULL, OR_FILEINFO, ITERATE, "List of option strings to set" }, { "RewriteBase", cmd_rewritebase, NULL, OR_FILEINFO, TAKE1, "the base URL of the per-directory context" }, { "RewriteCond", cmd_rewritecond, NULL, OR_FILEINFO, RAW_ARGS, "an input string and a to be applied regexp-pattern" }, { "RewriteRule", cmd_rewriterule, NULL, OR_FILEINFO, RAW_ARGS, "an URL-applied regexp-pattern and a substitution URL" }, { "RewriteMap", cmd_rewritemap, NULL, RSRC_CONF, TAKE2, "a mapname and a filename" }, { "RewriteLock", cmd_rewritelock, NULL, RSRC_CONF, TAKE1, "the filename of a lockfile used for inter-process synchronization"}, { "RewriteLog", cmd_rewritelog, NULL, RSRC_CONF, TAKE1, "the filename of the rewriting logfile" }, { "RewriteLogLevel", cmd_rewriteloglevel, NULL, RSRC_CONF, TAKE1, "the level of the rewriting logfile verbosity " "(0=none, 1=std, .., 9=max)" }, { NULL }}; /* the table of content handlers we provide */static const handler_rec handler_table[] = { { "redirect-handler", handler_redirect }, { NULL }}; /* the main config structure */module MODULE_VAR_EXPORT rewrite_module = { STANDARD_MODULE_STUFF, init_module, /* module initializer */ config_perdir_create, /* create per-dir config structures */ config_perdir_merge, /* merge per-dir config structures */ config_server_create, /* create per-server config structures */ config_server_merge, /* merge per-server config structures */ command_table, /* table of config file commands */ handler_table, /* [#8] MIME-typed-dispatched handlers */ hook_uri2file, /* [#1] URI to filename translation */ NULL, /* [#4] validate user id from request */ NULL, /* [#5] check if the user is ok _here_ */ NULL, /* [#3] check access by host address */ hook_mimetype, /* [#6] determine MIME type */ hook_fixup, /* [#7] pre-run fixups */ NULL, /* [#9] log a transaction */ NULL, /* [#2] header parser */ init_child, /* child_init */ NULL, /* child_exit */ NULL /* [#0] post read-request */}; /* the cache */static cache *cachep; /* whether proxy module is available or not */static int proxy_available;static char *lockname;static int lockfd = -1;/*** +-------------------------------------------------------+** | |** | configuration directive handling** | |** +-------------------------------------------------------+*//***** per-server configuration structure handling***/static void *config_server_create(pool *p, server_rec *s){ rewrite_server_conf *a; a = (rewrite_server_conf *)ap_pcalloc(p, sizeof(rewrite_server_conf)); a->state = ENGINE_DISABLED; a->options = OPTION_NONE; a->rewritelogfile = NULL; a->rewritelogfp = -1; a->rewriteloglevel = 0; a->rewritemaps = ap_make_array(p, 2, sizeof(rewritemap_entry)); a->rewriteconds = ap_make_array(p, 2, sizeof(rewritecond_entry)); a->rewriterules = ap_make_array(p, 2, sizeof(rewriterule_entry)); a->server = s; a->redirect_limit = 0; /* unset (use default) */ return (void *)a;}static void *config_server_merge(pool *p, void *basev, void *overridesv){ rewrite_server_conf *a, *base, *overrides; a = (rewrite_server_conf *)ap_pcalloc(p, sizeof(rewrite_server_conf)); base = (rewrite_server_conf *)basev; overrides = (rewrite_server_conf *)overridesv; a->state = overrides->state; a->options = overrides->options; a->server = overrides->server; a->redirect_limit = overrides->redirect_limit ? overrides->redirect_limit : base->redirect_limit; if (a->options & OPTION_INHERIT) { /* * local directives override * and anything else is inherited */ a->rewriteloglevel = overrides->rewriteloglevel != 0 ? overrides->rewriteloglevel : base->rewriteloglevel; a->rewritelogfile = overrides->rewritelogfile != NULL ? overrides->rewritelogfile : base->rewritelogfile; a->rewritelogfp = overrides->rewritelogfp != -1 ? overrides->rewritelogfp : base->rewritelogfp; a->rewritemaps = ap_append_arrays(p, overrides->rewritemaps, base->rewritemaps); a->rewriteconds = ap_append_arrays(p, overrides->rewriteconds, base->rewriteconds); a->rewriterules = ap_append_arrays(p, overrides->rewriterules, base->rewriterules); } else { /* * local directives override * and anything else gets defaults */ a->rewriteloglevel = overrides->rewriteloglevel; a->rewritelogfile = overrides->rewritelogfile; a->rewritelogfp = overrides->rewritelogfp; a->rewritemaps = overrides->rewritemaps; a->rewriteconds = overrides->rewriteconds; a->rewriterules = overrides->rewriterules; } return (void *)a;}/***** per-directory configuration structure handling***/static void *config_perdir_create(pool *p, char *path){ rewrite_perdir_conf *a; a = (rewrite_perdir_conf *)ap_pcalloc(p, sizeof(rewrite_perdir_conf)); a->state = ENGINE_DISABLED; a->options = OPTION_NONE; a->baseurl = NULL; a->rewriteconds = ap_make_array(p, 2, sizeof(rewritecond_entry)); a->rewriterules = ap_make_array(p, 2, sizeof(rewriterule_entry)); a->redirect_limit = 0; /* unset (use server config) */ if (path == NULL) { a->directory = NULL; } else { /* make sure it has a trailing slash */ if (path[strlen(path)-1] == '/') { a->directory = ap_pstrdup(p, path); } else { a->directory = ap_pstrcat(p, path, "/", NULL); } } return (void *)a;}static void *config_perdir_merge(pool *p, void *basev, void *overridesv){ rewrite_perdir_conf *a, *base, *overrides; a = (rewrite_perdir_conf *)ap_pcalloc(p, sizeof(rewrite_perdir_conf)); base = (rewrite_perdir_conf *)basev; overrides = (rewrite_perdir_conf *)overridesv; a->state = overrides->state; a->options = overrides->options; a->directory = overrides->directory; a->baseurl = overrides->baseurl; a->redirect_limit = overrides->redirect_limit ? overrides->redirect_limit : base->redirect_limit; if (a->options & OPTION_INHERIT) { a->rewriteconds = ap_append_arrays(p, overrides->rewriteconds, base->rewriteconds); a->rewriterules = ap_append_arrays(p, overrides->rewriterules, base->rewriterules); } else { a->rewriteconds = overrides->rewriteconds; a->rewriterules = overrides->rewriterules; } return (void *)a;}/***** the configuration commands***/static const char *cmd_rewriteengine(cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag){ rewrite_server_conf *sconf; sconf = (rewrite_server_conf *)ap_get_module_config(cmd->server->module_config, &rewrite_module); if (cmd->path == NULL) { /* is server command */ sconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED); } else /* is per-directory command */ { dconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED); } return NULL;}static const char *cmd_rewriteoptions(cmd_parms *cmd, void *in_dconf, const char *option){ int options = 0, limit = 0; char *w; while (*option) { w = ap_getword_conf(cmd->pool, &option); if (!strcasecmp(w, "inherit")) { options |= OPTION_INHERIT; } else if (!strncasecmp(w, "MaxRedirects=", 13)) { limit = atoi(&w[13]); if (limit <= 0) { return "RewriteOptions: MaxRedirects takes a number greater " "than zero."; } } else if (!strcasecmp(w, "MaxRedirects")) { /* be nice */ return "RewriteOptions: MaxRedirects has the format MaxRedirects" "=n."; } else { return ap_pstrcat(cmd->pool, "RewriteOptions: unknown option '", w, "'", NULL); } } /* put it into the appropriate config */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -