⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_rewrite.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 5 页
字号:
        /*         *  now apply the rules ...         */        rulestatus = apply_rewrite_list(r, conf->rewriterules, NULL);        apr_table_set(r->notes,"mod_rewrite_rewritten",                      apr_psprintf(r->pool,"%d",rulestatus));    }    else {        rewritelog(r, 2,                   "uri already rewritten. Status %s, Uri %s, r->filename %s",                   saved_rulestatus, r->uri, r->filename);        rulestatus = atoi(saved_rulestatus);    }    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_ERR, 0, r,                              "attempt to make remote request from mod_rewrite "                              "without proxy enabled: %s", r->filename);                return HTTP_FORBIDDEN;            }            /* make sure the QUERY_STRING and             * PATH_INFO parts get incorporated             */            if (r->path_info != NULL) {                r->filename = apr_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 = apr_pstrcat(r->pool, r->filename,                                          "?", r->args, NULL);            }            /* now make sure the request gets handled by the proxy handler */            if (PROXYREQ_NONE == r->proxyreq) {                r->proxyreq = PROXYREQ_REVERSE;            }            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 = apr_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 = HTTP_MOVED_TEMPORARILY;            }            /* now do the redirection */            apr_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 HTTP_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) {            /*             * 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             * add the document root             */            r->uri = apr_pstrdup(r->pool, r->filename+12);            return DECLINED;        }        else {            /* it was finally rewritten to a local path */            /* expand "/~user" prefix */#if APR_HAS_USER            r->filename = expand_tildepaths(r, r->filename);#endif            rewritelog(r, 2, "local path result: %s", r->filename);            /* the filename must be either an absolute local path or an             * absolute local URL.             */            if (   *r->filename != '/'                && !ap_os_is_path_absolute(r->pool, r->filename)) {                return HTTP_BAD_REQUEST;            }            /* if there is no valid prefix, we have             * to emulate the translator from the core and             * prefix the filename with document_root             *             * NOTICE:             * 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 -             *   this is also bad             *             * BUT:             * 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!             */            n = prefix_stat(r->filename, r->pool);            if (n == 0) {                if ((ccp = ap_document_root(r)) != NULL) {                    l = apr_cpystrn(docroot, ccp, sizeof(docroot)) - docroot;                    /* always NOT have a trailing slash */                    if (docroot[l-1] == '/') {                        docroot[l-1] = '\0';                    }                    if (r->server->path                        && !strncmp(r->filename, r->server->path,                                    r->server->pathlen)) {                        r->filename = apr_pstrcat(r->pool, docroot,                                                  (r->filename +                                                   r->server->pathlen), NULL);                    }                    else {                        r->filename = apr_pstrcat(r->pool, docroot,                                                  r->filename, NULL);                    }                    rewritelog(r, 2, "prefixed with document_root to %s",                               r->filename);                }            }            rewritelog(r, 1, "go-ahead with %s [OK]", r->filename);            return OK;        }    }    else {        rewritelog(r, 1, "pass through %s", r->filename);        return DECLINED;    }}/*****  MIME-type hook****  [used to support the forced-MIME-type feature]***/static int hook_mimetype(request_rec *r){    const char *t;    /* now check if we have to force a MIME-type */    t = apr_table_get(r->notes, REWRITE_FORCED_MIMETYPE_NOTEVAR);    if (t == NULL) {        return DECLINED;    }    else {        rewritelog(r, 1, "force filename %s to have MIME-type '%s'",                   r->filename, t);        ap_set_content_type(r, t);        return OK;    }}/*****  Fixup hook****  [used for the rewriting engine triggered by**  the per-directory 'RewriteRule' directives]***/static int hook_fixup(request_rec *r){    rewrite_perdir_conf *dconf;    char *cp;    char *cp2;    const char *ccp;    char *prefix;    apr_size_t l;    int rulestatus;    int n;    char *ofilename;    int is_proxyreq;    dconf = (rewrite_perdir_conf *)ap_get_module_config(r->per_dir_config,                                                        &rewrite_module);    /* if there is no per-dir config we return immediately */    if (dconf == NULL) {        return DECLINED;    }    /* we shouldn't do anything in subrequests */    if (r->main != NULL) {        return DECLINED;    }    /* if there are no real (i.e. no RewriteRule directives!)       per-dir config of us, we return also immediately */    if (dconf->directory == NULL) {        return DECLINED;    }    /*     * Proxy request?     */  	is_proxyreq = (   r->proxyreq && r->filename  	               && !strncmp(r->filename, "proxy:", 6));    /*     *  .htaccess file is called before really entering the directory, i.e.:     *  URL: http://localhost/foo  and .htaccess is located in foo directory     *  Ignore such attempts, since they may lead to undefined behaviour.     */    if (is_proxyreq) {        l = strlen(dconf->directory) - 1;        if (r->filename && strlen(r->filename) == l &&            (dconf->directory)[l] == '/' &&            !strncmp(r->filename, dconf->directory, l)) {            return DECLINED;        }    }    /*     *  only do something under runtime if the engine is really enabled,     *  for this directory, else return immediately!     */    if (dconf->state == ENGINE_DISABLED) {        return DECLINED;    }    /*     *  Do the Options check after engine check, so     *  the user is able to explicitely turn RewriteEngine Off.     */    if (!(ap_allow_options(r) & (OPT_SYM_LINKS | OPT_SYM_OWNER))) {        /* FollowSymLinks is mandatory! */        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                     "Options FollowSymLinks or SymLinksIfOwnerMatch is off "                     "which implies that RewriteRule directive is forbidden: "                     "%s", r->filename);        return HTTP_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     *  request     */    ofilename = r->filename;    if (r->filename == NULL) {        r->filename = apr_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, dconf->rewriterules, dconf->directory);    if (rulestatus) {        unsigned skip;        if (strlen(r->filename) > 6 &&            strncmp(r->filename, "proxy:", 6) == 0) {            /* 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!)             */            if (r->args != NULL) {                r->filename = apr_pstrcat(r->pool, r->filename,                                          "?", r->args, NULL);            }            /* now make sure the request gets handled by the proxy handler */            if (PROXYREQ_NONE == r->proxyreq) {                r->proxyreq = PROXYREQ_REVERSE;            }            r->handler  = "proxy-server";            rewritelog(r, 1, "[per-dir %s] go-ahead with proxy request "                       "%s [OK]", dconf->directory, r->filename);            return OK;        }        else if ((skip = is_absolute_uri(r->filename)) > 0) {            /* 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             */            if (dconf->baseurl != NULL) {                /* skip 'scheme://' */                cp = r->filename + skip;                if ((cp = ap_strchr(cp, '/')) != NULL && *(++cp)) {                    rewritelog(r, 2,                               "[per-dir %s] trying to replace "                               "prefix %s with %s",                               dconf->directory, dconf->directory,                               dconf->baseurl);                    /* I think, that hack needs an explanation:                     * well, here is it:                     * 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                     * URL.                     * 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                     * hostname and compare/substitute only the stuff after it.                     *                     * (note that cp was already increased to the right value)                     */                    cp2 = subst_prefix_path(r, cp, (*dconf->directory == '/')                                                   ? dconf->directory + 1                                                   : dconf->directory,                                            dconf->baseurl + 1);                    if (strcmp(cp2, cp) != 0) {                        *cp = '\0';                        r->filename = apr_pstrcat(r->pool, r->filename,                                                  cp2, NULL);                    }                }            }            /* now prepare the redirect... */            if (rulestatus != ACTION_NOESCAPE) {                rewritelog(r, 1, "[per-dir %s] escaping %s for redirect",                           dconf->directory, r->filename);                r->filename = escape_absolute_uri(r->pool, r->filename, skip);            }

⌨️ 快捷键说明

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