mod_rewrite.c

来自「apache 安装教程 apache 安装教程」· C语言 代码 · 共 1,959 行 · 第 1/5 页

C
1,959
字号
                                                  char *str){    char *cp;    char *cp1;    char *cp2;    char *cp3;    char *key;    char *val;    const char *err;    if (str[0] != '[' || str[strlen(str)-1] != ']') {        return "RewriteRule: bad flag delimiters";    }    cp = str+1;    str[strlen(str)-1] = ','; /* for simpler parsing */    for ( ; *cp != '\0'; ) {        /* skip whitespaces */        for ( ; (*cp == ' ' || *cp == '\t') && *cp != '\0'; cp++)            ;        if (*cp == '\0') {            break;        }        cp1 = cp;        if ((cp2 = strchr(cp, ',')) != NULL) {            cp = cp2+1;            for ( ; (*(cp2-1) == ' ' || *(cp2-1) == '\t'); cp2--)                ;            *cp2 = '\0';            if ((cp3 = strchr(cp1, '=')) != NULL) {                *cp3 = '\0';                key = cp1;                val = cp3+1;            }            else {                key = cp1;                val = "";            }            if ((err = cmd_rewriterule_setflag(p, cfg, key, val)) != NULL) {                return err;            }        }        else {            break;        }    }    return NULL;}static const char *cmd_rewriterule_setflag(pool *p, rewriterule_entry *cfg,                                           char *key, char *val){    int status = 0;    int i;    if (   strcasecmp(key, "redirect") == 0        || strcasecmp(key, "R") == 0       ) {        cfg->flags |= RULEFLAG_FORCEREDIRECT;        if (strlen(val) > 0) {            if (strcasecmp(val, "permanent") == 0) {                status = HTTP_MOVED_PERMANENTLY;            }            else if (strcasecmp(val, "temp") == 0) {                status = HTTP_MOVED_TEMPORARILY;            }            else if (strcasecmp(val, "seeother") == 0) {                status = HTTP_SEE_OTHER;            }            else if (ap_isdigit(*val)) {                status = atoi(val);            }            if (!ap_is_HTTP_REDIRECT(status)) {                return "RewriteRule: invalid HTTP response code "                       "for flag 'R'";            }            cfg->forced_responsecode = status;        }    }    else if (   strcasecmp(key, "noescape") == 0        || strcasecmp(key, "NE") == 0       ) {        cfg->flags |= RULEFLAG_NOESCAPE;    }    else if (   strcasecmp(key, "last") == 0             || strcasecmp(key, "L") == 0   ) {        cfg->flags |= RULEFLAG_LASTRULE;    }    else if (   strcasecmp(key, "next") == 0             || strcasecmp(key, "N") == 0   ) {        cfg->flags |= RULEFLAG_NEWROUND;    }    else if (   strcasecmp(key, "chain") == 0             || strcasecmp(key, "C") == 0    ) {        cfg->flags |= RULEFLAG_CHAIN;    }    else if (   strcasecmp(key, "type") == 0             || strcasecmp(key, "T") == 0   ) {        cfg->forced_mimetype = ap_pstrdup(p, val);        ap_str_tolower(cfg->forced_mimetype);    }    else if (   strcasecmp(key, "env") == 0             || strcasecmp(key, "E") == 0   ) {        for (i = 0; (cfg->env[i] != NULL) && (i < MAX_ENV_FLAGS); i++)            ;        if (i < MAX_ENV_FLAGS) {            cfg->env[i] = ap_pstrdup(p, val);            cfg->env[i+1] = NULL;        }        else {            return "RewriteRule: too many environment flags 'E'";        }    }    else if (   strcasecmp(key, "nosubreq") == 0             || strcasecmp(key, "NS") == 0      ) {        cfg->flags |= RULEFLAG_IGNOREONSUBREQ;    }    else if (   strcasecmp(key, "proxy") == 0             || strcasecmp(key, "P") == 0      ) {        cfg->flags |= RULEFLAG_PROXY;    }    else if (   strcasecmp(key, "passthrough") == 0             || strcasecmp(key, "PT") == 0      ) {        cfg->flags |= RULEFLAG_PASSTHROUGH;    }    else if (   strcasecmp(key, "skip") == 0             || strcasecmp(key, "S") == 0   ) {        cfg->skip = atoi(val);    }    else if (   strcasecmp(key, "forbidden") == 0             || strcasecmp(key, "F") == 0   ) {        cfg->flags |= RULEFLAG_FORBIDDEN;    }    else if (   strcasecmp(key, "gone") == 0             || strcasecmp(key, "G") == 0   ) {        cfg->flags |= RULEFLAG_GONE;    }    else if (   strcasecmp(key, "qsappend") == 0             || strcasecmp(key, "QSA") == 0   ) {        cfg->flags |= RULEFLAG_QSAPPEND;    }    else if (   strcasecmp(key, "nocase") == 0             || strcasecmp(key, "NC") == 0    ) {        cfg->flags |= RULEFLAG_NOCASE;    }    else {        return ap_pstrcat(p, "RewriteRule: unknown flag '", key, "'\n", NULL);    }    return NULL;}/*****  Global Module Initialization**  [called from read_config() after all**  config commands were already called]***/static void init_module(server_rec *s, pool *p){    /* check if proxy module is available */    proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL);    /* create the rewriting lockfile in the parent */    rewritelock_create(s, p);    ap_register_cleanup(p, (void *)s, rewritelock_remove, ap_null_cleanup);    /* step through the servers and     * - open each rewriting logfile     * - open the RewriteMap prg:xxx programs     */    for (; s; s = s->next) {        open_rewritelog(s, p);        run_rewritemap_programs(s, p);    }}/*****  Per-Child Module Initialization**  [called after a child process is spawned]***/static void init_child(server_rec *s, pool *p){     /* open the rewriting lockfile */     rewritelock_open(s, p);     /* create the lookup cache */     cachep = init_cache(p);}/*** +-------------------------------------------------------+** |                                                       |** |                     runtime hooks** |                                                       |** +-------------------------------------------------------+*//*****  URI-to-filename hook****  [used for the rewriting engine triggered by**  the per-server 'RewriteRule' directives]***/static int hook_uri2file(request_rec *r){    void *sconf;    rewrite_server_conf *conf;    const char *var;    const char *thisserver;    char *thisport;    const char *thisurl;    char buf[512];    char docroot[512];    const char *ccp;    unsigned int port;    int rulestatus;    int n;    int l;    /*     *  retrieve the config structures     */    sconf = r->server->module_config;    conf  = (rewrite_server_conf *)ap_get_module_config(sconf,                                                        &rewrite_module);    /*     *  only do something under runtime if the engine is really enabled,     *  else return immediately!     */    if (conf->state == ENGINE_DISABLED) {        return DECLINED;    }    /*     *  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.     */    if (conf->server != r->server) {        return DECLINED;    }    /*     *  add the SCRIPT_URL variable to the env. this is a bit complicated     *  due to the fact that apache uses subrequests and internal redirects     */    if (r->main == NULL) {         var = ap_pstrcat(r->pool, "REDIRECT_", ENVVAR_SCRIPT_URL, NULL);         var = ap_table_get(r->subprocess_env, var);         if (var == NULL) {             ap_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, r->uri);         }         else {             ap_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, var);         }    }    else {         var = ap_table_get(r->main->subprocess_env, ENVVAR_SCRIPT_URL);         ap_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, var);    }    /*     *  create the SCRIPT_URI variable for the env     */    /* add the canonical URI of this URL */    thisserver = ap_get_server_name(r);    port = ap_get_server_port(r);    if (ap_is_default_port(port, r)) {        thisport = "";    }    else {        ap_snprintf(buf, sizeof(buf), ":%u", port);        thisport = buf;    }    thisurl = ap_table_get(r->subprocess_env, ENVVAR_SCRIPT_URL);    /* set the variable */    var = ap_pstrcat(r->pool, ap_http_method(r), "://", thisserver, thisport,                     thisurl, NULL);    ap_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URI, var);    /* if filename was not initially set,     * we start with the requested URI     */    if (r->filename == NULL) {        r->filename = ap_pstrdup(r->pool, r->uri);        rewritelog(r, 2, "init rewrite engine with requested uri %s",                   r->filename);    }    /*     *  now apply the rules ...     */    rulestatus = apply_rewrite_list(r, conf->rewriterules, NULL);    if (rulestatus) {        unsigned skip;        if (strlen(r->filename) > 6 &&            strncmp(r->filename, "proxy:", 6) == 0) {            /* it should be go on as an internal proxy request */            /* check if the proxy module is enabled, so             * we can actually use it!             */            if (!proxy_available) {                ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,                             "attempt to make remote request from mod_rewrite "                             "without proxy enabled: %s", r->filename);                return FORBIDDEN;            }            /* make sure the QUERY_STRING and             * PATH_INFO parts get incorporated             */            if (r->path_info != NULL) {                r->filename = ap_pstrcat(r->pool, r->filename,                                         r->path_info, NULL);            }            if (r->args != NULL &&                r->uri == r->unparsed_uri) {                /* see proxy_http:proxy_http_canon() */                r->filename = ap_pstrcat(r->pool, r->filename,                                         "?", r->args, NULL);            }            /* now make sure the request gets handled by the proxy handler */            r->proxyreq = PROXY_PASS;            r->handler  = "proxy-server";            rewritelog(r, 1, "go-ahead with proxy request %s [OK]",                       r->filename);            return OK;        }        else if ((skip = is_absolute_uri(r->filename)) > 0) {            /* it was finally rewritten to a remote URL */            if (rulestatus != ACTION_NOESCAPE) {                rewritelog(r, 1, "escaping %s for redirect", r->filename);                r->filename = escape_absolute_uri(r->pool, r->filename, skip);            }            /* append the QUERY_STRING part */            if (r->args) {                r->filename = ap_pstrcat(r->pool, r->filename, "?",                                         (rulestatus == ACTION_NOESCAPE)                                           ? r->args                                           : ap_escape_uri(r->pool, r->args),                                         NULL);            }            /* determine HTTP redirect response code */            if (ap_is_HTTP_REDIRECT(r->status)) {                n = r->status;                r->status = HTTP_OK; /* make Apache kernel happy */            }            else {                n = REDIRECT;            }            /* now do the redirection */            ap_table_setn(r->headers_out, "Location", r->filename);            rewritelog(r, 1, "redirect to %s [REDIRECT/%d]", r->filename, n);            return n;        }        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) > 5 &&                 strncmp(r->filename, "gone:", 5) == 0) {            /* This URLs is forced to be gone */            return HTTP_GONE;        }        else if (strlen(r->filename) > 12 &&                 strncmp(r->filename, "passthrough:", 12) == 0) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?