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

📄 request.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 5 页
字号:
         *     ordered by number of segments. See core_reorder_directories         * startseg tells us how many segments describe the root path         *     e.g. the complete path "//host/foo/" to a UNC share (4)         */        startseg = seg = ap_count_dirs(r->filename);        sec_idx = 0;        /*         * Go down the directory hierarchy.  Where we have to check for         * symlinks, do so.  Where a .htaccess file has permission to         * override anything, try to find one.         */        do {            int res;            char *seg_name;            char *delim;            int temp_slash=0;            /* We have no trailing slash, but we sure would appreciate one.             * However, we don't want to append a / our first time through.             */            if ((seg > startseg) && r->filename[filename_len-1] != '/') {                r->filename[filename_len++] = '/';                r->filename[filename_len] = 0;                temp_slash=1;            }            /* Begin *this* level by looking for matching <Directory> sections             * from the server config.             */            for (; sec_idx < num_sec; ++sec_idx) {                ap_conf_vector_t *entry_config = sec_ent[sec_idx];                core_dir_config *entry_core;                entry_core = ap_get_module_config(entry_config, &core_module);                /* No more possible matches for this many segments?                 * We are done when we find relative/regex/longer components.                 */                if (entry_core->r || entry_core->d_components > seg) {                    break;                }                /* We will never skip '0' element components, e.g. plain old                 * <Directory >, and <Directory "/"> are classified as zero                 * so that Win32/Netware/OS2 etc all pick them up.                 * Otherwise, skip over the mismatches.                 */                if (entry_core->d_components                    && ((entry_core->d_components < seg)                     || (entry_core->d_is_fnmatch                         ? (apr_fnmatch(entry_core->d, r->filename,                                        FNM_PATHNAME) != APR_SUCCESS)                         : (strcmp(r->filename, entry_core->d) != 0)))) {                    continue;                }                /* If we haven't continue'd above, we have a match.                 *                 * Calculate our full-context core opts & override.                 */                core_opts_merge(sec_ent[sec_idx], &opts);                /* 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;            }            /* If .htaccess files are enabled, check for one, provided we             * have reached a real path.             */            do {  /* Not really a loop, just a break'able code block */                ap_conf_vector_t *htaccess_conf = NULL;                /* No htaccess in an incomplete root path,                  * nor if it's disabled                  */                if (seg < startseg || !opts.override) {                    break;                }                res = ap_parse_htaccess(&htaccess_conf, r, opts.override,                                        apr_pstrdup(r->pool, r->filename),                                        sconf->access_name);                if (res) {                    return res;                }                if (!htaccess_conf) {                    break;                }                /* If we are still here, we found our htaccess.                 *                 * Calculate our full-context core opts & override.                 */                core_opts_merge(htaccess_conf, &opts);                /* If we merged this same htaccess last time, reuse it...                 * this wouldn't work except that we cache the htaccess                 * sections for the lifetime of the request, so we match                 * the same conf.  Good planning (no, pure luck ;)                 */                if (matches) {                    if (last_walk->matched == htaccess_conf) {                        now_merged = last_walk->merged;                        ++last_walk;                        --matches;                        break;                    }                    /* 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,                                                          htaccess_conf);                }                else {                    now_merged = htaccess_conf;                }                last_walk = (walk_walked_t*)apr_array_push(cache->walked);                last_walk->matched = htaccess_conf;                last_walk->merged = now_merged;            } while (0); /* Only one htaccess, not a real loop */            /* That temporary trailing slash was useful, now drop it.             */            if (temp_slash) {                r->filename[--filename_len] = '\0';            }            /* Time for all good things to come to an end?             */            if (!r->path_info || !*r->path_info) {                break;            }            /* Now it's time for the next segment...             * We will assume the next element is an end node, and fix it up             * below as necessary...             */            seg_name = r->filename + filename_len;            delim = strchr(r->path_info + (*r->path_info == '/' ? 1 : 0), '/');            if (delim) {                size_t path_info_len = delim - r->path_info;                *delim = '\0';                memcpy(seg_name, r->path_info, path_info_len + 1);                filename_len += path_info_len;                r->path_info = delim;                *delim = '/';            }            else {                size_t path_info_len = strlen(r->path_info);                memcpy(seg_name, r->path_info, path_info_len + 1);                filename_len += path_info_len;                r->path_info += path_info_len;            }            if (*seg_name == '/')                ++seg_name;            /* If nothing remained but a '/' string, we are finished             */            if (!*seg_name) {                break;            }            /* First optimization;             * If...we knew r->filename was a file, and             * if...we have strict (case-sensitive) filenames, or             *      we know the canonical_filename matches to _this_ name, and             * if...we have allowed symlinks             * skip the lstat and dummy up an APR_DIR value for thisinfo.             */            if (r->finfo.filetype#ifdef CASE_BLIND_FILESYSTEM                && (filename_len <= canonical_len)#endif                && ((opts.opts & (OPT_SYM_OWNER | OPT_SYM_LINKS)) == OPT_SYM_LINKS))            {                thisinfo.filetype = APR_DIR;                ++seg;                continue;            }            /* We choose apr_lstat here, rather that apr_stat, so that we             * capture this path object rather than its target.  We will             * replace the info with our target's info below.  We especially             * want the name of this 'link' object, not the name of its             * target, if we are fixing the filename case/resolving aliases.             */            rv = apr_lstat(&thisinfo, r->filename,                           APR_FINFO_MIN | APR_FINFO_NAME, r->pool);            if (APR_STATUS_IS_ENOENT(rv)) {                /* Nothing?  That could be nice.  But our directory                 * walk is done.                 */                thisinfo.filetype = APR_NOFILE;                break;            }            else if (APR_STATUS_IS_EACCES(rv)) {                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,                              "access to %s denied", r->uri);                return r->status = HTTP_FORBIDDEN;            }            else if ((rv != APR_SUCCESS && rv != APR_INCOMPLETE)                     || !(thisinfo.valid & APR_FINFO_TYPE)) {                /* If we hit ENOTDIR, we must have over-optimized, deny                 * rather than assume not found.                 */                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,                              "access to %s failed", r->uri);                return r->status = HTTP_FORBIDDEN;            }            /* Fix up the path now if we have a name, and they don't agree             */            if ((thisinfo.valid & APR_FINFO_NAME)                && strcmp(seg_name, thisinfo.name)) {                /* TODO: provide users an option that an internal/external                 * redirect is required here?  We need to walk the URI and                 * filename in tandem to properly correlate these.                 */                strcpy(seg_name, thisinfo.name);                filename_len = strlen(r->filename);            }            if (thisinfo.filetype == APR_LNK) {                /* Is this a possibly acceptable symlink?                 */                if ((res = resolve_symlink(r->filename, &thisinfo,                                           opts.opts, r->pool)) != OK) {                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                                  "Symbolic link not allowed: %s",                                  r->filename);                    return r->status = res;                }            }            /* Ok, we are done with the link's info, test the real target             */            if (thisinfo.filetype == APR_REG ||                 thisinfo.filetype == APR_NOFILE) {                /* That was fun, nothing left for us here                 */                break;            }            else if (thisinfo.filetype != APR_DIR) {                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                              "Forbidden: %s doesn't point to "                              "a file or directory",                              r->filename);                return r->status = HTTP_FORBIDDEN;            }            ++seg;        } while (thisinfo.filetype == APR_DIR);        /* If we have _not_ optimized, this is the time to recover         * the final stat result.         */        if (!r->finfo.filetype || r->finfo.filetype == APR_LNK) {            r->finfo = thisinfo;        }        /* Now splice the saved path_info back onto any new path_info         */        if (save_path_info) {            if (r->path_info && *r->path_info) {                r->path_info = ap_make_full_path(r->pool, r->path_info,                                                 save_path_info);            }            else {                r->path_info = save_path_info;            }        }        /*         * Now we'll deal with the regexes, note we pick up sec_idx         * where we left off (we gave up after we hit entry_core->r)         */        for (; 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) {                continue;            }            if (ap_regexec(entry_core->r, r->filename, 0, NULL, REG_NOTEOL)) {                continue;            }            /* If we haven't already continue'd above, we have a match.             *             * Calculate our full-context core opts & override.             */            core_opts_merge(sec_ent[sec_idx], &opts);            /* 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,

⌨️ 快捷键说明

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