From 307ab558867a23cf46bdc3eb69e44c769e9adf98 Mon Sep 17 00:00:00 2001 From: "William A. Rowe Jr" Date: Sat, 25 Aug 2001 23:43:19 +0000 Subject: [PATCH] Introduce the map_to_storage hook, which allows modules to bypass the directory_walk and file_walk for non-file requests. TRACE shortcut moved to http_protocol.c as APR_HOOK_MIDDLE, and the directory_walk/file_walk happen as APR_HOOK_VERY_LAST in core.c. A seperate patch to mod_proxy is required to short circuit both the TRACE and directory_walk/file_walk stuff. That patch is next. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90665 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 6 +++++ include/http_request.h | 21 +++++++++++++--- modules/http/http_core.c | 1 + modules/http/http_protocol.c | 7 ++++-- modules/http/http_request.c | 40 ++++++------------------------ modules/http/mod_core.h | 9 ++++--- server/core.c | 21 ++++++++++++++++ server/request.c | 47 +++++++++++++++++++----------------- 8 files changed, 90 insertions(+), 62 deletions(-) diff --git a/CHANGES b/CHANGES index 7319155d76..01bf04ce87 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,11 @@ Changes with Apache 2.0.25-dev + *) Introduce the map_to_storage hook, which allows modules to bypass + the directory_walk and file_walk for non-file requests. TRACE + shortcut moved to http_protocol.c as APR_HOOK_MIDDLE, and the + directory_walk/file_walk happen as APR_HOOK_VERY_LAST in core.c. + [William Rowe] + *) Add the ability for mod_include to add the INCLUDES filter if the file is configured for the server-parsed handler. This makes the configuration for .shtml files much easier diff --git a/include/http_request.h b/include/http_request.h index 21693bdf4b..a4e63fdbcd 100644 --- a/include/http_request.h +++ b/include/http_request.h @@ -288,6 +288,21 @@ AP_DECLARE_HOOK(int,create_request,(request_rec *r)) */ AP_DECLARE_HOOK(int,translate_name,(request_rec *r)) +/** + * This hook allow modules to set the per_dir_config based on their own + * context (such as sections) and responds to contextless requests + * such as TRACE that need no security or filesystem mapping. + * based on the filesystem. + * @param r The current request + * @return DONE (or HTTP_) if this contextless request was just fulfilled + * (such as TRACE), OK if this is not a file, and DECLINED if this is a file. + * The core map_to_storage (HOOK_RUN_LAST) will directory_walk and file_walk + * the r->filename. + * + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,map_to_storage,(request_rec *r)) + /** * This hook allows modules to check the authentication information sent with * the request. @@ -341,9 +356,9 @@ AP_DECLARE_HOOK(int,auth_checker,(request_rec *r)) */ AP_DECLARE_HOOK(void,insert_filter,(request_rec *r)) -AP_DECLARE(int) directory_walk(request_rec *r); -AP_DECLARE(int) location_walk(request_rec *r); -AP_DECLARE(int) file_walk(request_rec *r); +AP_DECLARE(int) ap_location_walk(request_rec *r); +AP_DECLARE(int) ap_directory_walk(request_rec *r); +AP_DECLARE(int) ap_file_walk(request_rec *r); #ifdef __cplusplus } diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 83e1174887..9a86031e5a 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -317,6 +317,7 @@ static void register_hooks(apr_pool_t *p) APR_HOOK_REALLY_LAST); ap_hook_process_connection(ap_process_http_connection,NULL,NULL, APR_HOOK_REALLY_LAST); + ap_hook_map_to_storage(ap_send_http_trace,NULL,NULL,APR_HOOK_MIDDLE); ap_hook_http_method(http_method,NULL,NULL,APR_HOOK_REALLY_LAST); ap_hook_default_port(http_port,NULL,NULL,APR_HOOK_REALLY_LAST); diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index 910942e109..7aeb445a26 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -1023,12 +1023,15 @@ static char *make_allow(request_rec *r) return list + 2; } -AP_DECLARE(int) ap_send_http_trace(request_rec *r) +AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r) { int rv; apr_bucket_brigade *b; header_struct h; + if (r->method_number != M_TRACE) + return DECLINED; + /* Get the original request */ while (r->prev) r = r->prev; @@ -1049,7 +1052,7 @@ AP_DECLARE(int) ap_send_http_trace(request_rec *r) apr_brigade_puts(b, NULL, NULL, CRLF); ap_pass_brigade(r->output_filters, b); - return OK; + return DONE; } AP_DECLARE(int) ap_send_http_options(request_rec *r) diff --git a/modules/http/http_request.c b/modules/http/http_request.c index f208936f2f..01258f7f22 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -253,7 +253,7 @@ static void process_request_internal(request_rec *r) ap_getparents(r->uri); /* OK --- shrinking transformations... */ - if ((access_status = location_walk(r))) { + if ((access_status = ap_location_walk(r))) { ap_die(access_status, r); return; } @@ -263,40 +263,16 @@ static void process_request_internal(request_rec *r) return; } - if (r->proto_num > HTTP_VERSION(1,0) && apr_table_get(r->subprocess_env, "downgrade-1.0")) { - r->proto_num = HTTP_VERSION(1,0); - } - - if (!r->proxyreq) { - /* - * We don't want TRACE to run through the normal handler set, we - * handle it specially. - */ - if (r->method_number == M_TRACE) { - if ((access_status = ap_send_http_trace(r))) - ap_die(access_status, r); - else - ap_finalize_request_protocol(r); - return; - } - } - - /* - * NB: directory_walk() clears the per_dir_config, so we don't inherit - * from location_walk() above - */ - - if ((access_status = directory_walk(r))) { - ap_die(access_status, r); - return; - } - - if ((access_status = file_walk(r))) { - ap_die(access_status, r); + if ((access_status = ap_run_map_to_storage(r))) { + /* This request wasn't in storage (e.g. TRACE) */ + if (access_status == DONE) + ap_finalize_request_protocol(r); + else + ap_die(access_status, r); return; } - if ((access_status = location_walk(r))) { + if ((access_status = ap_location_walk(r))) { ap_die(access_status, r); return; } diff --git a/modules/http/mod_core.h b/modules/http/mod_core.h index 8ad7918d51..8622a00343 100644 --- a/modules/http/mod_core.h +++ b/modules/http/mod_core.h @@ -92,13 +92,16 @@ char *ap_response_code_string(request_rec *r, int error_index); AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb); /** - * XXX NEED DOC + * Send an appropriate response to an http TRACE request. * @param r The current request + * @tip returns DONE or the HTTP status error if it handles the TRACE, + * or DECLINED if the request was not for TRACE. + * request method was not TRACE. */ -AP_DECLARE(int) ap_send_http_trace(request_rec *r); +AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r); /** - * XXX NEED DOC + * Send an appropriate response to an http OPTIONS request. * @param r The current request */ AP_DECLARE(int) ap_send_http_options(request_rec *r); diff --git a/server/core.c b/server/core.c index 84ad34955a..6598e6b799 100644 --- a/server/core.c +++ b/server/core.c @@ -2952,6 +2952,26 @@ AP_DECLARE_NONSTD(int) ap_core_translate(request_rec *r) return OK; } +/***************************************************************** + * + * Test the filesystem name through directory_walk and file_walk + */ +static int core_map_to_storage(request_rec *r) +{ + int access_status; + + if ((access_status = ap_directory_walk(r))) { + return access_status; + } + + if ((access_status = ap_file_walk(r))) { + return access_status; + } + + return OK; +} + + static int do_nothing(request_rec *r) { return OK; } static int default_handler(request_rec *r) @@ -3376,6 +3396,7 @@ static void register_hooks(apr_pool_t *p) { ap_hook_post_config(core_post_config,NULL,NULL,APR_HOOK_REALLY_FIRST); ap_hook_translate_name(ap_core_translate,NULL,NULL,APR_HOOK_REALLY_LAST); + ap_hook_map_to_storage(core_map_to_storage,NULL,NULL,APR_HOOK_REALLY_LAST); ap_hook_open_logs(core_open_logs,NULL,NULL,APR_HOOK_MIDDLE); ap_hook_handler(default_handler,NULL,NULL,APR_HOOK_REALLY_LAST); /* FIXME: I suspect we can eliminate the need for these - Ben */ diff --git a/server/request.c b/server/request.c index 793a16d74d..ef7041456f 100644 --- a/server/request.c +++ b/server/request.c @@ -93,6 +93,7 @@ APR_HOOK_STRUCT( APR_HOOK_LINK(translate_name) + APR_HOOK_LINK(map_to_storage) APR_HOOK_LINK(check_user_id) APR_HOOK_LINK(fixups) APR_HOOK_LINK(type_checker) @@ -104,6 +105,8 @@ APR_HOOK_STRUCT( AP_IMPLEMENT_HOOK_RUN_FIRST(int,translate_name, (request_rec *r),(r),DECLINED) +AP_IMPLEMENT_HOOK_RUN_FIRST(int,map_to_storage, + (request_rec *r),(r),DECLINED) AP_IMPLEMENT_HOOK_RUN_FIRST(int,check_user_id, (request_rec *r),(r),DECLINED) AP_IMPLEMENT_HOOK_RUN_ALL(int,fixups, @@ -379,7 +382,7 @@ static int get_path_info(request_rec *r) return OK; } -AP_DECLARE(int) directory_walk(request_rec *r) +AP_DECLARE(int) ap_directory_walk(request_rec *r) { core_server_config *sconf = ap_get_module_config(r->server->module_config, &core_module); @@ -455,7 +458,7 @@ AP_DECLARE(int) directory_walk(request_rec *r) return OK; } - /* The replacement code [above] for directory_walk eliminates this issue. + /* The replacement code [below] for directory_walk eliminates this issue. */ res = get_path_info(r); if (res != OK) { @@ -699,7 +702,7 @@ AP_DECLARE(int) directory_walk(request_rec *r) * they change, all the way down. */ -AP_DECLARE(int) directory_walk(request_rec *r) +AP_DECLARE(int) ap_directory_walk(request_rec *r) { core_server_config *sconf = ap_get_module_config(r->server->module_config, &core_module); @@ -1035,7 +1038,8 @@ AP_DECLARE(int) directory_walk(request_rec *r) #endif /* defined REPLACE_PATH_INFO_METHOD */ -AP_DECLARE(int) location_walk(request_rec *r) + +AP_DECLARE(int) ap_location_walk(request_rec *r) { core_server_config *sconf = ap_get_module_config(r->server->module_config, &core_module); @@ -1106,7 +1110,7 @@ AP_DECLARE(int) location_walk(request_rec *r) return OK; } -AP_DECLARE(int) file_walk(request_rec *r) +AP_DECLARE(int) ap_file_walk(request_rec *r) { core_dir_config *conf = ap_get_module_config(r->per_dir_config, &core_module); @@ -1168,7 +1172,6 @@ AP_DECLARE(int) file_walk(request_rec *r) return OK; } - /***************************************************************** * * The sub_request mechanism. @@ -1318,7 +1321,7 @@ AP_DECLARE(request_rec *) ap_sub_req_method_uri(const char *method, ap_getparents(rnew->uri); - if ((res = location_walk(rnew))) { + if ((res = ap_location_walk(rnew))) { rnew->status = res; return rnew; } @@ -1340,9 +1343,9 @@ AP_DECLARE(request_rec *) ap_sub_req_method_uri(const char *method, * from location_walk() above */ - if ((res = directory_walk(rnew)) - || (res = file_walk(rnew)) - || (res = location_walk(rnew)) + if ((res = ap_directory_walk(rnew)) + || (res = ap_file_walk(rnew)) + || (res = ap_location_walk(rnew)) || (res = sub_req_common_validation(rnew))) { rnew->status = res; } @@ -1439,17 +1442,17 @@ AP_DECLARE(request_rec *) ap_sub_req_lookup_dirent(const apr_finfo_t *dirent, * directory_walk */ if (rnew->finfo.filetype == APR_DIR) { - if (!(res = directory_walk(rnew))) - if (!(res = file_walk(rnew))) - res = location_walk(rnew); + if (!(res = ap_directory_walk(rnew))) + if (!(res = ap_file_walk(rnew))) + res = ap_location_walk(rnew); } else if (rnew->finfo.filetype == APR_REG || !rnew->finfo.filetype) { /* * do a file_walk, if it doesn't change the per_dir_config then * we know that we don't have to redo all the access checks */ - if ( !(res = file_walk(rnew)) - && !(res = location_walk(rnew)) + if ( !(res = ap_file_walk(rnew)) + && !(res = ap_location_walk(rnew)) && (rnew->per_dir_config == r->per_dir_config)) { if ( (res = ap_run_type_checker(rnew)) @@ -1558,17 +1561,17 @@ AP_DECLARE(request_rec *) ap_sub_req_lookup_file(const char *new_file, * directory_walk */ if (rnew->finfo.filetype == APR_DIR) { - if (!(res = directory_walk(rnew))) - if (!(res = file_walk(rnew))) - res = location_walk(rnew); + if (!(res = ap_directory_walk(rnew))) + if (!(res = ap_file_walk(rnew))) + res = ap_location_walk(rnew); } else if (rnew->finfo.filetype == APR_REG || !rnew->finfo.filetype) { /* * do a file_walk, if it doesn't change the per_dir_config then * we know that we don't have to redo all the access checks */ - if ( !(res = file_walk(rnew)) - && !(res = location_walk(rnew)) + if ( !(res = ap_file_walk(rnew)) + && !(res = ap_location_walk(rnew)) && (rnew->per_dir_config == r->per_dir_config)) { if ( (res = ap_run_type_checker(rnew)) @@ -1595,9 +1598,9 @@ AP_DECLARE(request_rec *) ap_sub_req_lookup_file(const char *new_file, */ rnew->uri = "INTERNALLY GENERATED file-relative req"; rnew->per_dir_config = r->server->lookup_defaults; - res = directory_walk(rnew); + res = ap_directory_walk(rnew); if (!res) { - res = file_walk(rnew); + res = ap_file_walk(rnew); } } -- 2.50.1