This is the master logic for processing requests. Do NOT duplicate * this logic elsewhere, or the security model will be broken by future * API changes. Each phase must be individually optimized to pick up * redundant/duplicate calls by subrequests, and redirects. */
| 185 | * redundant/duplicate calls by subrequests, and redirects. |
| 186 | */ |
| 187 | AP_DECLARE(int) ap_process_request_internal(request_rec *r) |
| 188 | { |
| 189 | int access_status = DECLINED; |
| 190 | int file_req = (r->main && r->filename); |
| 191 | core_server_config *sconf = |
| 192 | ap_get_core_module_config(r->server->module_config); |
| 193 | unsigned int normalize_flags; |
| 194 | |
| 195 | normalize_flags = AP_NORMALIZE_NOT_ABOVE_ROOT; |
| 196 | if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { |
| 197 | normalize_flags |= AP_NORMALIZE_MERGE_SLASHES; |
| 198 | } |
| 199 | if (file_req) { |
| 200 | /* File subrequests can have a relative path. */ |
| 201 | normalize_flags |= AP_NORMALIZE_ALLOW_RELATIVE; |
| 202 | } |
| 203 | |
| 204 | if (r->parsed_uri.path) { |
| 205 | /* Normalize: remove /./ and shrink /../ segments, plus |
| 206 | * decode unreserved chars (first time only to avoid |
| 207 | * double decoding after ap_unescape_url() below). |
| 208 | */ |
| 209 | if (!ap_normalize_path(r->parsed_uri.path, |
| 210 | normalize_flags | |
| 211 | AP_NORMALIZE_DECODE_UNRESERVED)) { |
| 212 | ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10244) |
| 213 | "invalid URI path (%s)", r->unparsed_uri); |
| 214 | return HTTP_BAD_REQUEST; |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | /* All file subrequests are a huge pain... they cannot bubble through the |
| 219 | * next several steps. Only file subrequests are allowed an empty uri, |
| 220 | * otherwise let (pre_)translate_name kill the request. |
| 221 | */ |
| 222 | if (!file_req) { |
| 223 | ap_conf_vector_t *per_dir_config = r->per_dir_config; |
| 224 | |
| 225 | if ((access_status = walk_location_and_if(r))) { |
| 226 | return access_status; |
| 227 | } |
| 228 | |
| 229 | /* Let pre_translate_name hooks work with non-decoded URIs, and |
| 230 | * eventually prevent further URI transformations (return DONE). |
| 231 | */ |
| 232 | access_status = ap_run_pre_translate_name(r); |
| 233 | if (ap_is_HTTP_ERROR(access_status)) { |
| 234 | return access_status; |
| 235 | } |
| 236 | |
| 237 | /* Throw away pre_trans only merging */ |
| 238 | r->per_dir_config = per_dir_config; |
| 239 | } |
| 240 | |
| 241 | /* Ignore URL unescaping for translated URIs already */ |
| 242 | if (access_status != DONE && r->parsed_uri.path) { |
| 243 | core_dir_config *d = ap_get_core_module_config(r->per_dir_config); |
| 244 | /* Unreserved chars were already decoded by ap_normalize_path() */ |
no test coverage detected