summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2018-08-28 20:07:07 +0000
committerYann Ylavic <ylavic@apache.org>2018-08-28 20:07:07 +0000
commit831ef7623e9700e12432a9cf865935cd83c2b502 (patch)
treee1f62edcc41cc6196b54d2d6ea769d84543b49a7
parentafc3500b3213d6228712d7bdfbd5bc5b002fb2d4 (diff)
downloadhttpd-831ef7623e9700e12432a9cf865935cd83c2b502.tar.gz
Merge r1837130 from trunk:
mod_ratelimit: Don't interfere with "chunked" encoding. By the time ap_http_header_filter() sends the header brigade and adds the "CHUNK" filter, we need to garantee that the header went through all the filters' stack, and more specifically above ap_http_chunk_filter() which assumes that all it receives is content data. Since rate_limit_filter() may retain the header brigade, make it run after ap_http_chunk_filter(), just before AP_FTYPE_CONNECTION filters. Also, ap_http_header_filter() shouldn't eat the EOS for HEAD/no-body responses. For instance mod_ratelimit depends on it since r1835168, but any next request filter may as well to flush and/or bail out approprietely. This fixes the regression introduced in 2.4.34 (r1835168). PR 62568. Submitted by: ylavic Reviewed by: covener, ylavic, jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1839497 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES3
-rw-r--r--STATUS7
-rw-r--r--modules/filters/mod_ratelimit.c3
-rw-r--r--modules/http/chunk_filter.c3
-rw-r--r--modules/http/http_filters.c13
5 files changed, 18 insertions, 11 deletions
diff --git a/CHANGES b/CHANGES
index da9e5df25d..92c63d69f0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes with Apache 2.4.35
+ *) mod_ratelimit: Don't interfere with "chunked" encoding, fixing regression
+ introduced in 2.4.34. PR 62568. [Yann Ylavic]
+
*) Allow the argument to <IfFile>, <IfDefine>, <IfSection>, <IfDirective>,
and <IfModule> to be quoted. This is primarily for the benefit of
<IfFile>. [Eric Covener]
diff --git a/STATUS b/STATUS
index c378d22fa9..8db2fd08f9 100644
--- a/STATUS
+++ b/STATUS
@@ -138,13 +138,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
2.4.x patch: svn merge -c 1801144,1801148,1801456 ^/httpd/httpd/trunk .
+1: jailletc36, jim (via inspection), wrowe
- *) mod_ratelimit: Run after the chunking filter so headers are always sent
- uninterrupted., pass EOS to each downstream filter.
- Fixes regression in 2.4.34.
- trunk patch: http://svn.apache.org/r1837130
- 2.4.x patch: svn merge -c 1837130 ^/httpd/httpd/trunk .
- +1: covener, ylavic, jim
-
*) mod_proxy: fix load order dep between mod_proxy and lbmethod providers
trunk patch: http://svn.apache.org/r1836381
http://svn.apache.org/r1836382
diff --git a/modules/filters/mod_ratelimit.c b/modules/filters/mod_ratelimit.c
index cf79973120..d16eb39059 100644
--- a/modules/filters/mod_ratelimit.c
+++ b/modules/filters/mod_ratelimit.c
@@ -65,7 +65,6 @@ rate_limit_filter(ap_filter_t *f, apr_bucket_brigade *bb)
/* Set up our rl_ctx_t on first use */
if (ctx == NULL) {
-
const char *rl = NULL;
int ratelimit;
int burst = 0;
@@ -327,7 +326,7 @@ static void register_hooks(apr_pool_t *p)
{
/* run after mod_deflate etc etc, but not at connection level, ie, mod_ssl. */
ap_register_output_filter(RATE_LIMIT_FILTER_NAME, rate_limit_filter,
- NULL, AP_FTYPE_PROTOCOL + 3);
+ NULL, AP_FTYPE_CONNECTION - 1);
}
AP_DECLARE_MODULE(ratelimit) = {
diff --git a/modules/http/chunk_filter.c b/modules/http/chunk_filter.c
index 17fbabdb0a..cb1501aebf 100644
--- a/modules/http/chunk_filter.c
+++ b/modules/http/chunk_filter.c
@@ -69,6 +69,7 @@ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b)
{
if (APR_BUCKET_IS_EOS(e)) {
/* there shouldn't be anything after the eos */
+ ap_remove_output_filter(f);
eos = e;
break;
}
@@ -186,11 +187,11 @@ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b)
/* pass the brigade to the next filter. */
rv = ap_pass_brigade(f->next, b);
+ apr_brigade_cleanup(b);
if (rv != APR_SUCCESS || eos != NULL) {
return rv;
}
tmp = b;
- apr_brigade_cleanup(tmp);
}
return APR_SUCCESS;
}
diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c
index 5fa40635d8..37c0113e5b 100644
--- a/modules/http/http_filters.c
+++ b/modules/http/http_filters.c
@@ -1308,8 +1308,19 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
else if (ctx->headers_sent) {
/* Eat body if response must not have one. */
if (r->header_only || r->status == HTTP_NO_CONTENT) {
+ /* Still next filters may be waiting for EOS, so pass it (alone)
+ * when encountered and be done with this filter.
+ */
+ e = APR_BRIGADE_LAST(b);
+ if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
+ APR_BUCKET_REMOVE(e);
+ apr_brigade_cleanup(b);
+ APR_BRIGADE_INSERT_HEAD(b, e);
+ ap_remove_output_filter(f);
+ rv = ap_pass_brigade(f->next, b);
+ }
apr_brigade_cleanup(b);
- return APR_SUCCESS;
+ return rv;
}
}