request.c revision 098ae874f43f7a0b66be5406a7e2fb971bbbe00e
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * Licensed under the Apache License, Version 2.0 (the "License");
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * you may not use this file except in compliance with the License.
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * You may obtain a copy of the License at
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * http://www.apache.org/licenses/LICENSE-2.0
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * Unless required by applicable law or agreed to in writing, software
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * distributed under the License is distributed on an "AS IS" BASIS,
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * See the License for the specific language governing permissions and
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * limitations under the License.
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * @brief functions to get and process requests
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * @author Rob McCool 3/21/93
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * Thoroughly revamped by rst for Apache. NB this file reads
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * best from the bottom up.
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen GallagherAP_IMPLEMENT_HOOK_RUN_FIRST(int,translate_name,
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen GallagherAP_IMPLEMENT_HOOK_RUN_FIRST(int,map_to_storage,
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen GallagherAP_IMPLEMENT_HOOK_RUN_FIRST(int,check_user_id,
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen GallagherAP_IMPLEMENT_HOOK_RUN_FIRST(int,type_checker,
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen GallagherAP_IMPLEMENT_HOOK_RUN_ALL(int,access_checker,
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen GallagherAP_IMPLEMENT_HOOK_RUN_FIRST(int,auth_checker,
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen GallagherAP_IMPLEMENT_HOOK_VOID(insert_filter, (request_rec *r), (r))
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen GallagherAP_IMPLEMENT_HOOK_RUN_ALL(int, create_request,
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagherstatic int decl_die(int status, char *phase, request_rec *r)
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher "configuration error: couldn't %s: %s", phase, r->uri);
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher/* This is the master logic for processing requests. Do NOT duplicate
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * this logic elsewhere, or the security model will be broken by future
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * API changes. Each phase must be individually optimized to pick up
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher * redundant/duplicate calls by subrequests, and redirects.
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen GallagherAP_DECLARE(int) ap_process_request_internal(request_rec *r)
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher /* Ignore embedded %2F's in path for proxy requests */
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher d = ap_get_module_config(r->per_dir_config, &core_module);
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher access_status = ap_unescape_url_keep2f(r->parsed_uri.path);
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher access_status = ap_unescape_url(r->parsed_uri.path);
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher "found %%2f (encoded '/') in URI "
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher "(decoded='%s'), returning 404",
ae8d047122c7ba8123f72b2eac68944868ac37d4Stephen Gallagher ap_getparents(r->uri); /* OK --- shrinking transformations... */
if (!file_req) {
return access_status;
return access_status;
if (!file_req) {
return access_status;
return access_status;
switch (ap_satisfies(r)) {
case SATISFY_ALL:
case SATISFY_NOSPEC:
if (ap_some_auth_required(r)) {
|| !ap_auth_type(r)) {
|| !ap_auth_type(r)) {
case SATISFY_ANY:
if (!ap_some_auth_required(r)) {
|| !ap_auth_type(r)) {
|| !ap_auth_type(r)) {
* in mod-proxy for r->proxyreq && r->parsed_uri.scheme
* && !strcmp(r->parsed_uri.scheme, "http")
return access_status;
return OK;
* Directive order in the httpd.conf file and its Includes significantly
typedef struct walk_walked_t {
typedef struct walk_cache_t {
} walk_cache_t;
void **note;
if (!note) {
return NULL;
void **inherit_note;
if ((r->main
&& *inherit_note)
|| (r->prev
&& *inherit_note)) {
sizeof(*cache));
return cache;
int res;
const char *savename;
return HTTP_FORBIDDEN;
| APR_FINFO_LINK), p))
!= APR_SUCCESS) {
return HTTP_FORBIDDEN;
if (savename) {
return OK;
!= APR_SUCCESS) {
return HTTP_FORBIDDEN;
!= APR_SUCCESS) {
return HTTP_FORBIDDEN;
return HTTP_FORBIDDEN;
if (savename) {
return OK;
* See core.c::merge_core_dir_configs() for explanation.
typedef struct core_opts_t {
} core_opts_t;
if (!this_dir) {
&core_module);
char *entry_dir;
r->uri);
return OK;
!= APR_SUCCESS) {
return OK;
/* some OSs will return APR_SUCCESS/APR_REG if we stat
* Otherwise (as is the case with most dir_merged/file_merged requests)
return OK;
return OK;
int sec_idx;
char *save_path_info;
char *buf;
#ifdef CASE_BLIND_FILESYSTEM
r->path_info,
!= APR_SUCCESS) {
return HTTP_INTERNAL_SERVER_ERROR;
#ifdef CASE_BLIND_FILESYSTEM
canonical_len = 0;
while (canonical_len
(const char **)&r->path_info,
r->pool);
(const char **)&r->path_info,
canonical_len = 0;
(const char **)&r->path_info,
0, r->pool);
return HTTP_INTERNAL_SERVER_ERROR;
sec_idx = 0;
int res;
char *seg_name;
char *delim;
int temp_slash=0;
if (matches) {
++last_walk;
--matches;
matches = 0;
if (now_merged) {
if (res) {
return res;
if (!htaccess_conf) {
if (matches) {
++last_walk;
--matches;
matches = 0;
if (now_merged) {
if (temp_slash) {
if (delim) {
++seg_name;
if (!*seg_name) {
#ifdef CASE_BLIND_FILESYSTEM
++seg;
r->pool);
r->filename);
r->filename);
++seg;
if (save_path_info) {
if (!entry_core->r) {
if (matches) {
++last_walk;
--matches;
matches = 0;
if (now_merged) {
if (matches) {
x * APR_DIR test. But if you accessed /symlink/index.html, for example,
if (now_merged) {
r->per_dir_config,
return OK;
&core_module);
const char *entry_uri;
if (!num_sec) {
return OK;
/* Location and LocationMatch differ on their behaviour w.r.t. multiple
* Otherwise (as is the case with most dir_merged/file_merged requests)
return OK;
return OK;
if (entry_core->r
if (matches) {
++last_walk;
--matches;
matches = 0;
if (now_merged) {
if (matches) {
if (now_merged) {
r->per_dir_config,
return OK;
&core_module);
const char *test_file;
return OK;
if (!num_sec) {
return OK;
return OK;
return OK;
int sec_idx;
if (entry_core->r
if (matches) {
++last_walk;
--matches;
matches = 0;
if (now_merged) {
if (matches) {
if (now_merged) {
r->per_dir_config,
return OK;
if (next_filter) {
return rnew;
if (APR_BUCKET_IS_EOS(e)) {
return APR_SUCCESS;
if (!reqs_arr) {
const char *new_uri,
const request_rec *r,
char *udir;
if (ap_is_recursion_limit_exceeded(r)) {
return rnew;
if (next_filter) {
return rnew;
const request_rec *r,
const request_rec *r,
int subtype,
int res;
char *fdir;
char *udir;
udir,
!= OK) {
return rnew;
if (ap_is_recursion_limit_exceeded(r)) {
return rnew;
return rnew;
const request_rec *r,
int res;
char *fdir;
return rnew;
if (ap_is_recursion_limit_exceeded(r)) {
return rnew;
return rnew;
return retval;