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

📄 request.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 5 页
字号:
                                                      now_merged,                                                      sec_ent[sec_idx]);            }            else {                now_merged = sec_ent[sec_idx];            }            last_walk = (walk_walked_t*)apr_array_push(cache->walked);            last_walk->matched = sec_ent[sec_idx];            last_walk->merged = now_merged;        }        /* Whoops - everything matched in sequence, but the original walk         * found some additional matches.  Truncate them.         */        if (matches) {            cache->walked->nelts -= matches;        }    }/* It seems this shouldn't be needed anymore.  We translated the x symlink above into a real resource, and should have died up there. x Even if we keep this, it needs more thought (maybe an r->file_is_symlink) x perhaps it should actually happen in file_walk, so we catch more x obscure cases in autoindex subrequests, etc. x x    * Symlink permissions are determined by the parent.  If the request is x    * for a directory then applying the symlink test here would use the x    * permissions of the directory as opposed to its parent.  Consider a x    * symlink pointing to a dir with a .htaccess disallowing symlinks.  If x    * you access /symlink (or /symlink/) you would get a 403 without this x    * APR_DIR test.  But if you accessed /symlink/index.html, for example, x    * you would *not* get the 403. x x   if (r->finfo.filetype != APR_DIR x       && (res = resolve_symlink(r->filename, r->info, ap_allow_options(r), x                                 r->pool))) { x       ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, x                     "Symbolic link not allowed: %s", r->filename); x       return res; x   } */    /* Save future sub-requestors much angst in processing     * this subrequest.  If dir_walk couldn't canonicalize     * the file path, nothing can.     */    r->canonical_filename = r->filename;    if (r->finfo.filetype == APR_DIR) {        cache->cached = r->filename;    }    else {        cache->cached = ap_make_dirstr_parent(r->pool, r->filename);    }    cache->dir_conf_tested = sec_ent;    cache->dir_conf_merged = r->per_dir_config;    /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs,     * and note the end result to (potentially) skip this step next time.     */    if (now_merged) {        r->per_dir_config = ap_merge_per_dir_configs(r->pool,                                                     r->per_dir_config,                                                     now_merged);    }    cache->per_dir_result = r->per_dir_config;    return OK;}AP_DECLARE(int) ap_location_walk(request_rec *r){    ap_conf_vector_t *now_merged = NULL;    core_server_config *sconf = ap_get_module_config(r->server->module_config,                                                     &core_module);    ap_conf_vector_t **sec_ent = (ap_conf_vector_t **)sconf->sec_url->elts;    int num_sec = sconf->sec_url->nelts;    walk_cache_t *cache;    const char *entry_uri;    /* No tricks here, there are no <Locations > to parse in this vhost.     * We won't destroy the cache, just in case _this_ redirect is later     * redirected again to a vhost with <Location > blocks to optimize.     */    if (!num_sec) {        return OK;    }    cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r);    /* Location and LocationMatch differ on their behaviour w.r.t. multiple     * slashes.  Location matches multiple slashes with a single slash,     * LocationMatch doesn't.  An exception, for backwards brokenness is     * absoluteURIs... in which case neither match multiple slashes.     */    if (r->uri[0] != '/') {        entry_uri = r->uri;    }    else {        char *uri = apr_pstrdup(r->pool, r->uri);        ap_no2slash(uri);        entry_uri = uri;    }    /* If we have an cache->cached location that matches r->uri,     * and the vhost's list of locations hasn't changed, we can skip     * rewalking the location_walk entries.     */    if (cache->cached        && (cache->dir_conf_tested == sec_ent)        && (strcmp(entry_uri, cache->cached) == 0)) {        /* Well this looks really familiar!  If our end-result (per_dir_result)         * didn't change, we have absolutely nothing to do :)         * Otherwise (as is the case with most dir_merged/file_merged requests)         * we must merge our dir_conf_merged onto this new r->per_dir_config.         */        if (r->per_dir_config == cache->per_dir_result) {            return OK;        }        if (r->per_dir_config == cache->dir_conf_merged) {            r->per_dir_config = cache->per_dir_result;            return OK;        }        if (cache->walked->nelts) {            now_merged = ((walk_walked_t*)cache->walked->elts)                                            [cache->walked->nelts - 1].merged;        }    }    else {        /* We start now_merged from NULL since we want to build         * a locations list that can be merged to any vhost.         */        int len, sec_idx;        int matches = cache->walked->nelts;        walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;        cache->cached = entry_uri;        /* Go through the location entries, and check for matches.         * We apply the directive sections in given order, we should         * really try them with the most general first.         */        for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) {            core_dir_config *entry_core;            entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module);            /* ### const strlen can be optimized in location config parsing */            len = strlen(entry_core->d);            /* Test the regex, fnmatch or string as appropriate.             * If it's a strcmp, and the <Location > pattern was             * not slash terminated, then this uri must be slash             * terminated (or at the end of the string) to match.             */            if (entry_core->r                ? ap_regexec(entry_core->r, r->uri, 0, NULL, 0)                : (entry_core->d_is_fnmatch                   ? apr_fnmatch(entry_core->d, cache->cached, FNM_PATHNAME)                   : (strncmp(entry_core->d, cache->cached, len)                      || (entry_core->d[len - 1] != '/'                          && cache->cached[len] != '/'                          && cache->cached[len] != '\0')))) {                continue;            }            /* If we merged this same section last time, reuse it             */            if (matches) {                if (last_walk->matched == sec_ent[sec_idx]) {                    now_merged = last_walk->merged;                    ++last_walk;                    --matches;                    continue;                }                /* We fell out of sync.  This is our own copy of walked,                 * so truncate the remaining matches and reset remaining.                 */                cache->walked->nelts -= matches;                matches = 0;            }            if (now_merged) {                now_merged = ap_merge_per_dir_configs(r->pool,                                                      now_merged,                                                      sec_ent[sec_idx]);            }            else {                now_merged = sec_ent[sec_idx];            }            last_walk = (walk_walked_t*)apr_array_push(cache->walked);            last_walk->matched = sec_ent[sec_idx];            last_walk->merged = now_merged;        }        /* Whoops - everything matched in sequence, but the original walk         * found some additional matches.  Truncate them.         */        if (matches) {            cache->walked->nelts -= matches;        }    }    cache->dir_conf_tested = sec_ent;    cache->dir_conf_merged = r->per_dir_config;    /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs,     * and note the end result to (potentially) skip this step next time.     */    if (now_merged) {        r->per_dir_config = ap_merge_per_dir_configs(r->pool,                                                     r->per_dir_config,                                                     now_merged);    }    cache->per_dir_result = r->per_dir_config;    return OK;}AP_DECLARE(int) ap_file_walk(request_rec *r){    ap_conf_vector_t *now_merged = NULL;    core_dir_config *dconf = ap_get_module_config(r->per_dir_config,                                                  &core_module);    ap_conf_vector_t **sec_ent = (ap_conf_vector_t **)dconf->sec_file->elts;    int num_sec = dconf->sec_file->nelts;    walk_cache_t *cache;    const char *test_file;    /* To allow broken modules to proceed, we allow missing filenames to pass.     * We will catch it later if it's heading for the core handler.     * directory_walk already posted an INFO note for module debugging.     */    if (r->filename == NULL) {        return OK;    }    cache = prep_walk_cache(AP_NOTE_FILE_WALK, r);    /* No tricks here, there are just no <Files > to parse in this context.     * We won't destroy the cache, just in case _this_ redirect is later     * redirected again to a context containing the same or similar <Files >.     */    if (!num_sec) {        return OK;    }    /* Get the basename .. and copy for the cache just     * in case r->filename is munged by another module     */    test_file = strrchr(r->filename, '/');    if (test_file == NULL) {        test_file = apr_pstrdup(r->pool, r->filename);    }    else {        test_file = apr_pstrdup(r->pool, ++test_file);    }    /* If we have an cache->cached file name that matches test_file,     * and the directory's list of file sections hasn't changed, we     * can skip rewalking the file_walk entries.     */    if (cache->cached        && (cache->dir_conf_tested == sec_ent)        && (strcmp(test_file, cache->cached) == 0)) {        /* Well this looks really familiar!  If our end-result (per_dir_result)         * didn't change, we have absolutely nothing to do :)         * Otherwise (as is the case with most dir_merged requests)         * we must merge our dir_conf_merged onto this new r->per_dir_config.         */        if (r->per_dir_config == cache->per_dir_result) {            return OK;        }        if (r->per_dir_config == cache->dir_conf_merged) {            r->per_dir_config = cache->per_dir_result;            return OK;        }        if (cache->walked->nelts) {            now_merged = ((walk_walked_t*)cache->walked->elts)                [cache->walked->nelts - 1].merged;        }    }    else {        /* We start now_merged from NULL since we want to build         * a file section list that can be merged to any dir_walk.         */        int sec_idx;        int matches = cache->walked->nelts;        walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;        cache->cached = test_file;        /* Go through the location entries, and check for matches.         * We apply the directive sections in given order, we should         * really try them with the most general first.         */        for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) {            core_dir_config *entry_core;            entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module);            if (entry_core->r                ? ap_regexec(entry_core->r, cache->cached , 0, NULL, 0)                : (entry_core->d_is_fnmatch                   ? apr_fnmatch(entry_core->d, cache->cached, FNM_PATHNAME)                   : strcmp(entry_core->d, cache->cached))) {                continue;            }            /* If we merged this same section last time, reuse it             */            if (matches) {                if (last_walk->matched == sec_ent[sec_idx]) {                    now_merged = last_walk->merged;                    ++last_walk;                    --matches;                    continue;                }                /* We fell out of sync.  This is our own copy of walked,                 * so truncate the remaining matches and reset remaining.                 */                cache->walked->nelts -= matches;                matches = 0;            }            if (now_merged) {                now_merged = ap_merge_per_dir_configs(r->pool,                                                      now_merged,                                                      sec_ent[sec_idx]);            }            else {                now_merged = sec_ent[sec_idx];            }            last_walk = (walk_walked_t*)apr_array_push(cache->walked);            last_walk->matched = sec_ent[sec_idx];            last_walk->merged = now_merged;        }        /* Whoops - everything matched in sequence, but the original walk         * found some additional matches.  Truncate them.         */        if (matches) {            cache->walked->nelts -= matches;        }    }    cache->dir_conf_tested = sec_ent;    cache->dir_conf_merged = r->per_dir_config;

⌨️ 快捷键说明

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