You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by sf...@apache.org on 2011/01/17 12:02:38 UTC
svn commit: r1059867 - in /httpd/httpd/trunk: CHANGES include/ap_mmn.h
include/http_core.h include/http_request.h server/core.c server/request.c
Author: sf
Date: Mon Jan 17 11:02:38 2011
New Revision: 1059867
URL: http://svn.apache.org/viewvc?rev=1059867&view=rev
Log:
Merge the <If> sections in a separate step ap_if_walk, after ap_location_walk.
This makes <If> apply to all requests, not only to file base requests and
it allows to use <If> inside <Directory>, <Location>, and <Files> sections.
The merging of <If> sections always happens after the merging of <Location>
sections, even if the <If> section is embedded inside a <Directory> or
<Files> section.
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/include/ap_mmn.h
httpd/httpd/trunk/include/http_core.h
httpd/httpd/trunk/include/http_request.h
httpd/httpd/trunk/server/core.c
httpd/httpd/trunk/server/request.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1059867&r1=1059866&r2=1059867&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Mon Jan 17 11:02:38 2011
@@ -2,6 +2,12 @@
Changes with Apache 2.3.11
+ *) core: Apply <If> sections to all requests, not only to file base requests.
+ Allow to use <If> inside <Directory>, <Location>, and <Files> sections.
+ The merging of <If> sections now happens after the merging of <Location>
+ sections, even if an <If> section is embedded inside a <Directory> or
+ <Files> section. [Stefan Fritsch]
+
*) mod_proxy: Refactor usage of shared data by dropping the scoreboard
and using slotmem. Create foundation for dynamic growth/changes of
members within a balancer. Remove BalancerNonce in favor of a
Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1059867&r1=1059866&r2=1059867&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Mon Jan 17 11:02:38 2011
@@ -294,14 +294,16 @@
* info from scoreboard and use slotmem; Allow
* dynamic growth of balancer members; Remove
* BalancerNonce in favor of 'nonce' parameter.
+ * 20110117.0 (2.3.11-dev) Merge <If> sections in separate step (ap_if_walk).
+ * Add core_dir_config->sec_if.
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20101223
+#define MODULE_MAGIC_NUMBER_MAJOR 20110117
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
Modified: httpd/httpd/trunk/include/http_core.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/http_core.h?rev=1059867&r1=1059866&r2=1059867&view=diff
==============================================================================
--- httpd/httpd/trunk/include/http_core.h (original)
+++ httpd/httpd/trunk/include/http_core.h Mon Jan 17 11:02:38 2011
@@ -362,7 +362,8 @@ typedef struct {
#define AP_NOTE_DIRECTORY_WALK 0
#define AP_NOTE_LOCATION_WALK 1
#define AP_NOTE_FILE_WALK 2
-#define AP_NUM_STD_NOTES 3
+#define AP_NOTE_IF_WALK 3
+#define AP_NUM_STD_NOTES 4
/**
* Reserve an element in the core_request_config->notes array
@@ -499,6 +500,7 @@ typedef struct {
/* Access control */
apr_array_header_t *sec_file;
+ apr_array_header_t *sec_if;
ap_regex_t *r;
const char *mime_type; /* forced with ForceType */
@@ -597,6 +599,7 @@ void ap_core_reorder_directories(apr_poo
AP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config);
AP_CORE_DECLARE(void) ap_add_per_url_conf(server_rec *s, void *url_config);
AP_CORE_DECLARE(void) ap_add_file_conf(core_dir_config *conf, void *url_config);
+AP_CORE_DECLARE(void) ap_add_if_conf(core_dir_config *conf, void *url_config);
AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy, const char *arg);
/* Core filters; not exported. */
Modified: httpd/httpd/trunk/include/http_request.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/http_request.h?rev=1059867&r1=1059866&r2=1059867&view=diff
==============================================================================
--- httpd/httpd/trunk/include/http_request.h (original)
+++ httpd/httpd/trunk/include/http_request.h Mon Jan 17 11:02:38 2011
@@ -531,6 +531,7 @@ AP_DECLARE_HOOK(void,insert_filter,(requ
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);
+AP_DECLARE(int) ap_if_walk(request_rec *r);
/** End Of REQUEST (EOR) bucket */
AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_eor;
Modified: httpd/httpd/trunk/server/core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=1059867&r1=1059866&r2=1059867&view=diff
==============================================================================
--- httpd/httpd/trunk/server/core.c (original)
+++ httpd/httpd/trunk/server/core.c Mon Jan 17 11:02:38 2011
@@ -143,6 +143,7 @@ static void *create_core_dir_config(apr_
conf->limit_req_body = AP_LIMIT_REQ_BODY_UNSET;
conf->limit_xml_body = AP_LIMIT_UNSET;
conf->sec_file = apr_array_make(a, 2, sizeof(ap_conf_vector_t *));
+ conf->sec_if = apr_array_make(a, 2, sizeof(ap_conf_vector_t *));
conf->server_signature = srv_sig_unset;
@@ -301,6 +302,17 @@ static void *merge_core_dir_configs(apr_
/* Otherwise we simply use the base->sec_file array
*/
+ if (!conf->sec_if) {
+ conf->sec_if = new->sec_if;
+ }
+ else if (new->sec_if) {
+ /* If we merge, the merge-result must have it's own array
+ */
+ conf->sec_if = apr_array_append(a, base->sec_if, new->sec_if);
+ }
+ /* Otherwise we simply use the base->sec_if array
+ */
+
if (new->server_signature != srv_sig_unset) {
conf->server_signature = new->server_signature;
}
@@ -510,6 +522,14 @@ AP_CORE_DECLARE(void) ap_add_file_conf(c
*new_space = url_config;
}
+AP_CORE_DECLARE(void) ap_add_if_conf(core_dir_config *conf, void *url_config)
+{
+ void **new_space = (void **)apr_array_push(conf->sec_if);
+
+ *new_space = url_config;
+}
+
+
/* We need to do a stable sort, qsort isn't stable. So to make it stable
* we'll be maintaining the original index into the list, and using it
* as the minor key during sorting. The major key is the number of
@@ -2035,8 +2055,7 @@ static const char *ifsection(cmd_parms *
core_dir_config *conf;
const command_rec *thiscmd = cmd->cmd;
ap_conf_vector_t *new_file_conf = ap_create_per_dir_config(cmd->pool);
- const char *err = ap_check_cmd_context(cmd,
- NOT_IN_LOCATION | NOT_IN_LIMIT);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
const char *condition;
const char *expr_err;
@@ -2078,7 +2097,7 @@ static const char *ifsection(cmd_parms *
conf->d_is_fnmatch = 0;
conf->r = NULL;
- ap_add_file_conf((core_dir_config *)mconfig, new_file_conf);
+ ap_add_if_conf((core_dir_config *)mconfig, new_file_conf);
if (*arg != '\0') {
return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name,
Modified: httpd/httpd/trunk/server/request.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/request.c?rev=1059867&r1=1059866&r2=1059867&view=diff
==============================================================================
--- httpd/httpd/trunk/server/request.c (original)
+++ httpd/httpd/trunk/server/request.c Mon Jan 17 11:02:38 2011
@@ -152,6 +152,9 @@ AP_DECLARE(int) ap_process_request_inter
if ((access_status = ap_location_walk(r))) {
return access_status;
}
+ if ((access_status = ap_if_walk(r))) {
+ return access_status;
+ }
d = ap_get_module_config(r->per_dir_config, &core_module);
if (d->log) {
@@ -177,6 +180,9 @@ AP_DECLARE(int) ap_process_request_inter
if ((access_status = ap_location_walk(r))) {
return access_status;
}
+ if ((access_status = ap_if_walk(r))) {
+ return access_status;
+ }
d = ap_get_module_config(r->per_dir_config, &core_module);
if (d->log) {
@@ -1527,24 +1533,15 @@ AP_DECLARE(int) ap_file_walk(request_rec
* really try them with the most general first.
*/
for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) {
- const char *err = NULL;
core_dir_config *entry_core;
entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module);
- if (entry_core->condition) {
- /* XXX: error handling */
- if (ap_expr_exec(r, entry_core->condition, &err) <= 0) {
- continue;
- }
- }
- else {
- if (entry_core->r
- ? ap_regexec(entry_core->r, cache->cached , 0, NULL, 0)
- : (entry_core->d_is_fnmatch
- ? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME)
- : strcmp(entry_core->d, cache->cached))) {
- continue;
- }
+ if (entry_core->r
+ ? ap_regexec(entry_core->r, cache->cached , 0, NULL, 0)
+ : (entry_core->d_is_fnmatch
+ ? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME)
+ : strcmp(entry_core->d, cache->cached))) {
+ continue;
}
/* If we merged this same section last time, reuse it
@@ -1614,6 +1611,119 @@ AP_DECLARE(int) ap_file_walk(request_rec
return OK;
}
+AP_DECLARE(int) ap_if_walk(request_rec *r)
+{
+ ap_conf_vector_t *now_merged = NULL;
+ core_dir_config *dconf = ap_get_module_config(r->per_dir_config,
+ &core_module);
+ ap_conf_vector_t **sec_ent = (ap_conf_vector_t **)dconf->sec_if->elts;
+ int num_sec = dconf->sec_if->nelts;
+ walk_cache_t *cache;
+ int cached;
+ int sec_idx;
+ int matches;
+ int cached_matches;
+ walk_walked_t *last_walk;
+
+ /* No tricks here, there are just no <If > to parse in this context.
+ * We won't destroy the cache, just in case _this_ redirect is later
+ * redirected again to a context containing the same or similar <If >.
+ */
+ if (!num_sec) {
+ return OK;
+ }
+
+ cache = prep_walk_cache(AP_NOTE_IF_WALK, r);
+ cached = (cache->cached != NULL);
+ cache->cached = (void *)1;
+ matches = cache->walked->nelts;
+ cached_matches = matches;
+ last_walk = (walk_walked_t*)cache->walked->elts;
+
+ cached &= auth_internal_per_conf;
+
+ /* Go through the if entries, and check for matches */
+ for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) {
+ const char *err = NULL;
+ core_dir_config *entry_core;
+ int rc;
+ entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module);
+
+ rc = ap_expr_exec(r, entry_core->condition, &err);
+ if (rc <= 0) {
+ if (rc < 0)
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Failed to evaluate <If > condition: %s",
+ err);
+ continue;
+ }
+
+ /* If we merged this same section last time, reuse it
+ */
+ if (matches) {
+ if (last_walk->matched == sec_ent[sec_idx]) {
+ now_merged = last_walk->merged;
+ ++last_walk;
+ --matches;
+ continue;
+ }
+
+ /* We fell out of sync. This is our own copy of walked,
+ * so truncate the remaining matches and reset remaining.
+ */
+ cache->walked->nelts -= matches;
+ matches = 0;
+ cached = 0;
+ }
+
+ if (now_merged) {
+ now_merged = ap_merge_per_dir_configs(r->pool,
+ now_merged,
+ sec_ent[sec_idx]);
+ }
+ else {
+ now_merged = sec_ent[sec_idx];
+ }
+
+ last_walk = (walk_walked_t*)apr_array_push(cache->walked);
+ last_walk->matched = sec_ent[sec_idx];
+ last_walk->merged = now_merged;
+ }
+
+ /* Everything matched in sequence, but it may be that the original
+ * walk found some additional matches (which we need to truncate), or
+ * this walk found some additional matches.
+ */
+ if (matches) {
+ cache->walked->nelts -= matches;
+ cached = 0;
+ }
+ else if (cache->walked->nelts > cached_matches) {
+ cached = 0;
+ }
+
+ if (cached
+ && r->per_dir_config == cache->dir_conf_merged) {
+ r->per_dir_config = cache->per_dir_result;
+ return OK;
+ }
+
+ cache->dir_conf_tested = sec_ent;
+ cache->dir_conf_merged = r->per_dir_config;
+
+ /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs,
+ * and note the end result to (potentially) skip this step next time.
+ */
+ if (now_merged) {
+ r->per_dir_config = ap_merge_per_dir_configs(r->pool,
+ r->per_dir_config,
+ now_merged);
+ }
+ cache->per_dir_result = r->per_dir_config;
+
+ return OK;
+}
+
/*****************************************************************
*
* The sub_request mechanism.