summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Orton <jorton@redhat.com>2017-09-13 14:21:17 +0100
committerJoe Orton <jorton@redhat.com>2017-09-13 14:21:17 +0100
commitb022e3b52344b687c25875b0a7d6c1ee26f8e5fa (patch)
tree5be801d56e4aa13b82962d2e0a5c0ec136c49d57
parentddabcffa42aeee042fbe2af37931158ec539cb80 (diff)
downloadhttpd-b022e3b52344b687c25875b0a7d6c1ee26f8e5fa.tar.gz
httpd-b022e3b52344b687c25875b0a7d6c1ee26f8e5fa.tar.xz
httpd-b022e3b52344b687c25875b0a7d6c1ee26f8e5fa.zip
add new content-length filter (upstream PR 61222)
-rw-r--r--.gitignore2
-rw-r--r--httpd-2.4.27-r1808230.patch131
-rw-r--r--httpd.spec7
-rwxr-xr-xpullrev.sh4
4 files changed, 140 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index 19a3666..e364382 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,7 +10,7 @@ x86_64
/httpd-2.2.21.tar.bz2
/clog
/httpd-2.2.22.tar.bz2
-/httpd-2.4.?
+/httpd-2.4.??/
/httpd-2.4.2.tar.bz2
/httpd-2.4.3.tar.bz2
/httpd-2.4.4.tar.bz2
diff --git a/httpd-2.4.27-r1808230.patch b/httpd-2.4.27-r1808230.patch
new file mode 100644
index 0000000..e4062ea
--- /dev/null
+++ b/httpd-2.4.27-r1808230.patch
@@ -0,0 +1,131 @@
+# ./pullrev.sh 1808230
+http://svn.apache.org/viewvc?view=revision&revision=1808230
+
+--- httpd-2.4.27/server/protocol.c
++++ httpd-2.4.27/server/protocol.c
+@@ -1708,62 +1708,88 @@
+ ctx->tmpbb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+ }
+
+- /* Loop through this set of buckets to compute their length
+- */
++ /* Loop through the brigade to count the length. To avoid
++ * arbitrary memory consumption with morphing bucket types, this
++ * loop will stop and pass on the brigade when necessary. */
+ e = APR_BRIGADE_FIRST(b);
+ while (e != APR_BRIGADE_SENTINEL(b)) {
++ apr_status_t rv;
++
+ if (APR_BUCKET_IS_EOS(e)) {
+ eos = 1;
+ break;
+ }
+- if (e->length == (apr_size_t)-1) {
++ /* For a flush bucket, fall through to pass the brigade and
++ * flush now. */
++ else if (APR_BUCKET_IS_FLUSH(e)) {
++ e = APR_BUCKET_NEXT(e);
++ }
++ /* For metadata bucket types other than FLUSH, loop. */
++ else if (APR_BUCKET_IS_METADATA(e)) {
++ e = APR_BUCKET_NEXT(e);
++ continue;
++ }
++ /* For determinate length data buckets, count the length and
++ * continue. */
++ else if (e->length != (apr_size_t)-1) {
++ r->bytes_sent += e->length;
++ e = APR_BUCKET_NEXT(e);
++ continue;
++ }
++ /* For indeterminate length data buckets, perform one read. */
++ else /* e->length == (apr_size_t)-1 */ {
+ apr_size_t len;
+ const char *ignored;
+- apr_status_t rv;
+-
+- /* This is probably a pipe bucket. Send everything
+- * prior to this, and then read the data for this bucket.
+- */
++
+ rv = apr_bucket_read(e, &ignored, &len, eblock);
++ if ((rv != APR_SUCCESS) && !APR_STATUS_IS_EAGAIN(rv)) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00574)
++ "ap_content_length_filter: "
++ "apr_bucket_read() failed");
++ return rv;
++ }
+ if (rv == APR_SUCCESS) {
+- /* Attempt a nonblocking read next time through */
+ eblock = APR_NONBLOCK_READ;
++ e = APR_BUCKET_NEXT(e);
+ r->bytes_sent += len;
+ }
+ else if (APR_STATUS_IS_EAGAIN(rv)) {
+- /* Output everything prior to this bucket, and then
+- * do a blocking read on the next batch.
+- */
+- if (e != APR_BRIGADE_FIRST(b)) {
+- apr_bucket *flush;
+- apr_brigade_split_ex(b, e, ctx->tmpbb);
+- flush = apr_bucket_flush_create(r->connection->bucket_alloc);
++ apr_bucket *flush;
+
+- APR_BRIGADE_INSERT_TAIL(b, flush);
+- rv = ap_pass_brigade(f->next, b);
+- if (rv != APR_SUCCESS || f->c->aborted) {
+- return rv;
+- }
+- apr_brigade_cleanup(b);
+- APR_BRIGADE_CONCAT(b, ctx->tmpbb);
+- e = APR_BRIGADE_FIRST(b);
++ /* Next read must block. */
++ eblock = APR_BLOCK_READ;
+
+- ctx->data_sent = 1;
+- }
+- eblock = APR_BLOCK_READ;
+- continue;
++ /* Ensure the last bucket to pass down is a flush if
++ * the next read will block. */
++ flush = apr_bucket_flush_create(f->c->bucket_alloc);
++ APR_BUCKET_INSERT_BEFORE(e, flush);
+ }
+- else {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00574)
+- "ap_content_length_filter: "
+- "apr_bucket_read() failed");
+- return rv;
+- }
+ }
+- else {
+- r->bytes_sent += e->length;
++
++ /* Optimization: if the next bucket is EOS (directly after a
++ * bucket morphed to the heap, or a flush), short-cut to
++ * handle EOS straight away - allowing C-L to be determined
++ * for content which is already entirely in memory. */
++ if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
++ continue;
+ }
+- e = APR_BUCKET_NEXT(e);
++
++ /* On reaching here, pass on everything in the brigade up to
++ * this point. */
++ apr_brigade_split_ex(b, e, ctx->tmpbb);
++
++ rv = ap_pass_brigade(f->next, b);
++ if (rv != APR_SUCCESS) {
++ return rv;
++ }
++ else if (f->c->aborted) {
++ return APR_ECONNABORTED;
++ }
++ apr_brigade_cleanup(b);
++ APR_BRIGADE_CONCAT(b, ctx->tmpbb);
++ e = APR_BRIGADE_FIRST(b);
++
++ ctx->data_sent = 1;
+ }
+
+ /* If we've now seen the entire response and it's otherwise
diff --git a/httpd.spec b/httpd.spec
index 0e25a2c..01beaf2 100644
--- a/httpd.spec
+++ b/httpd.spec
@@ -13,7 +13,7 @@
Summary: Apache HTTP Server
Name: httpd
Version: 2.4.27
-Release: 6%{?dist}
+Release: 7%{?dist}
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source1: index.html
@@ -72,6 +72,7 @@ Patch56: httpd-2.4.4-mod_unique_id.patch
Patch57: httpd-2.4.10-sigint.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1397243
Patch58: httpd-2.4.25-r1738878.patch
+Patch59: httpd-2.4.27-r1808230.patch
# Security fixes
License: ASL 2.0
@@ -218,6 +219,7 @@ interface for storing and accessing per-user session data.
%patch56 -p1 -b .uniqueid
%patch57 -p1 -b .sigint
%patch58 -p1 -b .r1738878
+%patch59 -p1 -b .r1808230
# Patch in the vendor string
sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h
@@ -703,6 +705,9 @@ rm -rf $RPM_BUILD_ROOT
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
+* Wed Sep 13 2017 Joe Orton <jorton@redhat.com> - 2.4.27-7
+- add new content-length filter (upstream PR 61222)
+
* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.4.27-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
diff --git a/pullrev.sh b/pullrev.sh
index d106968..c366613 100755
--- a/pullrev.sh
+++ b/pullrev.sh
@@ -6,8 +6,8 @@ if [ $# -lt 1 ]; then
fi
repo="https://svn.apache.org/repos/asf/httpd/httpd/trunk"
-repo="https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x"
-ver=2.4.26
+#repo="https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x"
+ver=2.4.27
prefix="httpd-${ver}"
suffix="r$1${2:++}"
fn="${prefix}-${suffix}.patch"