request.c revision 48e4b65042d94992c50f1db6c0b0cdbd99ca77e8
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere/* Licensed to the Apache Software Foundation (ASF) under one or more
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * contributor license agreements. See the NOTICE file distributed with
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * this work for additional information regarding copyright ownership.
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * The ASF licenses this file to You under the Apache License, Version 2.0
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * (the "License"); you may not use this file except in compliance with
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * the License. You may obtain a copy of the License at
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * Unless required by applicable law or agreed to in writing, software
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * distributed under the License is distributed on an "AS IS" BASIS,
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * See the License for the specific language governing permissions and
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * limitations under the License.
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * @brief functions to get and process requests
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * @author Rob McCool 3/21/93
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * Thoroughly revamped by rst for Apache. NB this file reads
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * best from the bottom up.
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclereAP_IMPLEMENT_HOOK_VOID(insert_filter, (request_rec *r), (r))
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclerestatic int decl_die(int status, const char *phase, request_rec *r)
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor/* This is the master logic for processing requests. Do NOT duplicate
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * this logic elsewhere, or the security model will be broken by future
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * API changes. Each phase must be individually optimized to pick up
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * redundant/duplicate calls by subrequests, and redirects.
999942e8e84bcae9b439ab30a040b1b997b343c9gryzorAP_DECLARE(int) ap_process_request_internal(request_rec *r)
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere /* Ignore embedded %2F's in path for proxy requests */
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere d = ap_get_module_config(r->per_dir_config, &core_module);
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere access_status = ap_unescape_url_keep2f(r->parsed_uri.path);
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere access_status = ap_unescape_url(r->parsed_uri.path);
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere "found %%2f (encoded '/') in URI "
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor "(decoded='%s'), returning 404",
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ap_getparents(r->uri); /* OK --- shrinking transformations... */
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor /* All file subrequests are a huge pain... they cannot bubble through the
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * next several steps. Only file subrequests are allowed an empty uri,
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * otherwise let translate_name kill the request.
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere d = ap_get_module_config(r->per_dir_config, &core_module);
ba543b319188dc1887607f6d59feddc00e38eee2humbedooh /* Reset to the server default config prior to running map_to_storage
0d0ba3a410038e179b695446bb149cce6264e0abnd /* This request wasn't in storage (e.g. TRACE) */
0d0ba3a410038e179b695446bb149cce6264e0abnd /* Rerun the location walk, which overrides any map_to_storage config.
5effc8b39fae5cd169d17f342bfc265705840014rbowen d = ap_get_module_config(r->per_dir_config, &core_module);
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd /* Only on the main request! */
return access_status;
switch (ap_satisfies(r)) {
case SATISFY_ALL:
case SATISFY_NOSPEC:
r->uri);
case SATISFY_ANY:
r->uri);
r->uri);
* 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;
int count;
if ((r->prev
&& *inherit_note)
|| (r->main
&& *inherit_note)) {
if (copy_cache) {
return cache;
const char *savename;
return HTTP_FORBIDDEN;
!= APR_SUCCESS)
return HTTP_FORBIDDEN;
if (savename) {
return OK;
!= APR_SUCCESS)
return HTTP_FORBIDDEN;
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;
int cached;
r->uri);
return OK;
!= APR_SUCCESS) {
return OK;
/* some OSs will return APR_SUCCESS/APR_REG if we stat
if (cached
int familiar = 0;
* Otherwise (as is the case with most dir_merged/file_merged requests)
if (familiar) {
int res;
r->pool);
r->filename);
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;
cached = 0;
if (now_merged) {
if (res) {
return res;
if (!htaccess_conf) {
if (matches) {
++last_walk;
--matches;
matches = 0;
cached = 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;
cached = 0;
if (now_merged) {
if (matches) {
cached = 0;
cached = 0;
x * APR_DIR test. But if you accessed /symlink/index.html, for example,
if (cached
return OK;
if (now_merged) {
r->per_dir_config,
return OK;
&core_module);
const char *entry_uri;
int cached;
if (!num_sec) {
return OK;
/* Location and LocationMatch differ on their behaviour w.r.t. multiple
if (cached
* Otherwise (as is the case with most dir_merged/file_merged requests)
return OK;
if (entry_core->r
|| (len > 0
if (matches) {
++last_walk;
--matches;
matches = 0;
cached = 0;
if (now_merged) {
if (matches) {
cached = 0;
cached = 0;
if (cached
return OK;
if (now_merged) {
r->per_dir_config,
return OK;
&core_module);
const char *test_file;
int cached;
return OK;
if (!num_sec) {
return OK;
if (cached
return OK;
int sec_idx;
if (entry_core->r
if (matches) {
++last_walk;
--matches;
matches = 0;
cached = 0;
if (now_merged) {
if (matches) {
cached = 0;
cached = 0;
if (cached
return OK;
if (now_merged) {
r->per_dir_config,
return OK;
&core_module);
int cached;
int sec_idx;
int matches;
int cached_matches;
if (!num_sec) {
return OK;
int rc;
if (rc <= 0) {
if (rc < 0)
err);
if (matches) {
++last_walk;
--matches;
matches = 0;
cached = 0;
if (now_merged) {
if (matches) {
cached = 0;
cached = 0;
if (cached
return OK;
if (now_merged) {
r->per_dir_config,
return OK;
if (next_filter) {
return rnew;
if (APR_BUCKET_IS_EOS(e)) {
return APR_SUCCESS;
return ap__authz_ap_some_auth_required(r);
int total_auth_hooks = 0;
int total_auth_providers = 0;
const char *provider_group,
const char *provider_name,
const char *provider_version,
const void *provider,
int type)
const char * const *aszPre,
const char * const *aszSucc,
const char * const *aszPre,
const char * const *aszSucc,
const char * const *aszPre,
const char * const *aszSucc,
const char * const *aszPre,
const char * const *aszSucc,
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;