summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author(no author) <(no author)@unknown>2003-05-28 04:50:15 +0000
committer(no author) <(no author)@unknown>2003-05-28 04:50:15 +0000
commit13d25cd681ca3c80ab0ea1bbcfb4d8727736b78e (patch)
treee04b44346cd921b021ba69d3a70d726b529fed92
parent3fe01f3dd7085a5867efedf5d178d9d6829e12a1 (diff)
downloadhttpd-2.0.46.tar.gz
This commit was manufactured by cvs2svn to create tag2.0.46
'APACHE_2_0_46'. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/tags/2.0.46@100062 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES12
-rw-r--r--docs/manual/content-negotiation.html.en14
-rw-r--r--docs/manual/content-negotiation.xml14
-rw-r--r--docs/manual/env.html.en12
-rw-r--r--docs/manual/env.xml12
-rw-r--r--modules/mappers/mod_negotiation.c148
-rw-r--r--modules/metadata/mod_expires.c195
7 files changed, 106 insertions, 301 deletions
diff --git a/CHANGES b/CHANGES
index 71628f7f86..f3cfb6cf5a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,17 @@
Changes with Apache 2.0.46
+ *) SECURITY [CAN-2003-0245]: Fixed a bug that could be triggered
+ remotely through mod_dav and possibly other mechanisms, causing
+ an Apache child process to crash. The crash was first reported
+ by David Endler <DEndler@iDefense.com> and was researched and
+ fixed by Joe Orton <jorton@redhat.com>. Details will be released
+ on 30 May 2003.
+
+ *) SECURITY [CAN-2003-0189]: Fixed a denial-of-service vulnerability
+ affecting basic authentication on Unix platforms related to
+ thread-safety in apr_password_validate(). The problem was reported
+ by John Hughes <john.hughes@entegrity.com>.
+
*) Fix for mod_dav. Call the 'can_be_activity' callback, if provided,
when a MKACTIVITY request comes in.
[Ben Collins-Sussman <sussman@collab.net>]
diff --git a/docs/manual/content-negotiation.html.en b/docs/manual/content-negotiation.html.en
index 937af9647f..9baa734680 100644
--- a/docs/manual/content-negotiation.html.en
+++ b/docs/manual/content-negotiation.html.en
@@ -480,20 +480,6 @@ Negotiation</a></li>
specification and to work effectively with properly configured
clients.</p>
- <p>In order to support advanced techniques (such as Cookies or
- special URL-paths) to determine the user's preferred language,
- since Apache 2.0.46 <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> recognizes
- the <a href="env.html">environment variable</a>
- <code>prefer-language</code>. If it exists and contains an
- appropriate language tag, <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> will
- try to select a matching variant. If there's no such variant,
- the normal negotiation process applies.</p>
-
- <div class="example"><h3>Example</h3><p><code>
- SetEnvIf Cookie "language=en" prefer-language=en
- SetEnvIf Cookie "language=fr" prefer-language=fr
- </code></p></div>
-
</div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div>
<div class="section">
<h2><a name="extensions" id="extensions">Extensions to Transparent Content
diff --git a/docs/manual/content-negotiation.xml b/docs/manual/content-negotiation.xml
index 0618696e02..ee7562b89d 100644
--- a/docs/manual/content-negotiation.xml
+++ b/docs/manual/content-negotiation.xml
@@ -465,20 +465,6 @@
This is necessary to maintain compliance with the HTTP/1.1
specification and to work effectively with properly configured
clients.</p>
-
- <p>In order to support advanced techniques (such as Cookies or
- special URL-paths) to determine the user's preferred language,
- since Apache 2.0.46 <module>mod_negotiation</module> recognizes
- the <a href="env.html">environment variable</a>
- <code>prefer-language</code>. If it exists and contains an
- appropriate language tag, <module>mod_negotiation</module> will
- try to select a matching variant. If there's no such variant,
- the normal negotiation process applies.</p>
-
- <example><title>Example</title>
- SetEnvIf Cookie "language=en" prefer-language=en
- SetEnvIf Cookie "language=fr" prefer-language=fr
- </example>
</section>
</section>
diff --git a/docs/manual/env.html.en b/docs/manual/env.html.en
index 95ae3c8ea3..6c37c2c454 100644
--- a/docs/manual/env.html.en
+++ b/docs/manual/env.html.en
@@ -268,18 +268,6 @@
<p>This disables <code class="directive"><a href="./mod/core.html#keepalive">KeepAlive</a></code> when set.</p>
-
- <h3><a name="prefer-language" id="prefer-language">prefer-language</a></h3>
-
- <p>This influences <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code>'s behaviour. If
- it contains a language tag (such as <code>en</code>, <code>ja</code>
- or <code>x-klingon</code>), <code class="module"><a href="./mod/mod_negotiation.html">mod_negotiation</a></code> tries
- to deliver a variant with that language. If there's no such variant,
- the normal <a href="content-negotiation.html">negotiation</a> process
- applies.</p>
-
-
-
<h3><a name="redirect-carefully" id="redirect-carefully">redirect-carefully</a></h3>
diff --git a/docs/manual/env.xml b/docs/manual/env.xml
index 58ae9cfd7a..ded93dd7da 100644
--- a/docs/manual/env.xml
+++ b/docs/manual/env.xml
@@ -294,18 +294,6 @@
<p>This disables <directive module="core">KeepAlive</directive> when set.</p>
</section>
-
- <section id="prefer-language"><title>prefer-language</title>
-
- <p>This influences <module>mod_negotiation</module>'s behaviour. If
- it contains a language tag (such as <code>en</code>, <code>ja</code>
- or <code>x-klingon</code>), <module>mod_negotiation</module> tries
- to deliver a variant with that language. If there's no such variant,
- the normal <a href="content-negotiation.html">negotiation</a> process
- applies.</p>
-
- </section>
-
<section id="redirect-carefully">
<title>redirect-carefully</title>
diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c
index b486d6ee78..8f2670ca93 100644
--- a/modules/mappers/mod_negotiation.c
+++ b/modules/mappers/mod_negotiation.c
@@ -2202,134 +2202,74 @@ static int is_variant_better(negotiation_state *neg, var_rec *variant,
return 1;
}
-/* figure out, whether a variant is in a specific language
- * it returns also false, if the variant has no language.
- */
-static int variant_has_language(var_rec *variant, const char *lang)
-{
- int j, max;
-
- /* fast exit */
- if ( !lang
- || !variant->content_languages
- || !(max = variant->content_languages->nelts)) {
- return 0;
- }
-
- for (j = 0; j < max; ++j) {
- if (!strcmp(lang,
- ((char **) (variant->content_languages->elts))[j])) {
- return 1;
- }
- }
-
- return 0;
-}
-
static int best_match(negotiation_state *neg, var_rec **pbest)
{
int j;
- var_rec *best;
+ var_rec *best = NULL;
float bestq = 0.0f;
enum algorithm_results algorithm_result;
var_rec *avail_recs = (var_rec *) neg->avail_vars->elts;
- const char *preferred_language = apr_table_get(neg->r->subprocess_env,
- "prefer-language");
-
set_default_lang_quality(neg);
/*
- * Find the 'best' variant
- * We run the loop possibly twice: if "prefer-language"
- * environment variable is set but we did not find an appropriate
- * best variant. In that case forget the preferred language and
- * negotiate over all variants.
+ * Find the 'best' variant
*/
- do {
- best = NULL;
-
- for (j = 0; j < neg->avail_vars->nelts; ++j) {
- var_rec *variant = &avail_recs[j];
+ for (j = 0; j < neg->avail_vars->nelts; ++j) {
+ var_rec *variant = &avail_recs[j];
- /* if a language is preferred, but the current variant
- * is not in that language, then drop it for now
- */
- if ( preferred_language
- && !variant_has_language(variant, preferred_language)) {
- continue;
- }
+ /* Find all the relevant 'quality' values from the
+ * Accept... headers, and store in the variant. This also
+ * prepares for sending an Alternates header etc so we need to
+ * do it even if we do not actually plan to find a best
+ * variant.
+ */
+ set_accept_quality(neg, variant);
+ set_language_quality(neg, variant);
+ set_encoding_quality(neg, variant);
+ set_charset_quality(neg, variant);
- /* Find all the relevant 'quality' values from the
- * Accept... headers, and store in the variant. This also
- * prepares for sending an Alternates header etc so we need to
- * do it even if we do not actually plan to find a best
- * variant.
- */
- set_accept_quality(neg, variant);
- /* accept the preferred language, even when it's not listed within
- * the Accept-Language header
- */
- if (preferred_language) {
- variant->lang_quality = 1.0f;
- variant->definite = 1;
- }
- else {
- set_language_quality(neg, variant);
- }
- set_encoding_quality(neg, variant);
- set_charset_quality(neg, variant);
+ /* Only do variant selection if we may actually choose a
+ * variant for the client
+ */
+ if (neg->may_choose) {
- /* Only do variant selection if we may actually choose a
- * variant for the client
+ /* Now find out if this variant is better than the current
+ * best, either using the RVSA/1.0 algorithm, or Apache's
+ * internal server-driven algorithm. Presumably other
+ * server-driven algorithms are possible, and could be
+ * implemented here.
*/
- if (neg->may_choose) {
- /* Now find out if this variant is better than the current
- * best, either using the RVSA/1.0 algorithm, or Apache's
- * internal server-driven algorithm. Presumably other
- * server-driven algorithms are possible, and could be
- * implemented here.
- */
-
- if (neg->use_rvsa) {
- if (is_variant_better_rvsa(neg, variant, best, &bestq)) {
- best = variant;
- }
+ if (neg->use_rvsa) {
+ if (is_variant_better_rvsa(neg, variant, best, &bestq)) {
+ best = variant;
}
- else {
- if (is_variant_better(neg, variant, best, &bestq)) {
- best = variant;
- }
+ }
+ else {
+ if (is_variant_better(neg, variant, best, &bestq)) {
+ best = variant;
}
}
}
+ }
- /* We now either have a best variant, or no best variant */
-
- if (neg->use_rvsa) {
- /* calculate result for RVSA/1.0 algorithm:
- * only a choice response if the best variant has q>0
- * and is definite
- */
- algorithm_result = (best && best->definite) && (bestq > 0) ?
- alg_choice : alg_list;
- }
- else {
- /* calculate result for Apache negotiation algorithm */
- algorithm_result = bestq > 0 ? alg_choice : alg_list;
- }
-
- /* run the loop again, if the "prefer-language" got no clear result */
- if (preferred_language && (!best || algorithm_result != alg_choice)) {
- preferred_language = NULL;
- continue;
- }
+ /* We now either have a best variant, or no best variant */
- break;
- } while (1);
+ if (neg->use_rvsa) {
+ /* calculate result for RVSA/1.0 algorithm:
+ * only a choice response if the best variant has q>0
+ * and is definite
+ */
+ algorithm_result = (best && best->definite) && (bestq > 0) ?
+ alg_choice : alg_list;
+ }
+ else {
+ /* calculate result for Apache negotiation algorithm */
+ algorithm_result = bestq > 0 ? alg_choice : alg_list;
+ }
/* Returning a choice response with a non-neighboring variant is a
* protocol security error in TCN (see rfc2295). We do *not*
diff --git a/modules/metadata/mod_expires.c b/modules/metadata/mod_expires.c
index 64fdb0cf14..e35e5544e4 100644
--- a/modules/metadata/mod_expires.c
+++ b/modules/metadata/mod_expires.c
@@ -212,11 +212,6 @@ typedef struct {
apr_table_t *expiresbytype;
} expires_dir_config;
-typedef struct {
- int defaulted;
- apr_table_t *expfields;
-} expires_interphase_t;
-
/* from mod_dir, why is this alias used?
*/
#define DIR_CMD_PERMS OR_INDEXES
@@ -421,23 +416,59 @@ static void *merge_expires_dir_configs(apr_pool_t *p, void *basev, void *addv)
return new;
}
-/*
- * Handle the setting of the expiration response header fields according
- * to our criteria.
- */
-
-static int set_expiration_fields(request_rec *r, const char *code,
- apr_table_t *t)
+static int add_expires(request_rec *r)
{
+ expires_dir_config *conf;
+ char *code;
apr_time_t base;
apr_time_t additional;
apr_time_t expires;
int additional_sec;
char *timestr;
- expires_interphase_t *notes;
- notes = (expires_interphase_t *) ap_get_module_config(r->request_config,
- &expires_module);
+ if (ap_is_HTTP_ERROR(r->status)) /* Don't add Expires headers to errors */
+ return DECLINED;
+
+ if (r->main != NULL) /* Say no to subrequests */
+ return DECLINED;
+
+ conf = (expires_dir_config *) ap_get_module_config(r->per_dir_config, &expires_module);
+ if (conf == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "internal error: %s", r->filename);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if (conf->active != ACTIVE_ON)
+ return DECLINED;
+
+ /* we perhaps could use the default_type(r) in its place but that
+ * may be 2nd guesing the desired configuration... calling table_get
+ * with a NULL key will SEGV us
+ *
+ * I still don't know *why* r->content_type would ever be NULL, this
+ * is possibly a result of fixups being called in many different
+ * places. Fixups is probably the wrong place to be doing all this
+ * work... Bah.
+ *
+ * Changed as of 08.Jun.96 don't DECLINE, look for an ExpiresDefault.
+ */
+ if (r->content_type == NULL)
+ code = NULL;
+ else
+ code = (char *) apr_table_get(conf->expiresbytype,
+ ap_field_noparam(r->pool, r->content_type));
+
+ if (code == NULL) {
+ /* no expires defined for that type, is there a default? */
+ code = conf->expiresdefault;
+
+ if (code[0] == '\0')
+ return OK;
+ }
+
+ /* we have our code */
+
switch (code[0]) {
case 'M':
if (r->finfo.filetype == 0) {
@@ -468,143 +499,17 @@ static int set_expiration_fields(request_rec *r, const char *code,
}
expires = base + additional;
- apr_table_mergen(t, "Cache-Control",
- apr_psprintf(r->pool, "max-age=%" APR_TIME_T_FMT,
- apr_time_sec(expires - r->request_time)));
+ apr_table_mergen(r->headers_out, "Cache-Control",
+ apr_psprintf(r->pool, "max-age=%" APR_TIME_T_FMT,
+ apr_time_sec(expires - r->request_time)));
timestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
apr_rfc822_date(timestr, expires);
- apr_table_setn(t, "Expires", timestr);
+ apr_table_setn(r->headers_out, "Expires", timestr);
return OK;
}
-/*
- * Output filter to set the Expires response header field
- * according to the content-type of the response -- if it hasn't
- * already been set.
- */
-static apr_status_t expires_by_type_filter(ap_filter_t *f,
- apr_bucket_brigade *b)
-{
- request_rec *r;
- expires_dir_config *conf;
- expires_interphase_t *notes;
- const char *bytype_expiry;
- apr_table_t *t;
-
- r = f->r;
- conf = (expires_dir_config *) ap_get_module_config(r->per_dir_config,
- &expires_module);
- notes = (expires_interphase_t *) ap_get_module_config(r->request_config,
- &expires_module);
-
- /*
- * If this filter is getting called, it *should* mean that
- * the fixup-phase handler ran and set things up for us.
- * Check to see which output header table we should use;
- * mod_cgi loads script fields into r->err_headers_out,
- * for instance.
- */
- bytype_expiry = apr_table_get(r->err_headers_out, "Expires");
- if (bytype_expiry != NULL) {
- t = r->err_headers_out;
- }
- else {
- bytype_expiry = apr_table_get(r->headers_out, "Expires");
- t = r->headers_out;
- }
- if (bytype_expiry == NULL) {
- /*
- * No expiration has been set, so we can apply any managed by
- * this module. Check for one for this content type.
- */
- bytype_expiry = apr_table_get(conf->expiresbytype,
- ap_field_noparam(r->pool,
- r->content_type));
- if (bytype_expiry != NULL) {
- set_expiration_fields(r, bytype_expiry, t);
- }
- else if ((notes != NULL) && notes->defaulted) {
- /*
- * None for this type, but there was a default defined --
- * so use it.
- */
- t = apr_table_overlay(r->pool, notes->expfields, t);
- }
- }
- ap_remove_output_filter(f);
- return ap_pass_brigade(f->next, b);
-}
-
-static int add_expires(request_rec *r)
-{
- expires_dir_config *conf;
- expires_interphase_t *notes;
- apr_table_t *rfields;
- char *code;
-
- if (ap_is_HTTP_ERROR(r->status)) {/* Don't add Expires headers to errors */
- return DECLINED;
- }
-
- if (r->main != NULL) { /* Say no to subrequests */
- return DECLINED;
- }
-
- conf = (expires_dir_config *) ap_get_module_config(r->per_dir_config,
- &expires_module);
- if (conf == NULL) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "internal error: %s", r->filename);
- return HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (conf->active != ACTIVE_ON) {
- return DECLINED;
- }
-
- notes = apr_palloc(r->pool, sizeof(expires_interphase_t));
- notes->defaulted = 0;
- notes->expfields = apr_table_make(r->pool, 4);
- ap_set_module_config(r->request_config, &expires_module, notes);
-
- /*
- * If there are any ExpiresByType directives for this scope,
- * add the output filter and defer all setting to it. We
- * do make a note of any ExpiresDefault value for its use.
- */
- if (! apr_is_empty_table(conf->expiresbytype)) {
- ap_add_output_filter("MOD_EXPIRES", NULL, r, r->connection);
- rfields = notes->expfields;
- }
- else {
- rfields = r->headers_out;
- }
- /*
- * Apply the default expiration if there is one; the filter will
- * narrow it down later if possible.
- */
- code = conf->expiresdefault;
-
- if (code[0] == '\0') {
- return OK;
- }
- else {
- /*
- * Note that we're setting it from the default, so that
- * the output filter (if it runs) knows it can override the
- * value. This allows the by-type filter to be able to
- * tell the difference between a value set by, say, a
- * CGI script and the one we set by default.
- */
- notes->defaulted = 1;
- }
- return set_expiration_fields(r, code, rfields);
-}
-
static void register_hooks(apr_pool_t *p)
{
- ap_register_output_filter("MOD_EXPIRES", expires_by_type_filter, NULL,
- AP_FTYPE_CONTENT_SET);
ap_hook_fixups(add_expires,NULL,NULL,APR_HOOK_MIDDLE);
}