mirror of
https://github.com/apache/httpd.git
synced 2025-08-07 04:02:58 +03:00
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
This commit is contained in:
6
CHANGES
6
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
|
||||
|
@@ -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 <Proxy > 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
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
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);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NB: directory_walk() clears the per_dir_config, so we don't inherit
|
||||
* from location_walk() above
|
||||
*/
|
||||
|
||||
if ((access_status = directory_walk(r))) {
|
||||
else
|
||||
ap_die(access_status, r);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((access_status = file_walk(r))) {
|
||||
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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user