Merge ~bryce/ubuntu/+source/apache2:sru-lp1832182-graceful-revert-bionic into ubuntu/+source/apache2:ubuntu/devel

Proposed by Bryce Harrington
Status: Merged
Merge reported by: Bryce Harrington
Merged at revision: 95c238eedea3c6b7d877857d522e03f2d4e8e951
Proposed branch: ~bryce/ubuntu/+source/apache2:sru-lp1832182-graceful-revert-bionic
Merge into: ubuntu/+source/apache2:ubuntu/devel
Diff against target: 22219 lines (+21167/-0) (has conflicts)
81 files modified
debian/NEWS (+12/-0)
debian/apache2-systemd.conf (+3/-0)
debian/apache2.dirs (+4/-0)
debian/apache2.install (+4/-0)
debian/changelog (+249/-0)
debian/control (+16/-0)
debian/patches/086_svn_cross_compiles (+118/-0)
debian/patches/CVE-2017-15710.patch (+24/-0)
debian/patches/CVE-2017-15715.patch (+192/-0)
debian/patches/CVE-2018-1283.patch (+28/-0)
debian/patches/CVE-2018-1301.patch (+200/-0)
debian/patches/CVE-2018-1303.patch (+17/-0)
debian/patches/CVE-2018-1312.patch (+403/-0)
debian/patches/CVE-2018-17199.patch (+85/-0)
debian/patches/CVE-2019-0211.patch (+249/-0)
debian/patches/CVE-2019-0217.patch (+147/-0)
debian/patches/CVE-2019-0220-1.patch (+259/-0)
debian/patches/CVE-2019-0220-2.patch (+50/-0)
debian/patches/CVE-2019-0220-3.patch (+43/-0)
debian/patches/CVE-2019-10092-1.patch (+245/-0)
debian/patches/CVE-2019-10092-2.patch (+45/-0)
debian/patches/CVE-2019-10098.patch (+159/-0)
debian/patches/CVE-2020-11993-pre1.patch (+406/-0)
debian/patches/CVE-2020-11993.patch (+1905/-0)
debian/patches/CVE-2020-1927-1.patch (+93/-0)
debian/patches/CVE-2020-1927-2.patch (+99/-0)
debian/patches/CVE-2020-1934.patch (+103/-0)
debian/patches/CVE-2020-35452.patch (+51/-0)
debian/patches/CVE-2020-9490.patch (+436/-0)
debian/patches/CVE-2021-26690.patch (+25/-0)
debian/patches/CVE-2021-26691.patch (+39/-0)
debian/patches/CVE-2021-30641.patch (+60/-0)
debian/patches/CVE-2021-33193-pre1.patch (+175/-0)
debian/patches/CVE-2021-33193-pre2.patch (+521/-0)
debian/patches/CVE-2021-33193.patch (+197/-0)
debian/patches/CVE-2021-34798.patch (+6/-0)
debian/patches/CVE-2021-39275.patch (+4/-0)
debian/patches/CVE-2021-40438-2.patch (+4/-0)
debian/patches/CVE-2021-40438-3.patch (+8/-0)
debian/patches/CVE-2021-40438-pre1.patch (+16/-0)
debian/patches/CVE-2021-40438.patch (+12/-0)
debian/patches/balance-member-long-hostname-part1.patch (+30/-0)
debian/patches/balance-member-long-hostname-part2.patch (+430/-0)
debian/patches/clear-retry-flags-before-abort.patch (+67/-0)
debian/patches/disable-ssl-1.1.1-auto-retry.patch (+41/-0)
debian/patches/includeoptional-ignore-non-existent.patch (+61/-0)
debian/patches/mod_http2-1.14.1-backport-0001-On-the-2.4.x-branch.patch (+192/-0)
debian/patches/mod_http2-1.14.1-backport-0002-On-the-2.4.x-branch.patch (+73/-0)
debian/patches/mod_http2-1.14.1-backport-0003-On-the-2.4.x-branch.patch (+29/-0)
debian/patches/mod_http2-1.14.1-backport-0004-docco-fix.-correct-license-copyright-info.patch (+640/-0)
debian/patches/mod_http2-1.14.1-backport-0005-Merge-r1818804-r1818951-r1818958-r1818960-r1819027-r.patch (+263/-0)
debian/patches/mod_http2-1.14.1-backport-0006-On-the-2.4.x-branch-CVE-2018-1302.patch (+1530/-0)
debian/patches/mod_http2-1.14.1-backport-0008-Merge-r1822849-r1822858-r1822878-r1822879-r1822883-r.patch (+298/-0)
debian/patches/mod_http2-1.14.1-backport-0009-Merge-r1828879-from-trunk-CVE-2018-1333.patch (+65/-0)
debian/patches/mod_http2-1.14.1-backport-0010-Merge-r1826687-r1827166-r1828210-r1828232-r1828687-f.patch (+563/-0)
debian/patches/mod_http2-1.14.1-backport-0011-Merge-r1830562-from-trunk.patch (+108/-0)
debian/patches/mod_http2-1.14.1-backport-0012-fix-a-potential-NULL-dereference-spotted-by-gcc-8.1..patch (+114/-0)
debian/patches/mod_http2-1.14.1-backport-0013-Merge-r1837056-from-trunk.patch (+265/-0)
debian/patches/mod_http2-1.14.1-backport-0014-Merge-r1840010-from-trunk-CVE-2018-11763.patch (+527/-0)
debian/patches/mod_http2-1.14.1-backport-0015-Merge-r1835118-from-trunk.patch (+325/-0)
debian/patches/mod_http2-1.14.1-backport-0016-Merge-r1843426-from-trunk.patch (+110/-0)
debian/patches/mod_http2-1.14.1-backport-0017-Merge-of-r1846125-from-trunk-CVE-2018-17189.patch (+77/-0)
debian/patches/mod_http2-1.14.1-backport-0018-Merge-of-r1852986-from-trunk-CVE-2019-0196.patch (+30/-0)
debian/patches/mod_http2-1.14.1-backport-0019-Merge-r1852038-r1852101-from-trunk-CVE-2019-0197.patch (+159/-0)
debian/patches/mod_http2-1.14.1-backport-0020-Merge-r1853901-r1853906-r1853908-r1853929-r1853935-r.patch (+671/-0)
debian/patches/mod_http2-1.14.1-backport-0021-Merge-of-1849296-1852038-1852101-1852339-1853171-185.patch (+4605/-0)
debian/patches/mod_http2-1.14.1-backport-0022-adjust-per-r1855434.patch (+98/-0)
debian/patches/mod_http2-1.15.4-backport-0001.patch (+128/-0)
debian/patches/mod_http2-1.15.4-backport-0002.patch (+223/-0)
debian/patches/mod_http2-1.15.4-backport-0003.patch (+74/-0)
debian/patches/mod_http2-1.15.4-backport-0004-CVE-2019-9517.patch (+922/-0)
debian/patches/mod_http2-1.15.4-backport-0005.patch (+37/-0)
debian/patches/series (+105/-0)
debian/patches/ssl-read-rc-value-openssl-1.1.1.patch (+110/-0)
debian/patches/tlsv1.3-support-2.patch (+152/-0)
debian/patches/tlsv1.3-support-3.patch (+37/-0)
debian/patches/tlsv1.3-support-4.patch (+37/-0)
debian/patches/tlsv1.3-support-5.patch (+298/-0)
debian/patches/tlsv1.3-support.patch (+909/-0)
debian/patches/util_ldap_cache_lock_fix.patch (+48/-0)
debian/source/include-binaries (+4/-0)
Conflict in debian/apache2.dirs
Conflict in debian/apache2.install
Conflict in debian/changelog
Conflict in debian/control
Conflict in debian/patches/CVE-2021-33193.patch
Conflict in debian/patches/CVE-2021-34798.patch
Conflict in debian/patches/CVE-2021-39275.patch
Conflict in debian/patches/CVE-2021-40438-2.patch
Conflict in debian/patches/CVE-2021-40438-3.patch
Conflict in debian/patches/CVE-2021-40438-pre1.patch
Conflict in debian/patches/CVE-2021-40438.patch
Conflict in debian/patches/series
Conflict in debian/source/include-binaries
Reviewer Review Type Date Requested Status
Christian Ehrhardt  (community) Approve
Canonical Server Pending
Review via email: mp+412056@code.launchpad.net

Description of the change

This reverts an SRU fix that was reported to have a performance impact reported by focal users when supporting large numbers of vhosts. We reverted this in focal a few weeks ago and there's been no feedback regarding problems, so it's probably worth doing the same revert to the other releases.

After that, the plan will be to focus on a fix just for jammy, and then also get it accepted into Debian. After that we can evaluate whether or not to try SRUing again.

PPA: https://launchpad.net/~bryce/+archive/ubuntu/apache2-sru-lp1832182-graceful-revert

To post a comment you must log in.
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Again wrong target branch, but ok from git.

This revert is different than the one for H/I releases.
But that is intentional and ok as the change to Bionic was different when it was applied.

We are - as intended - back on the level of 2.4.29-1ubuntu4.18

$ git diff 0697199b656c588c0a7fdc80055795b9a837300c -- debian/ | diffstat
 changelog | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

LGTM
thanks!

review: Approve
Revision history for this message
Bryce Harrington (bryce) wrote :

Thanks Christian, I've uploaded the reverts. Sorry for the mistargeted branches.

I'll be keeping an eye on the uploads since with apache2 in focal we saw a ton of flaky test failures.

$ dput ubuntu ../apache2_2.4.29-1ubuntu4.20_source.changes
Checking signature on .changes
gpg: ../apache2_2.4.29-1ubuntu4.20_source.changes: Valid signature from E603B2578FB8F0FB
Checking signature on .dsc
gpg: ../apache2_2.4.29-1ubuntu4.20.dsc: Valid signature from E603B2578FB8F0FB
Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading apache2_2.4.29-1ubuntu4.20.dsc: done.
  Uploading apache2_2.4.29-1ubuntu4.20.debian.tar.xz: done.
  Uploading apache2_2.4.29-1ubuntu4.20_source.buildinfo: done.
  Uploading apache2_2.4.29-1ubuntu4.20_source.changes: done.
Successfully uploaded packages.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/NEWS b/debian/NEWS
2new file mode 100644
3index 0000000..db737ef
4--- /dev/null
5+++ b/debian/NEWS
6@@ -0,0 +1,12 @@
7+apache2 (2.4.29-1ubuntu4.10) bionic-security; urgency=medium
8+
9+ - To address HTTP/2 issues CVE-2019-9517, CVE-2019-0197,
10+ CVE-2019-10081, and CVE-2019-10082, mod_http2 from 2.4.41 (aka
11+ v1.15.4) was backported into this release of apache2, which
12+ includes additional bug fixes as well.
13+
14+ - For CVE-2019-10098, PCRE_DOTALL flag is by default by default to
15+ avoid unpredictable matches and substitutions with encoded line
16+ break characters mod_rewrite and the apache core.
17+
18+ -- Steve Beattie <sbeattie@ubuntu.com> Mon, 26 Aug 2019 06:41:43 -0700
19diff --git a/debian/apache2-systemd.conf b/debian/apache2-systemd.conf
20new file mode 100644
21index 0000000..b031203
22--- /dev/null
23+++ b/debian/apache2-systemd.conf
24@@ -0,0 +1,3 @@
25+[Service]
26+Type=forking
27+RemainAfterExit=no
28diff --git a/debian/apache2.dirs b/debian/apache2.dirs
29index 1aa6d3c..fed7c9e 100644
30--- a/debian/apache2.dirs
31+++ b/debian/apache2.dirs
32@@ -10,4 +10,8 @@ var/cache/apache2/mod_cache_disk
33 var/lib/apache2
34 var/log/apache2
35 var/www/html
36+<<<<<<< debian/apache2.dirs
37+=======
38+usr/share/bug/apache2
39+>>>>>>> debian/apache2.dirs
40 /etc/ufw/applications.d/apache2
41diff --git a/debian/apache2.install b/debian/apache2.install
42index 92865fc..3d076c5 100644
43--- a/debian/apache2.install
44+++ b/debian/apache2.install
45@@ -9,3 +9,7 @@ debian/config-dir/envvars /etc/apache2
46 debian/config-dir/magic /etc/apache2
47 debian/debhelper/apache2-maintscript-helper /usr/share/apache2/
48 debian/apache2-utils.ufw.profile /etc/ufw/applications.d/
49+<<<<<<< debian/apache2.install
50+=======
51+debian/apache2-systemd.conf /lib/systemd/system/apache2.service.d/
52+>>>>>>> debian/apache2.install
53diff --git a/debian/changelog b/debian/changelog
54index 0dbb7c5..27857c7 100644
55--- a/debian/changelog
56+++ b/debian/changelog
57@@ -1,4 +1,25 @@
58+<<<<<<< debian/changelog
59 apache2 (2.4.48-3.1ubuntu3) impish; urgency=medium
60+=======
61+apache2 (2.4.29-1ubuntu4.20) bionic; urgency=medium
62+
63+ * Revert fix from 2.4.29-1ubuntu4.19, due to performance regression.
64+ (LP 1832182)
65+
66+ -- Bryce Harrington <bryce@canonical.com> Sun, 14 Nov 2021 23:52:18 +0000
67+
68+apache2 (2.4.29-1ubuntu4.19) bionic; urgency=medium
69+
70+ * d/apache2ctl: Also use systemd for graceful if it is in use.
71+ (LP: #1832182)
72+ - This extends an earlier fix for the start command to behave
73+ similarly for restart / graceful. Fixes service failures on
74+ unattended upgrade.
75+
76+ -- Bryce Harrington <bryce@canonical.com> Tue, 28 Sep 2021 22:27:27 +0000
77+
78+apache2 (2.4.29-1ubuntu4.18) bionic-security; urgency=medium
79+>>>>>>> debian/changelog
80
81 * SECURITY REGRESSION: Issues in UDS URIs (LP: #1945311)
82 - debian/patches/CVE-2021-40438-2.patch: Fix UDS unix: scheme for P
83@@ -7,11 +28,31 @@ apache2 (2.4.48-3.1ubuntu3) impish; urgency=medium
84 hostname in modules/mappers/mod_rewrite.c,
85 modules/proxy/proxy_util.c.
86
87+<<<<<<< debian/changelog
88 -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Tue, 28 Sep 2021 08:52:26 -0400
89
90 apache2 (2.4.48-3.1ubuntu2) impish; urgency=medium
91
92 * SECURITY UPDATE: request splitting over HTTP/2
93+=======
94+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Tue, 28 Sep 2021 07:01:16 -0400
95+
96+apache2 (2.4.29-1ubuntu4.17) bionic-security; urgency=medium
97+
98+ * SECURITY UPDATE: request splitting over HTTP/2
99+ - debian/patches/CVE-2021-33193-pre1.patch: process early errors via a
100+ dummy HTTP/1.1 request as well in modules/http2/h2.h,
101+ modules/http2/h2_request.c, modules/http2/h2_session.c,
102+ modules/http2/h2_stream.c.
103+ - debian/patches/CVE-2021-33193-pre2.patch: sync with github standalone
104+ version 1.15.17 in modules/http2/h2_bucket_beam.c,
105+ modules/http2/h2_config.c, modules/http2/h2_config.h,
106+ modules/http2/h2_h2.c, modules/http2/h2_headers.c,
107+ modules/http2/h2_headers.h, modules/http2/h2_mplx.c,
108+ modules/http2/h2_request.c, modules/http2/h2_stream.h,
109+ modules/http2/h2_task.c, modules/http2/h2_task.h,
110+ modules/http2/h2_version.h.
111+>>>>>>> debian/changelog
112 - debian/patches/CVE-2021-33193.patch: refactor request parsing in
113 include/ap_mmn.h, include/http_core.h, include/http_protocol.h,
114 include/http_vhost.h, modules/http2/h2_request.c, server/core.c,
115@@ -21,10 +62,13 @@ apache2 (2.4.48-3.1ubuntu2) impish; urgency=medium
116 - debian/patches/CVE-2021-34798.patch: add NULL check in
117 server/scoreboard.c.
118 - CVE-2021-34798
119+<<<<<<< debian/changelog
120 * SECURITY UPDATE: DoS in mod_proxy_uwsgi
121 - debian/patches/CVE-2021-36160.patch: fix PATH_INFO setting for
122 generic worker in modules/proxy/mod_proxy_uwsgi.c.
123 - CVE-2021-36160
124+=======
125+>>>>>>> debian/changelog
126 * SECURITY UPDATE: buffer overflow in ap_escape_quotes
127 - debian/patches/CVE-2021-39275.patch: fix ap_escape_quotes
128 substitution logic in server/util.c.
129@@ -37,6 +81,7 @@ apache2 (2.4.48-3.1ubuntu2) impish; urgency=medium
130 configured UDS path in modules/proxy/proxy_util.c.
131 - CVE-2021-40438
132
133+<<<<<<< debian/changelog
134 -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Thu, 23 Sep 2021 12:51:16 -0400
135
136 apache2 (2.4.48-3.1ubuntu1) impish; urgency=medium
137@@ -174,6 +219,12 @@ apache2 (2.4.46-4ubuntu2) impish; urgency=medium
138 - debian/patches/CVE-2020-13950.patch: don't dereference NULL proxy
139 connection in modules/proxy/mod_proxy_http.c.
140 - CVE-2020-13950
141+=======
142+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Thu, 23 Sep 2021 13:01:10 -0400
143+
144+apache2 (2.4.29-1ubuntu4.16) bionic-security; urgency=medium
145+
146+>>>>>>> debian/changelog
147 * SECURITY UPDATE: stack overflow via Digest nonce in mod_auth_digest
148 - debian/patches/CVE-2020-35452.patch: fast validation of the nonce's
149 base64 to fail early if the format can't match anyway in
150@@ -191,6 +242,7 @@ apache2 (2.4.46-4ubuntu2) impish; urgency=medium
151 - debian/patches/CVE-2021-30641.patch: change default behavior in
152 server/request.c.
153 - CVE-2021-30641
154+<<<<<<< debian/changelog
155
156 -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Thu, 17 Jun 2021 13:09:41 -0400
157
158@@ -573,6 +625,143 @@ apache2 (2.4.38-3ubuntu1) eoan; urgency=low
159 apache2 (2.4.38-3) unstable; urgency=high
160
161 [ Marc Deslauriers ]
162+=======
163+ * This update does _not_ include the changes from 2.4.29-1ubuntu4.15 in
164+ bionic-proposed.
165+
166+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Fri, 18 Jun 2021 07:06:22 -0400
167+
168+apache2 (2.4.29-1ubuntu4.14) bionic-security; urgency=medium
169+
170+ * SECURITY UPDATE: mod_rewrite redirect issue
171+ - debian/patches/CVE-2020-1927-1.patch: factor out default regex flags
172+ in include/ap_regex.h, server/core.c, server/util_pcre.c.
173+ - debian/patches/CVE-2020-1927-2.patch: add AP_REG_NO_DEFAULT to allow
174+ opt-out of pcre defaults in include/ap_regex.h,
175+ modules/filters/mod_substitute.c, server/util_pcre.c,
176+ server/util_regex.c.
177+ - CVE-2020-1927
178+ * SECURITY UPDATE: mod_proxy_ftp uninitialized memory issue
179+ - debian/patches/CVE-2020-1934.patch: trap bad FTP responses in
180+ modules/proxy/mod_proxy_ftp.c.
181+ - CVE-2020-1934
182+ * SECURITY UPDATE: DoS via invalid Cache-Digest header
183+ - debian/patches/CVE-2020-9490.patch: remove support for abandoned
184+ http-wg draft in modules/http2/h2_push.c, modules/http2/h2_push.h.
185+ - CVE-2020-9490
186+ * SECURITY UPDATE: concurrent use of memory pools in HTTP/2 module
187+ - debian/patches/CVE-2020-11993-pre1.patch: fixed rare cases where a h2
188+ worker could deadlock the main connection in modules/http2/*.
189+ - debian/patches/CVE-2020-11993.patch: fix logging and rename
190+ terminology in modules/http2/*.
191+ - CVE-2020-11993
192+
193+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Wed, 12 Aug 2020 17:33:25 -0400
194+
195+apache2 (2.4.29-1ubuntu4.13) bionic-security; urgency=medium
196+
197+ * Add additional missing commits to TLSv1.3 support. (LP: #1867223)
198+ - debian/patches/tlsv1.3-support-2.patch: fix whitespace and copy/paste
199+ typos in modules/ssl/ssl_engine_kernel.c.
200+ - debian/patches/tlsv1.3-support-3.patch: fail with 403 if
201+ SSL_verify_client_post_handshake fails in
202+ modules/ssl/ssl_engine_kernel.c.
203+ - debian/patches/tlsv1.3-support-4.patch: disable AUTO_RETRY mode for
204+ OpenSSL 1.1.1, which fixes post-handshake authentication in
205+ modules/ssl/ssl_engine_init.c.
206+ - debian/patches/tlsv1.3-support-5.patch: retrieve and set
207+ sslconn->client_cert here for both "modern" and classic access
208+ control in modules/ssl/ssl_engine_kernel.c.
209+
210+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Fri, 13 Mar 2020 08:26:16 -0400
211+
212+apache2 (2.4.29-1ubuntu4.12) bionic; urgency=medium
213+
214+ * Add TLSv1.3 support. (LP: #1845263)
215+ - debian/patches/tlsv1.3-support.patch: backport upstream 2.4 commit
216+ which introduced TLSv1.3 support.
217+
218+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Tue, 03 Dec 2019 10:55:03 -0500
219+
220+apache2 (2.4.29-1ubuntu4.11) bionic-security; urgency=medium
221+
222+ * SECURITY REGRESSION: mod_proxy balancer XSS/CSRF hardening broke
223+ browsers which change case in headers and breaks balancers
224+ loading in some configurations (LP: #1842701)
225+ - drop d/p/CVE-2019-10092-3.patch
226+
227+ -- Steve Beattie <sbeattie@ubuntu.com> Mon, 16 Sep 2019 05:58:48 -0700
228+
229+apache2 (2.4.29-1ubuntu4.10) bionic-security; urgency=medium
230+
231+ * SECURITY UPDATE: HTTP/2 internal data buffering denial of service.
232+ - d/p/mod_http2-1.15.4-backport-0004-CVE-2019-9517.patch: improve
233+ http/2 module keepalive throttling.
234+ - CVE-2019-9517
235+ * SECURITY UPDATE: Upgrade request from http/1.1 to http/2 crash
236+ denial of service (LP: #1840188)
237+ - d/p/mod_http2-1.14.1-backport-0019-Merge-r1852038-r1852101-from-trunk-CVE-2019-0197.patch:
238+ re-use slave connections and fix slave connection keepalives
239+ counter.
240+ - CVE-2019-0197
241+ * SECURITY UPDATE: mod_http2 memory corruption on early pushes
242+ - included in mod_http2 1.15.4 backport
243+ - CVE-2019-10081
244+ * SECURITY UPDATE: read-after-free in mod_http2 h2 connection
245+ shutdown.
246+ - included in mod_http2 1.15.4 backport
247+ - CVE-2019-10082
248+ * SECURITY UPDATE: Limited cross-site scripting in mod_proxy
249+ error page.
250+ - d/p/CVE-2019-10092-1.patch: Remove request details from built-in
251+ error documents.
252+ - d/p/CVE-2019-10092-2.patch: Add missing log numbers.
253+ - d/p/CVE-2019-10092-3.patch: mod_proxy: Improve XSRF/XSS
254+ protection.
255+ - CVE-2019-10092-1
256+ * SECURITY UPDATE: mod_rewrite potential open redirect.
257+ - d/p/CVE-2019-10098.patch: Set PCRE_DOTALL by default.
258+ - CVE-2019-10098
259+ * Backport mod_http2 v1.14.1 and v1.15.4 for CVE-2019-9517,
260+ CVE-2019-10081, and CVE-2019-10082 fixes:
261+ - add d/p/mod_http2-1.14.1-backport-*.patches and
262+ d/p/mod_http2-1.15.4-backport-*.patches
263+ - dropped the following patches included above:
264+ + d/p/CVE-2018-1302.patch
265+ + d/p/CVE-2018-1333.patch
266+ + d/p/CVE-2018-11763.patch
267+ + d/p/CVE-2018-17189.patch
268+ + d/p/CVE-2019-0196.patch
269+
270+ -- Steve Beattie <sbeattie@ubuntu.com> Mon, 26 Aug 2019 06:41:23 -0700
271+
272+apache2 (2.4.29-1ubuntu4.8) bionic; urgency=medium
273+
274+ * d/p/ssl-read-rc-value-openssl-1.1.1.patch: Handle SSL_read() return code 0
275+ similarly to <0 with openssl 1.1.1
276+ * d/p/clear-retry-flags-before-abort.patch: clear retry flags before
277+ aborting on client-initiated reneg (LP: #1836329)
278+
279+ -- Andreas Hasenack <andreas@canonical.com> Tue, 16 Jul 2019 15:14:45 -0300
280+
281+apache2 (2.4.29-1ubuntu4.7) bionic; urgency=medium
282+
283+ * d/p/disable-ssl-1.1.1-auto-retry.patch: fix client certificate
284+ authentication when built with openssl 1.1.1 (LP: #1833039)
285+
286+ -- Andreas Hasenack <andreas@canonical.com> Fri, 28 Jun 2019 13:49:35 -0300
287+
288+apache2 (2.4.29-1ubuntu4.6) bionic-security; urgency=medium
289+
290+ * SECURITY UPDATE: slowloris DoS in mod_http2
291+ - debian/patches/CVE-2018-17189.patch: change cleanup strategy for
292+ slave connections in modules/http2/h2_conn.c.
293+ - CVE-2018-17189
294+ * SECURITY UPDATE: mod_session expiry time issue
295+ - debian/patches/CVE-2018-17199.patch: always decode session attributes
296+ early in modules/session/mod_session.c.
297+ - CVE-2018-17199
298+>>>>>>> debian/changelog
299 * SECURITY UPDATE: read-after-free on a string compare in mod_http2
300 - debian/patches/CVE-2019-0196.patch: disentangelment of stream and
301 request method in modules/http2/h2_request.c.
302@@ -583,10 +772,13 @@ apache2 (2.4.38-3) unstable; urgency=high
303 server/mpm/event/event.c, server/mpm/prefork/prefork.c,
304 server/mpm/worker/worker.c.
305 - CVE-2019-0211
306+<<<<<<< debian/changelog
307 * SECURITY UPDATE: mod_ssl access control bypass
308 - debian/patches/CVE-2019-0215.patch: restore SSL verify state after
309 PHA failure in TLSv1.3 in modules/ssl/ssl_engine_kernel.c.
310 - CVE-2019-0215
311+=======
312+>>>>>>> debian/changelog
313 * SECURITY UPDATE: mod_auth_digest access control bypass
314 - debian/patches/CVE-2019-0217.patch: fix a race condition in
315 modules/aaa/mod_auth_digest.c.
316@@ -601,6 +793,7 @@ apache2 (2.4.38-3) unstable; urgency=high
317 server/util.c.
318 - CVE-2019-0220
319
320+<<<<<<< debian/changelog
321 [ Stefan Fritsch ]
322 * Pull security fixes from 2.4.39 via Ubuntu
323 * CVE-2019-0197: mod_http2: Fix possible crash on late upgrade
324@@ -765,11 +958,35 @@ apache2 (2.4.35-1) unstable; urgency=medium
325 apache2 (2.4.34-1ubuntu2) cosmic; urgency=medium
326
327 * SECURITY UPDATE: denial of service in HTTP/2 via large SETTINGS frames
328+=======
329+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Wed, 03 Apr 2019 09:22:37 -0400
330+
331+apache2 (2.4.29-1ubuntu4.5) bionic; urgency=medium
332+
333+ * d/debhelper/apache2-maintscript-helper: fix typo in apache2_switch_mpm()'s
334+ a2query call. (LP: #1782806)
335+
336+ -- Andreas Hasenack <andreas@canonical.com> Wed, 10 Oct 2018 15:59:25 -0300
337+
338+apache2 (2.4.29-1ubuntu4.4) bionic-security; urgency=medium
339+
340+ * SECURITY UPDATE: DoS in HTTP/2 via NULL pointer
341+ - debian/patches/CVE-2018-1302.patch: remove obsolete stream detach
342+ code in modules/http2/h2_bucket_beam.c, modules/http2/h2_stream.c,
343+ modules/http2/h2_stream.h.
344+ - CVE-2018-1302
345+ * SECURITY UPDATE: DoS in HTTP/2 via worker exhaustion
346+ - debian/patches/CVE-2018-1333.patch: always wake up any conditional
347+ waits when streams are aborted in modules/http2/h2_bucket_beam.c.
348+ - CVE-2018-1333
349+ * SECURITY UPDATE: DoS in HTTP/2 via large SETTINGS frames
350+>>>>>>> debian/changelog
351 - debian/patches/CVE-2018-11763.patch: rework connection IO event
352 handling in modules/http2/h2_session.c, modules/http2/h2_session.h,
353 modules/http2/h2_version.h.
354 - CVE-2018-11763
355
356+<<<<<<< debian/changelog
357 -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Wed, 03 Oct 2018 09:57:22 -0400
358
359 apache2 (2.4.34-1ubuntu1) cosmic; urgency=medium
360@@ -963,6 +1180,26 @@ apache2 (2.4.29-2) unstable; urgency=medium
361 * Add Build-Depends on libbrotli-dev and enable brotli module
362
363 -- Ondřej Surý <ondrej@debian.org> Sun, 14 Jan 2018 11:01:58 +0000
364+=======
365+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Wed, 03 Oct 2018 10:41:08 -0400
366+
367+apache2 (2.4.29-1ubuntu4.3) bionic; urgency=medium
368+
369+ * d/p/balance-member-long-hostname-part{1,2}.patch: Provide an RFC1035
370+ compliant version of the hostname in the
371+ proxy_worker_shared structure. A hostname that is too long is no longer a
372+ fatal error. (LP: #1750356)
373+
374+ -- Andreas Hasenack <andreas@canonical.com> Wed, 27 Jun 2018 14:05:04 -0300
375+
376+apache2 (2.4.29-1ubuntu4.2) bionic; urgency=medium
377+
378+ * debian/patches/includeoptional-ignore-non-existent.patch: silently
379+ ignore a not existent file path with IncludeOptional . Closes LP:
380+ #1766186.
381+
382+ -- Andreas Hasenack <andreas@canonical.com> Thu, 07 Jun 2018 18:10:10 -0300
383+>>>>>>> debian/changelog
384
385 apache2 (2.4.29-1ubuntu4.1) bionic-security; urgency=medium
386
387@@ -3072,6 +3309,18 @@ apache2 (2.2.21-5ubuntu1) precise; urgency=low
388
389 -- Chuck Short <zulcss@ubuntu.com> Mon, 09 Jan 2012 06:26:31 +0000
390
391+apache2 (2.2.21-5ubuntu1) precise; urgency=low
392+
393+ * Merge from Debian testing. Remaining changes:
394+ - debian/{control, rules}: Enable PIE hardening.
395+ - debian/{control, rules, apache2.2-common.ufw.profile}: Add ufw profiles.
396+ - debian/control: Add bzr tag and point it to our tree
397+ - debian/apache2.py, debian/apache2.2-common.install: Add apport hook.
398+ - debian/control, debian/ask-for-passphrase, debian/config-dir/mods-available/ssl.conf:
399+ Plymouth aware passphrase dialog program ask-for-passphrase.
400+
401+ -- Chuck Short <zulcss@ubuntu.com> Mon, 09 Jan 2012 06:26:31 +0000
402+
403 apache2 (2.2.21-5) unstable; urgency=low
404
405 [ Arno Töll ]
406diff --git a/debian/control b/debian/control
407index c12b174..9c00a61 100644
408--- a/debian/control
409+++ b/debian/control
410@@ -7,6 +7,7 @@ Uploaders: Stefan Fritsch <sf@debian.org>,
411 Yadd <yadd@debian.org>
412 Section: httpd
413 Priority: optional
414+<<<<<<< debian/control
415 Build-Depends: debhelper-compat (= 13),
416 dpkg-dev (>= 1.16.1~),
417 bison,
418@@ -25,6 +26,15 @@ Build-Depends: debhelper-compat (= 13),
419 zlib1g-dev,
420 libcurl4-openssl-dev | libcurl4-dev,
421 libjansson-dev
422+=======
423+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
424+XSBC-Original-Maintainer: Debian Apache Maintainers <debian-apache@lists.debian.org>
425+Uploaders: Stefan Fritsch <sf@debian.org>, Arno Töll <arno@debian.org>
426+Build-Depends: debhelper (>= 9.20160709~), lsb-release, dpkg-dev (>= 1.16.1~),
427+ libaprutil1-dev (>= 1.5.0), libapr1-dev (>= 1.5.0), libpcre3-dev, zlib1g-dev,
428+ libnghttp2-dev, libssl-dev (>= 1.1), perl,
429+ liblua5.2-dev, libxml2-dev, autotools-dev, gawk | awk
430+>>>>>>> debian/control
431 Build-Conflicts: autoconf2.13
432 Standards-Version: 4.5.1
433 Vcs-Browser: https://salsa.debian.org/apache-team/apache2
434@@ -43,6 +53,7 @@ Depends: apache2-bin (= ${binary:Version}),
435 procps [!hurd-i386],
436 ${misc:Depends}
437 Recommends: ssl-cert
438+<<<<<<< debian/control
439 Suggests: apache2-doc,
440 apache2-suexec-pristine | apache2-suexec-custom,
441 www-browser,
442@@ -57,6 +68,11 @@ Provides: httpd,
443 Replaces: apache2.2-bin,
444 apache2.2-common,
445 libapache2-mod-proxy-uwsgi (<< 2.4.33)
446+=======
447+Conflicts: apache2.2-common, apache2.2-bin
448+Replaces: apache2.2-common, apache2.2-bin
449+Suggests: www-browser, apache2-doc, apache2-suexec-pristine | apache2-suexec-custom, ufw
450+>>>>>>> debian/control
451 Description: Apache HTTP Server
452 The Apache HTTP Server Project's goal is to build a secure, efficient and
453 extensible HTTP server as standards-compliant open source software. The
454diff --git a/debian/patches/086_svn_cross_compiles b/debian/patches/086_svn_cross_compiles
455new file mode 100644
456index 0000000..b237908
457--- /dev/null
458+++ b/debian/patches/086_svn_cross_compiles
459@@ -0,0 +1,118 @@
460+Description: Pull upstream fixes for autotools for cross-compiling
461+Author: Adam Conrad <adconrad@ubuntu.com>
462+Origin: upstream, http://svn.eu.apache.org/viewvc?view=revision&revision=1328445
463+Origin: upstream, http://svn.eu.apache.org/viewvc?view=revision&revision=1327907
464+Origin: upstream, http://svn.eu.apache.org/viewvc?view=revision&revision=1328390
465+Origin: upstream, http://svn.eu.apache.org/viewvc?view=revision&revision=1328714
466+Forwarded: not-needed
467+
468+Index: apache2-2.4.29/acinclude.m4
469+===================================================================
470+--- apache2-2.4.29.orig/acinclude.m4 2017-11-10 10:56:51.488205250 -0500
471++++ apache2-2.4.29/acinclude.m4 2017-11-10 10:56:51.484205199 -0500
472+@@ -55,6 +55,8 @@ AC_DEFUN([APACHE_GEN_CONFIG_VARS],[
473+ APACHE_SUBST(CPPFLAGS)
474+ APACHE_SUBST(CFLAGS)
475+ APACHE_SUBST(CXXFLAGS)
476++ APACHE_SUBST(CC_FOR_BUILD)
477++ APACHE_SUBST(CFLAGS_FOR_BUILD)
478+ APACHE_SUBST(LTFLAGS)
479+ APACHE_SUBST(LDFLAGS)
480+ APACHE_SUBST(LT_LDFLAGS)
481+@@ -697,7 +699,7 @@ int main(void)
482+ {
483+ return sizeof(void *) < sizeof(long);
484+ }], [ap_cv_void_ptr_lt_long=no], [ap_cv_void_ptr_lt_long=yes],
485+- [ap_cv_void_ptr_lt_long=yes])])
486++ [ap_cv_void_ptr_lt_long="cross compile - not checked"])])
487+
488+ if test "$ap_cv_void_ptr_lt_long" = "yes"; then
489+ AC_MSG_ERROR([Size of "void *" is less than size of "long"])
490+Index: apache2-2.4.29/configure
491+===================================================================
492+--- apache2-2.4.29.orig/configure 2017-11-10 10:56:51.488205250 -0500
493++++ apache2-2.4.29/configure 2017-11-10 10:56:51.488205250 -0500
494+@@ -662,6 +662,8 @@ HTTPD_LDFLAGS
495+ SH_LDFLAGS
496+ LT_LDFLAGS
497+ LTFLAGS
498++CFLAGS_FOR_BUILD
499++CC_FOR_BUILD
500+ CXXFLAGS
501+ CXX
502+ other_targets
503+@@ -6071,6 +6073,12 @@ fi
504+
505+
506+
507++if test "x${build_alias}" != "x${host_alias}"; then
508++ if test "x${CC_FOR_BUILD}" = "x"; then
509++ CC_FOR_BUILD=cc
510++ fi
511++fi
512++
513+ if test "x${cache_file}" = "x/dev/null"; then
514+ # Likewise, ensure that CC and CPP are passed through to the pcre
515+ # configure script iff caching is disabled (the autoconf 2.5x default).
516+@@ -7698,7 +7706,7 @@ if ${ap_cv_void_ptr_lt_long+:} false; th
517+ $as_echo_n "(cached) " >&6
518+ else
519+ if test "$cross_compiling" = yes; then :
520+- ap_cv_void_ptr_lt_long=yes
521++ ap_cv_void_ptr_lt_long="cross compile - not checked"
522+ else
523+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
524+ /* end confdefs.h. */
525+@@ -37522,6 +37530,14 @@ $as_echo "$as_me: " >&6;}
526+
527+
528+
529++ APACHE_VAR_SUBST="$APACHE_VAR_SUBST CC_FOR_BUILD"
530++
531++
532++
533++ APACHE_VAR_SUBST="$APACHE_VAR_SUBST CFLAGS_FOR_BUILD"
534++
535++
536++
537+ APACHE_VAR_SUBST="$APACHE_VAR_SUBST LTFLAGS"
538+
539+
540+Index: apache2-2.4.29/configure.in
541+===================================================================
542+--- apache2-2.4.29.orig/configure.in 2017-11-10 10:56:51.488205250 -0500
543++++ apache2-2.4.29/configure.in 2017-11-10 10:56:51.488205250 -0500
544+@@ -206,6 +206,14 @@ AC_PROG_CPP
545+ dnl Try to get c99 support for variadic macros
546+ ifdef([AC_PROG_CC_C99], [AC_PROG_CC_C99])
547+
548++dnl In case of cross compilation we set CC_FOR_BUILD to cc unless
549++dnl we got already CC_FOR_BUILD from environment.
550++if test "x${build_alias}" != "x${host_alias}"; then
551++ if test "x${CC_FOR_BUILD}" = "x"; then
552++ CC_FOR_BUILD=cc
553++ fi
554++fi
555++
556+ if test "x${cache_file}" = "x/dev/null"; then
557+ # Likewise, ensure that CC and CPP are passed through to the pcre
558+ # configure script iff caching is disabled (the autoconf 2.5x default).
559+Index: apache2-2.4.29/server/Makefile.in
560+===================================================================
561+--- apache2-2.4.29.orig/server/Makefile.in 2017-11-10 10:56:51.488205250 -0500
562++++ apache2-2.4.29/server/Makefile.in 2017-11-10 10:56:51.488205250 -0500
563+@@ -24,9 +24,14 @@ TARGETS = delete-exports $(LTLIBRARY_NAM
564+ include $(top_builddir)/build/rules.mk
565+ include $(top_srcdir)/build/library.mk
566+
567++ifdef CC_FOR_BUILD
568++gen_test_char: gen_test_char.c
569++ $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -DCROSS_COMPILE -o $@ $<
570++else
571+ gen_test_char_OBJECTS = gen_test_char.lo
572+ gen_test_char: $(gen_test_char_OBJECTS)
573+ $(LINK) $(EXTRA_LDFLAGS) $(gen_test_char_OBJECTS) $(EXTRA_LIBS)
574++endif
575+
576+ test_char.h: gen_test_char
577+ ./gen_test_char > test_char.h
578diff --git a/debian/patches/CVE-2017-15710.patch b/debian/patches/CVE-2017-15710.patch
579new file mode 100644
580index 0000000..a218970
581--- /dev/null
582+++ b/debian/patches/CVE-2017-15710.patch
583@@ -0,0 +1,24 @@
584+Description: fix DoS via missing header with AuthLDAPCharsetConfig
585+Origin: upstream, http://svn.apache.org/viewvc?view=revision&revision=1824456
586+
587+Index: apache2-2.4.29/modules/aaa/mod_authnz_ldap.c
588+===================================================================
589+--- apache2-2.4.29.orig/modules/aaa/mod_authnz_ldap.c 2017-06-29 07:31:20.000000000 -0400
590++++ apache2-2.4.29/modules/aaa/mod_authnz_ldap.c 2018-04-18 09:14:38.995193064 -0400
591+@@ -126,9 +126,13 @@ static char* derive_codepage_from_lang (
592+
593+ charset = (char*) apr_hash_get(charset_conversions, language, APR_HASH_KEY_STRING);
594+
595+- if (!charset) {
596+- language[2] = '\0';
597+- charset = (char*) apr_hash_get(charset_conversions, language, APR_HASH_KEY_STRING);
598++ /*
599++ * Test if language values like 'en-US' return a match from the charset
600++ * conversion map when shortened to 'en'.
601++ */
602++ if (!charset && strlen(language) > 3 && language[2] == '-') {
603++ char *language_short = apr_pstrndup(p, language, 2);
604++ charset = (char*) apr_hash_get(charset_conversions, language_short, APR_HASH_KEY_STRING);
605+ }
606+
607+ if (charset) {
608diff --git a/debian/patches/CVE-2017-15715.patch b/debian/patches/CVE-2017-15715.patch
609new file mode 100644
610index 0000000..157a0b2
611--- /dev/null
612+++ b/debian/patches/CVE-2017-15715.patch
613@@ -0,0 +1,192 @@
614+Description: fix incorrect <FilesMatch> matching
615+Origin: upstream, https://svn.apache.org/viewvc?view=revision&revision=1824472
616+
617+Index: apache2-2.4.29/include/ap_regex.h
618+===================================================================
619+--- apache2-2.4.29.orig/include/ap_regex.h 2014-01-05 11:14:26.000000000 -0500
620++++ apache2-2.4.29/include/ap_regex.h 2018-04-18 09:14:53.391220215 -0400
621+@@ -77,6 +77,8 @@ extern "C" {
622+ #define AP_REG_NOMEM 0x20 /* nomem in our code */
623+ #define AP_REG_DOTALL 0x40 /* perl's /s flag */
624+
625++#define AP_REG_DOLLAR_ENDONLY 0x200 /* '$' matches at end of subject string only */
626++
627+ #define AP_REG_MATCH "MATCH_" /** suggested prefix for ap_regname */
628+
629+ /* Error values: */
630+@@ -103,6 +105,26 @@ typedef struct {
631+ /* The functions */
632+
633+ /**
634++ * Get default compile flags
635++ * @return Bitwise OR of AP_REG_* flags
636++ */
637++AP_DECLARE(int) ap_regcomp_get_default_cflags(void);
638++
639++/**
640++ * Set default compile flags
641++ * @param cflags Bitwise OR of AP_REG_* flags
642++ */
643++AP_DECLARE(void) ap_regcomp_set_default_cflags(int cflags);
644++
645++/**
646++ * Get the AP_REG_* corresponding to the string.
647++ * @param name The name (i.e. AP_REG_<name>)
648++ * @return The AP_REG_*, or zero if the string is unknown
649++ *
650++ */
651++AP_DECLARE(int) ap_regcomp_default_cflag_by_name(const char *name);
652++
653++/**
654+ * Compile a regular expression.
655+ * @param preg Returned compiled regex
656+ * @param regex The regular expression string
657+Index: apache2-2.4.29/server/core.c
658+===================================================================
659+--- apache2-2.4.29.orig/server/core.c 2017-09-08 09:13:11.000000000 -0400
660++++ apache2-2.4.29/server/core.c 2018-04-18 09:14:53.387220208 -0400
661+@@ -48,6 +48,7 @@
662+ #include "mod_core.h"
663+ #include "mod_proxy.h"
664+ #include "ap_listen.h"
665++#include "ap_regex.h"
666+
667+ #include "mod_so.h" /* for ap_find_loaded_module_symbol */
668+
669+@@ -2846,6 +2847,58 @@ static const char *virtualhost_section(c
670+ return errmsg;
671+ }
672+
673++static const char *set_regex_default_options(cmd_parms *cmd,
674++ void *dummy,
675++ const char *arg)
676++{
677++ const command_rec *thiscmd = cmd->cmd;
678++ int cflags, cflag;
679++
680++ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
681++ if (err != NULL) {
682++ return err;
683++ }
684++
685++ cflags = ap_regcomp_get_default_cflags();
686++ while (*arg) {
687++ const char *name = ap_getword_conf(cmd->pool, &arg);
688++ int how = 0;
689++
690++ if (strcasecmp(name, "none") == 0) {
691++ cflags = 0;
692++ continue;
693++ }
694++
695++ if (*name == '+') {
696++ name++;
697++ how = +1;
698++ }
699++ else if (*name == '-') {
700++ name++;
701++ how = -1;
702++ }
703++
704++ cflag = ap_regcomp_default_cflag_by_name(name);
705++ if (!cflag) {
706++ return apr_psprintf(cmd->pool, "%s: option '%s' unknown",
707++ thiscmd->name, name);
708++ }
709++
710++ if (how > 0) {
711++ cflags |= cflag;
712++ }
713++ else if (how < 0) {
714++ cflags &= ~cflag;
715++ }
716++ else {
717++ cflags = cflag;
718++ }
719++ }
720++ ap_regcomp_set_default_cflags(cflags);
721++
722++ return NULL;
723++}
724++
725+ static const char *set_server_alias(cmd_parms *cmd, void *dummy,
726+ const char *arg)
727+ {
728+@@ -4421,6 +4474,9 @@ AP_INIT_TAKE12("RLimitNPROC", no_set_lim
729+ OR_ALL, "soft/hard limits for max number of processes per uid"),
730+ #endif
731+
732++AP_INIT_RAW_ARGS("RegexDefaultOptions", set_regex_default_options, NULL, RSRC_CONF,
733++ "default options for regexes (prefixed by '+' to add, '-' to del)"),
734++
735+ /* internal recursion stopper */
736+ AP_INIT_TAKE12("LimitInternalRecursion", set_recursion_limit, NULL, RSRC_CONF,
737+ "maximum recursion depth of internal redirects and subrequests"),
738+@@ -4856,6 +4912,8 @@ static int core_pre_config(apr_pool_t *p
739+ apr_pool_cleanup_register(pconf, NULL, reset_config_defines,
740+ apr_pool_cleanup_null);
741+
742++ ap_regcomp_set_default_cflags(AP_REG_DOLLAR_ENDONLY);
743++
744+ mpm_common_pre_config(pconf);
745+
746+ return OK;
747+Index: apache2-2.4.29/server/util_pcre.c
748+===================================================================
749+--- apache2-2.4.29.orig/server/util_pcre.c 2014-01-05 11:14:26.000000000 -0500
750++++ apache2-2.4.29/server/util_pcre.c 2018-04-18 09:14:53.391220215 -0400
751+@@ -111,6 +111,38 @@ AP_DECLARE(void) ap_regfree(ap_regex_t *
752+ * Compile a regular expression *
753+ *************************************************/
754+
755++static int default_cflags = AP_REG_DOLLAR_ENDONLY;
756++
757++AP_DECLARE(int) ap_regcomp_get_default_cflags(void)
758++{
759++ return default_cflags;
760++}
761++
762++AP_DECLARE(void) ap_regcomp_set_default_cflags(int cflags)
763++{
764++ default_cflags = cflags;
765++}
766++
767++AP_DECLARE(int) ap_regcomp_default_cflag_by_name(const char *name)
768++{
769++ int cflag = 0;
770++
771++ if (ap_cstr_casecmp(name, "ICASE") == 0) {
772++ cflag = AP_REG_ICASE;
773++ }
774++ else if (ap_cstr_casecmp(name, "DOTALL") == 0) {
775++ cflag = AP_REG_DOTALL;
776++ }
777++ else if (ap_cstr_casecmp(name, "DOLLAR_ENDONLY") == 0) {
778++ cflag = AP_REG_DOLLAR_ENDONLY;
779++ }
780++ else if (ap_cstr_casecmp(name, "EXTENDED") == 0) {
781++ cflag = AP_REG_EXTENDED;
782++ }
783++
784++ return cflag;
785++}
786++
787+ /*
788+ * Arguments:
789+ * preg points to a structure for recording the compiled expression
790+@@ -127,12 +159,15 @@ AP_DECLARE(int) ap_regcomp(ap_regex_t *
791+ int errcode = 0;
792+ int options = PCRE_DUPNAMES;
793+
794++ cflags |= default_cflags;
795+ if ((cflags & AP_REG_ICASE) != 0)
796+ options |= PCRE_CASELESS;
797+ if ((cflags & AP_REG_NEWLINE) != 0)
798+ options |= PCRE_MULTILINE;
799+ if ((cflags & AP_REG_DOTALL) != 0)
800+ options |= PCRE_DOTALL;
801++ if ((cflags & AP_REG_DOLLAR_ENDONLY) != 0)
802++ options |= PCRE_DOLLAR_ENDONLY;
803+
804+ preg->re_pcre =
805+ pcre_compile2(pattern, options, &errcode, &errorptr, &erroffset, NULL);
806diff --git a/debian/patches/CVE-2018-1283.patch b/debian/patches/CVE-2018-1283.patch
807new file mode 100644
808index 0000000..b596b3c
809--- /dev/null
810+++ b/debian/patches/CVE-2018-1283.patch
811@@ -0,0 +1,28 @@
812+Description: fix mod_session header manipulation
813+Origin: upstream, https://svn.apache.org/viewvc?view=revision&revision=1824477
814+
815+Index: apache2-2.4.29/modules/session/mod_session.c
816+===================================================================
817+--- apache2-2.4.29.orig/modules/session/mod_session.c 2016-11-14 06:15:08.000000000 -0500
818++++ apache2-2.4.29/modules/session/mod_session.c 2018-04-18 09:15:12.551256243 -0400
819+@@ -510,12 +510,15 @@ static int session_fixups(request_rec *
820+ */
821+ ap_session_load(r, &z);
822+
823+- if (z && conf->env) {
824+- session_identity_encode(r, z);
825+- if (z->encoded) {
826+- apr_table_set(r->subprocess_env, HTTP_SESSION, z->encoded);
827+- z->encoded = NULL;
828++ if (conf->env) {
829++ if (z) {
830++ session_identity_encode(r, z);
831++ if (z->encoded) {
832++ apr_table_set(r->subprocess_env, HTTP_SESSION, z->encoded);
833++ z->encoded = NULL;
834++ }
835+ }
836++ apr_table_unset(r->headers_in, "Session");
837+ }
838+
839+ return OK;
840diff --git a/debian/patches/CVE-2018-1301.patch b/debian/patches/CVE-2018-1301.patch
841new file mode 100644
842index 0000000..c4fc07a
843--- /dev/null
844+++ b/debian/patches/CVE-2018-1301.patch
845@@ -0,0 +1,200 @@
846+Description: fix DoS via specially-crafted request
847+Origin: upstream, https://svn.apache.org/viewvc?view=revision&revision=1824469
848+
849+Index: apache2-2.4.29/server/protocol.c
850+===================================================================
851+--- apache2-2.4.29.orig/server/protocol.c 2017-10-10 13:51:13.000000000 -0400
852++++ apache2-2.4.29/server/protocol.c 2018-04-18 09:15:27.027283380 -0400
853+@@ -225,6 +225,11 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
854+ int fold = flags & AP_GETLINE_FOLD;
855+ int crlf = flags & AP_GETLINE_CRLF;
856+
857++ if (!n) {
858++ /* Needs room for NUL byte at least */
859++ return APR_BADARG;
860++ }
861++
862+ /*
863+ * Initialize last_char as otherwise a random value will be compared
864+ * against APR_ASCII_LF at the end of the loop if bb only contains
865+@@ -238,14 +243,15 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
866+ rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_GETLINE,
867+ APR_BLOCK_READ, 0);
868+ if (rv != APR_SUCCESS) {
869+- return rv;
870++ goto cleanup;
871+ }
872+
873+ /* Something horribly wrong happened. Someone didn't block!
874+ * (this also happens at the end of each keepalive connection)
875+ */
876+ if (APR_BRIGADE_EMPTY(bb)) {
877+- return APR_EGENERAL;
878++ rv = APR_EGENERAL;
879++ goto cleanup;
880+ }
881+
882+ for (e = APR_BRIGADE_FIRST(bb);
883+@@ -263,7 +269,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
884+
885+ rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
886+ if (rv != APR_SUCCESS) {
887+- return rv;
888++ goto cleanup;
889+ }
890+
891+ if (len == 0) {
892+@@ -276,17 +282,8 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
893+
894+ /* Would this overrun our buffer? If so, we'll die. */
895+ if (n < bytes_handled + len) {
896+- *read = bytes_handled;
897+- if (*s) {
898+- /* ensure this string is NUL terminated */
899+- if (bytes_handled > 0) {
900+- (*s)[bytes_handled-1] = '\0';
901+- }
902+- else {
903+- (*s)[0] = '\0';
904+- }
905+- }
906+- return APR_ENOSPC;
907++ rv = APR_ENOSPC;
908++ goto cleanup;
909+ }
910+
911+ /* Do we have to handle the allocation ourselves? */
912+@@ -294,7 +291,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
913+ /* We'll assume the common case where one bucket is enough. */
914+ if (!*s) {
915+ current_alloc = len;
916+- *s = apr_palloc(r->pool, current_alloc);
917++ *s = apr_palloc(r->pool, current_alloc + 1);
918+ }
919+ else if (bytes_handled + len > current_alloc) {
920+ /* Increase the buffer size */
921+@@ -305,7 +302,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
922+ new_size = (bytes_handled + len) * 2;
923+ }
924+
925+- new_buffer = apr_palloc(r->pool, new_size);
926++ new_buffer = apr_palloc(r->pool, new_size + 1);
927+
928+ /* Copy what we already had. */
929+ memcpy(new_buffer, *s, bytes_handled);
930+@@ -329,19 +326,15 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
931+ }
932+ }
933+
934+- if (crlf && (last_char <= *s || last_char[-1] != APR_ASCII_CR)) {
935+- *last_char = '\0';
936+- bytes_handled = last_char - *s;
937+- *read = bytes_handled;
938+- return APR_EINVAL;
939+- }
940+-
941+- /* Now NUL-terminate the string at the end of the line;
942++ /* Now terminate the string at the end of the line;
943+ * if the last-but-one character is a CR, terminate there */
944+ if (last_char > *s && last_char[-1] == APR_ASCII_CR) {
945+ last_char--;
946+ }
947+- *last_char = '\0';
948++ else if (crlf) {
949++ rv = APR_EINVAL;
950++ goto cleanup;
951++ }
952+ bytes_handled = last_char - *s;
953+
954+ /* If we're folding, we have more work to do.
955+@@ -361,7 +354,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
956+ rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_SPECULATIVE,
957+ APR_BLOCK_READ, 1);
958+ if (rv != APR_SUCCESS) {
959+- return rv;
960++ goto cleanup;
961+ }
962+
963+ if (APR_BRIGADE_EMPTY(bb)) {
964+@@ -378,7 +371,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
965+ rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
966+ if (rv != APR_SUCCESS) {
967+ apr_brigade_cleanup(bb);
968+- return rv;
969++ goto cleanup;
970+ }
971+
972+ /* Found one, so call ourselves again to get the next line.
973+@@ -395,10 +388,8 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
974+ if (c == APR_ASCII_BLANK || c == APR_ASCII_TAB) {
975+ /* Do we have enough space? We may be full now. */
976+ if (bytes_handled >= n) {
977+- *read = n;
978+- /* ensure this string is terminated */
979+- (*s)[n-1] = '\0';
980+- return APR_ENOSPC;
981++ rv = APR_ENOSPC;
982++ goto cleanup;
983+ }
984+ else {
985+ apr_size_t next_size, next_len;
986+@@ -411,7 +402,6 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
987+ tmp = NULL;
988+ }
989+ else {
990+- /* We're null terminated. */
991+ tmp = last_char;
992+ }
993+
994+@@ -420,7 +410,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
995+ rv = ap_rgetline_core(&tmp, next_size,
996+ &next_len, r, 0, bb);
997+ if (rv != APR_SUCCESS) {
998+- return rv;
999++ goto cleanup;
1000+ }
1001+
1002+ if (do_alloc && next_len > 0) {
1003+@@ -434,7 +424,7 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
1004+ memcpy(new_buffer, *s, bytes_handled);
1005+
1006+ /* copy the new line, including the trailing null */
1007+- memcpy(new_buffer + bytes_handled, tmp, next_len + 1);
1008++ memcpy(new_buffer + bytes_handled, tmp, next_len);
1009+ *s = new_buffer;
1010+ }
1011+
1012+@@ -447,8 +437,21 @@ AP_DECLARE(apr_status_t) ap_rgetline_cor
1013+ }
1014+ }
1015+ }
1016++
1017++cleanup:
1018++ if (bytes_handled >= n) {
1019++ bytes_handled = n - 1;
1020++ }
1021++ if (*s) {
1022++ /* ensure the string is NUL terminated */
1023++ (*s)[bytes_handled] = '\0';
1024++ }
1025+ *read = bytes_handled;
1026+
1027++ if (rv != APR_SUCCESS) {
1028++ return rv;
1029++ }
1030++
1031+ /* PR#43039: We shouldn't accept NULL bytes within the line */
1032+ if (strlen(*s) < bytes_handled) {
1033+ return APR_EINVAL;
1034+@@ -487,6 +490,11 @@ AP_DECLARE(int) ap_getline(char *s, int
1035+ apr_size_t len;
1036+ apr_bucket_brigade *tmp_bb;
1037+
1038++ if (n < 1) {
1039++ /* Can't work since we always NUL terminate */
1040++ return -1;
1041++ }
1042++
1043+ tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
1044+ rv = ap_rgetline(&tmp_s, n, &len, r, flags, tmp_bb);
1045+ apr_brigade_destroy(tmp_bb);
1046diff --git a/debian/patches/CVE-2018-1303.patch b/debian/patches/CVE-2018-1303.patch
1047new file mode 100644
1048index 0000000..42192c8
1049--- /dev/null
1050+++ b/debian/patches/CVE-2018-1303.patch
1051@@ -0,0 +1,17 @@
1052+Description: fix mod_cache_socache DoS
1053+Origin: upstream, https://svn.apache.org/viewvc?view=revision&revision=1824475
1054+
1055+Index: apache2-2.4.29/modules/cache/mod_cache_socache.c
1056+===================================================================
1057+--- apache2-2.4.29.orig/modules/cache/mod_cache_socache.c 2017-06-29 07:31:20.000000000 -0400
1058++++ apache2-2.4.29/modules/cache/mod_cache_socache.c 2018-04-18 09:15:39.675307037 -0400
1059+@@ -213,7 +213,8 @@ static apr_status_t read_table(cache_han
1060+ "Premature end of cache headers.");
1061+ return APR_EGENERAL;
1062+ }
1063+- while (apr_isspace(buffer[colon])) {
1064++ /* Do not go past the \r from above as apr_isspace('\r') is true */
1065++ while (apr_isspace(buffer[colon]) && (colon < *slider)) {
1066+ colon++;
1067+ }
1068+ apr_table_addn(table, apr_pstrndup(r->pool, (const char *) buffer
1069diff --git a/debian/patches/CVE-2018-1312.patch b/debian/patches/CVE-2018-1312.patch
1070new file mode 100644
1071index 0000000..f91999a
1072--- /dev/null
1073+++ b/debian/patches/CVE-2018-1312.patch
1074@@ -0,0 +1,403 @@
1075+Description: fix insecure nonce generation
1076+Origin: upstream, https://svn.apache.org/viewvc?view=revision&revision=1824481
1077+Bug: https://bz.apache.org/bugzilla/show_bug.cgi?id=54637
1078+
1079+Index: apache2-2.4.29/modules/aaa/mod_auth_digest.c
1080+===================================================================
1081+--- apache2-2.4.29.orig/modules/aaa/mod_auth_digest.c 2017-07-05 20:02:54.000000000 -0400
1082++++ apache2-2.4.29/modules/aaa/mod_auth_digest.c 2018-04-18 09:15:50.839327873 -0400
1083+@@ -26,20 +26,13 @@
1084+ * reports to the Apache bug-database, or send them directly to me
1085+ * at ronald@innovation.ch.
1086+ *
1087+- * Requires either /dev/random (or equivalent) or the truerand library,
1088+- * available for instance from
1089+- * ftp://research.att.com/dist/mab/librand.shar
1090+- *
1091+ * Open Issues:
1092+ * - qop=auth-int (when streams and trailer support available)
1093+ * - nonce-format configurability
1094+ * - Proxy-Authorization-Info header is set by this module, but is
1095+ * currently ignored by mod_proxy (needs patch to mod_proxy)
1096+- * - generating the secret takes a while (~ 8 seconds) if using the
1097+- * truerand library
1098+ * - The source of the secret should be run-time directive (with server
1099+- * scope: RSRC_CONF). However, that could be tricky when trying to
1100+- * choose truerand vs. file...
1101++ * scope: RSRC_CONF)
1102+ * - shared-mem not completely tested yet. Seems to work ok for me,
1103+ * but... (definitely won't work on Windoze)
1104+ * - Sharing a realm among multiple servers has following problems:
1105+@@ -52,6 +45,8 @@
1106+ * captures a packet sent to one server and sends it to another
1107+ * one. Should we add "AuthDigestNcCheck Strict"?
1108+ * - expired nonces give amaya fits.
1109++ * - MD5-sess and auth-int are not yet implemented. An incomplete
1110++ * implementation has been removed and can be retrieved from svn history.
1111+ */
1112+
1113+ #include "apr_sha1.h"
1114+@@ -94,7 +89,6 @@ typedef struct digest_config_struct {
1115+ apr_array_header_t *qop_list;
1116+ apr_sha1_ctx_t nonce_ctx;
1117+ apr_time_t nonce_lifetime;
1118+- const char *nonce_format;
1119+ int check_nc;
1120+ const char *algorithm;
1121+ char *uri_list;
1122+@@ -112,7 +106,8 @@ typedef struct digest_config_struct {
1123+ #define NONCE_HASH_LEN (2*APR_SHA1_DIGESTSIZE)
1124+ #define NONCE_LEN (int )(NONCE_TIME_LEN + NONCE_HASH_LEN)
1125+
1126+-#define SECRET_LEN 20
1127++#define SECRET_LEN 20
1128++#define RETAINED_DATA_ID "mod_auth_digest"
1129+
1130+
1131+ /* client list definitions */
1132+@@ -121,7 +116,6 @@ typedef struct hash_entry {
1133+ unsigned long key; /* the key for this entry */
1134+ struct hash_entry *next; /* next entry in the bucket */
1135+ unsigned long nonce_count; /* for nonce-count checking */
1136+- char ha1[2*APR_MD5_DIGESTSIZE+1]; /* for algorithm=MD5-sess */
1137+ char last_nonce[NONCE_LEN+1]; /* for one-time nonce's */
1138+ } client_entry;
1139+
1140+@@ -170,7 +164,7 @@ typedef union time_union {
1141+ unsigned char arr[sizeof(apr_time_t)];
1142+ } time_rec;
1143+
1144+-static unsigned char secret[SECRET_LEN];
1145++static unsigned char *secret;
1146+
1147+ /* client-list, opaque, and one-time-nonce stuff */
1148+
1149+@@ -228,35 +222,11 @@ static apr_status_t cleanup_tables(void
1150+ return APR_SUCCESS;
1151+ }
1152+
1153+-static apr_status_t initialize_secret(server_rec *s)
1154+-{
1155+- apr_status_t status;
1156+-
1157+- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01757)
1158+- "generating secret for digest authentication ...");
1159+-
1160+-#if APR_HAS_RANDOM
1161+- status = apr_generate_random_bytes(secret, sizeof(secret));
1162+-#else
1163+-#error APR random number support is missing; you probably need to install the truerand library.
1164+-#endif
1165+-
1166+- if (status != APR_SUCCESS) {
1167+- ap_log_error(APLOG_MARK, APLOG_CRIT, status, s, APLOGNO(01758)
1168+- "error generating secret");
1169+- return status;
1170+- }
1171+-
1172+- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01759) "done");
1173+-
1174+- return APR_SUCCESS;
1175+-}
1176+-
1177+ static void log_error_and_cleanup(char *msg, apr_status_t sts, server_rec *s)
1178+ {
1179+ ap_log_error(APLOG_MARK, APLOG_ERR, sts, s, APLOGNO(01760)
1180+- "%s - all nonce-count checking, one-time nonces, and "
1181+- "MD5-sess algorithm disabled", msg);
1182++ "%s - all nonce-count checking and one-time nonces"
1183++ "disabled", msg);
1184+
1185+ cleanup_tables(NULL);
1186+ }
1187+@@ -386,16 +356,32 @@ static int initialize_tables(server_rec
1188+ static int pre_init(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
1189+ {
1190+ apr_status_t rv;
1191++ void *retained;
1192+
1193+ rv = ap_mutex_register(pconf, client_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
1194+- if (rv == APR_SUCCESS) {
1195+- rv = ap_mutex_register(pconf, opaque_mutex_type, NULL, APR_LOCK_DEFAULT,
1196+- 0);
1197+- }
1198+- if (rv != APR_SUCCESS) {
1199+- return rv;
1200+- }
1201++ if (rv != APR_SUCCESS)
1202++ return !OK;
1203++ rv = ap_mutex_register(pconf, opaque_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
1204++ if (rv != APR_SUCCESS)
1205++ return !OK;
1206+
1207++ retained = ap_retained_data_get(RETAINED_DATA_ID);
1208++ if (retained == NULL) {
1209++ retained = ap_retained_data_create(RETAINED_DATA_ID, SECRET_LEN);
1210++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(01757)
1211++ "generating secret for digest authentication");
1212++#if APR_HAS_RANDOM
1213++ rv = apr_generate_random_bytes(retained, SECRET_LEN);
1214++#else
1215++#error APR random number support is missing
1216++#endif
1217++ if (rv != APR_SUCCESS) {
1218++ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(01758)
1219++ "error generating secret");
1220++ return !OK;
1221++ }
1222++ }
1223++ secret = retained;
1224+ return OK;
1225+ }
1226+
1227+@@ -408,10 +394,6 @@ static int initialize_module(apr_pool_t
1228+ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
1229+ return OK;
1230+
1231+- if (initialize_secret(s) != APR_SUCCESS) {
1232+- return !OK;
1233+- }
1234+-
1235+ #if APR_HAS_SHARED_MEMORY
1236+ /* Note: this stuff is currently fixed for the lifetime of the server,
1237+ * i.e. even across restarts. This means that A) any shmem-size
1238+@@ -492,6 +474,16 @@ static void *create_digest_dir_config(ap
1239+ static const char *set_realm(cmd_parms *cmd, void *config, const char *realm)
1240+ {
1241+ digest_config_rec *conf = (digest_config_rec *) config;
1242++#ifdef AP_DEBUG
1243++ int i;
1244++
1245++ /* check that we got random numbers */
1246++ for (i = 0; i < SECRET_LEN; i++) {
1247++ if (secret[i] != 0)
1248++ break;
1249++ }
1250++ ap_assert(i < SECRET_LEN);
1251++#endif
1252+
1253+ /* The core already handles the realm, but it's just too convenient to
1254+ * grab it ourselves too and cache some setups. However, we need to
1255+@@ -505,7 +497,7 @@ static const char *set_realm(cmd_parms *
1256+ * and directives outside a virtual host section)
1257+ */
1258+ apr_sha1_init(&conf->nonce_ctx);
1259+- apr_sha1_update_binary(&conf->nonce_ctx, secret, sizeof(secret));
1260++ apr_sha1_update_binary(&conf->nonce_ctx, secret, SECRET_LEN);
1261+ apr_sha1_update_binary(&conf->nonce_ctx, (const unsigned char *) realm,
1262+ strlen(realm));
1263+
1264+@@ -599,8 +591,7 @@ static const char *set_nonce_lifetime(cm
1265+ static const char *set_nonce_format(cmd_parms *cmd, void *config,
1266+ const char *fmt)
1267+ {
1268+- ((digest_config_rec *) config)->nonce_format = fmt;
1269+- return "AuthDigestNonceFormat is not implemented (yet)";
1270++ return "AuthDigestNonceFormat is not implemented";
1271+ }
1272+
1273+ static const char *set_nc_check(cmd_parms *cmd, void *config, int flag)
1274+@@ -621,7 +612,7 @@ static const char *set_algorithm(cmd_par
1275+ {
1276+ if (!strcasecmp(alg, "MD5-sess")) {
1277+ return "AuthDigestAlgorithm: ERROR: algorithm `MD5-sess' "
1278+- "is not fully implemented";
1279++ "is not implemented";
1280+ }
1281+ else if (strcasecmp(alg, "MD5")) {
1282+ return apr_pstrcat(cmd->pool, "Invalid algorithm in AuthDigestAlgorithm: ", alg, NULL);
1283+@@ -1147,7 +1138,7 @@ static const char *gen_nonce(apr_pool_t
1284+ static client_entry *gen_client(const request_rec *r)
1285+ {
1286+ unsigned long op;
1287+- client_entry new_entry = { 0, NULL, 0, "", "" }, *entry;
1288++ client_entry new_entry = { 0, NULL, 0, "" }, *entry;
1289+
1290+ if (!opaque_cntr) {
1291+ return NULL;
1292+@@ -1168,92 +1159,6 @@ static client_entry *gen_client(const re
1293+
1294+
1295+ /*
1296+- * MD5-sess code.
1297+- *
1298+- * If you want to use algorithm=MD5-sess you must write get_userpw_hash()
1299+- * yourself (see below). The dummy provided here just uses the hash from
1300+- * the auth-file, i.e. it is only useful for testing client implementations
1301+- * of MD5-sess .
1302+- */
1303+-
1304+-/*
1305+- * get_userpw_hash() will be called each time a new session needs to be
1306+- * generated and is expected to return the equivalent of
1307+- *
1308+- * h_urp = ap_md5(r->pool,
1309+- * apr_pstrcat(r->pool, username, ":", ap_auth_name(r), ":", passwd))
1310+- * ap_md5(r->pool,
1311+- * (unsigned char *) apr_pstrcat(r->pool, h_urp, ":", resp->nonce, ":",
1312+- * resp->cnonce, NULL));
1313+- *
1314+- * or put differently, it must return
1315+- *
1316+- * MD5(MD5(username ":" realm ":" password) ":" nonce ":" cnonce)
1317+- *
1318+- * If something goes wrong, the failure must be logged and NULL returned.
1319+- *
1320+- * You must implement this yourself, which will probably consist of code
1321+- * contacting the password server with the necessary information (typically
1322+- * the username, realm, nonce, and cnonce) and receiving the hash from it.
1323+- *
1324+- * TBD: This function should probably be in a separate source file so that
1325+- * people need not modify mod_auth_digest.c each time they install a new
1326+- * version of apache.
1327+- */
1328+-static const char *get_userpw_hash(const request_rec *r,
1329+- const digest_header_rec *resp,
1330+- const digest_config_rec *conf)
1331+-{
1332+- return ap_md5(r->pool,
1333+- (unsigned char *) apr_pstrcat(r->pool, conf->ha1, ":", resp->nonce,
1334+- ":", resp->cnonce, NULL));
1335+-}
1336+-
1337+-
1338+-/* Retrieve current session H(A1). If there is none and "generate" is
1339+- * true then a new session for MD5-sess is generated and stored in the
1340+- * client struct; if generate is false, or a new session could not be
1341+- * generated then NULL is returned (in case of failure to generate the
1342+- * failure reason will have been logged already).
1343+- */
1344+-static const char *get_session_HA1(const request_rec *r,
1345+- digest_header_rec *resp,
1346+- const digest_config_rec *conf,
1347+- int generate)
1348+-{
1349+- const char *ha1 = NULL;
1350+-
1351+- /* return the current sessions if there is one */
1352+- if (resp->opaque && resp->client && resp->client->ha1[0]) {
1353+- return resp->client->ha1;
1354+- }
1355+- else if (!generate) {
1356+- return NULL;
1357+- }
1358+-
1359+- /* generate a new session */
1360+- if (!resp->client) {
1361+- resp->client = gen_client(r);
1362+- }
1363+- if (resp->client) {
1364+- ha1 = get_userpw_hash(r, resp, conf);
1365+- if (ha1) {
1366+- memcpy(resp->client->ha1, ha1, sizeof(resp->client->ha1));
1367+- }
1368+- }
1369+-
1370+- return ha1;
1371+-}
1372+-
1373+-
1374+-static void clear_session(const digest_header_rec *resp)
1375+-{
1376+- if (resp->client) {
1377+- resp->client->ha1[0] = '\0';
1378+- }
1379+-}
1380+-
1381+-/*
1382+ * Authorization challenge generation code (for WWW-Authenticate)
1383+ */
1384+
1385+@@ -1291,8 +1196,7 @@ static void note_digest_auth_failure(req
1386+
1387+ if (resp->opaque == NULL) {
1388+ /* new client */
1389+- if ((conf->check_nc || conf->nonce_lifetime == 0
1390+- || !strcasecmp(conf->algorithm, "MD5-sess"))
1391++ if ((conf->check_nc || conf->nonce_lifetime == 0)
1392+ && (resp->client = gen_client(r)) != NULL) {
1393+ opaque = ltox(r->pool, resp->client->key);
1394+ }
1395+@@ -1332,15 +1236,6 @@ static void note_digest_auth_failure(req
1396+ memcpy(resp->client->last_nonce, nonce, NONCE_LEN+1);
1397+ }
1398+
1399+- /* Setup MD5-sess stuff. Note that we just clear out the session
1400+- * info here, since we can't generate a new session until the request
1401+- * from the client comes in with the cnonce.
1402+- */
1403+-
1404+- if (!strcasecmp(conf->algorithm, "MD5-sess")) {
1405+- clear_session(resp);
1406+- }
1407+-
1408+ /* setup domain attribute. We want to send this attribute wherever
1409+ * possible so that the client won't send the Authorization header
1410+ * unnecessarily (it's usually > 200 bytes!).
1411+@@ -1606,24 +1501,9 @@ static const char *new_digest(const requ
1412+ {
1413+ const char *ha1, *ha2, *a2;
1414+
1415+- if (resp->algorithm && !strcasecmp(resp->algorithm, "MD5-sess")) {
1416+- ha1 = get_session_HA1(r, resp, conf, 1);
1417+- if (!ha1) {
1418+- return NULL;
1419+- }
1420+- }
1421+- else {
1422+- ha1 = conf->ha1;
1423+- }
1424++ ha1 = conf->ha1;
1425+
1426+- if (resp->message_qop && !strcasecmp(resp->message_qop, "auth-int")) {
1427+- a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, ":",
1428+- ap_md5(r->pool, (const unsigned char*) ""), NULL);
1429+- /* TBD */
1430+- }
1431+- else {
1432+- a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL);
1433+- }
1434++ a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL);
1435+ ha2 = ap_md5(r->pool, (const unsigned char *)a2);
1436+
1437+ return ap_md5(r->pool,
1438+@@ -1871,8 +1751,7 @@ static int authenticate_digest_user(requ
1439+ }
1440+
1441+ if (resp->algorithm != NULL
1442+- && strcasecmp(resp->algorithm, "MD5")
1443+- && strcasecmp(resp->algorithm, "MD5-sess")) {
1444++ && strcasecmp(resp->algorithm, "MD5")) {
1445+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01789)
1446+ "unknown algorithm `%s' received: %s",
1447+ resp->algorithm, r->uri);
1448+@@ -2024,27 +1903,9 @@ static int add_auth_info(request_rec *r)
1449+
1450+ /* calculate rspauth attribute
1451+ */
1452+- if (resp->algorithm && !strcasecmp(resp->algorithm, "MD5-sess")) {
1453+- ha1 = get_session_HA1(r, resp, conf, 0);
1454+- if (!ha1) {
1455+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01795)
1456+- "internal error: couldn't find session "
1457+- "info for user %s", resp->username);
1458+- return !OK;
1459+- }
1460+- }
1461+- else {
1462+- ha1 = conf->ha1;
1463+- }
1464++ ha1 = conf->ha1;
1465+
1466+- if (resp->message_qop && !strcasecmp(resp->message_qop, "auth-int")) {
1467+- a2 = apr_pstrcat(r->pool, ":", resp->uri, ":",
1468+- ap_md5(r->pool,(const unsigned char *) ""), NULL);
1469+- /* TBD */
1470+- }
1471+- else {
1472+- a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL);
1473+- }
1474++ a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL);
1475+ ha2 = ap_md5(r->pool, (const unsigned char *)a2);
1476+
1477+ resp_dig = ap_md5(r->pool,
1478diff --git a/debian/patches/CVE-2018-17199.patch b/debian/patches/CVE-2018-17199.patch
1479new file mode 100644
1480index 0000000..e42f56b
1481--- /dev/null
1482+++ b/debian/patches/CVE-2018-17199.patch
1483@@ -0,0 +1,85 @@
1484+From 34f58ae20d9a85f2a1508a9a732874239491d456 Mon Sep 17 00:00:00 2001
1485+From: Hank Ibell <hwibell@apache.org>
1486+Date: Tue, 15 Jan 2019 19:54:41 +0000
1487+Subject: [PATCH] mod_session: Always decode session attributes early.
1488+
1489+Backport r1850947 from trunk
1490+Submitted by: hwibell
1491+Reviewed by: hwibell, covener, wrowe
1492+
1493+
1494+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1851409 13f79535-47bb-0310-9956-ffa450edef68
1495+---
1496+ CHANGES | 2 ++
1497+ STATUS | 5 -----
1498+ modules/session/mod_session.c | 25 ++++++++++++++-----------
1499+ 3 files changed, 16 insertions(+), 16 deletions(-)
1500+
1501+#diff --git a/CHANGES b/CHANGES
1502+#index c4d9f6c2ea8..4b0a07fdcf5 100644
1503+#--- a/CHANGES
1504+#+++ b/CHANGES
1505+#@@ -9,6 +9,8 @@ Changes with Apache 2.4.38
1506+# and we should just set the value for the environment variable
1507+# like in the pattern case. [Ruediger Pluem]
1508+#
1509+#+ *) mod_session: Always decode session attributes early. [Hank Ibell]
1510+#+
1511+# *) core: Incorrect values for environment variables are substituted when
1512+# multiple environment variables are specified in a directive. [Hank Ibell]
1513+#
1514+#diff --git a/STATUS b/STATUS
1515+#index 00070f9f247..45a92ba4d81 100644
1516+#--- a/STATUS
1517+#+++ b/STATUS
1518+#@@ -125,11 +125,6 @@ RELEASE SHOWSTOPPERS:
1519+# PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
1520+# [ start all new proposals below, under PATCHES PROPOSED. ]
1521+#
1522+#- *) mod_session: Always decode session attributes early.
1523+#- trunk patch: http://svn.apache.org/r1850947
1524+#- 2.4.x patch: svn merge -c 1850947 ^/httpd/httpd/trunk .
1525+#- +1: hwibell, covener, wrowe
1526+#-
1527+# *) mod_ssl (ssl_engine_io.c: bio_filter_out_write, bio_filter_in_read)
1528+# Clear retry flags before aborting on client-initiated reneg. [Joe Orton]
1529+# PR: 63052
1530+diff --git a/modules/session/mod_session.c b/modules/session/mod_session.c
1531+index d517020d995..64e6e4a8132 100644
1532+--- a/modules/session/mod_session.c
1533++++ b/modules/session/mod_session.c
1534+@@ -126,20 +126,23 @@ static apr_status_t ap_session_load(request_rec * r, session_rec ** z)
1535+
1536+ /* found a session that hasn't expired? */
1537+ now = apr_time_now();
1538++
1539+ if (zz) {
1540+- if (zz->expiry && zz->expiry < now) {
1541++ /* load the session attibutes */
1542++ rv = ap_run_session_decode(r, zz);
1543++
1544++ /* having a session we cannot decode is just as good as having
1545++ none at all */
1546++ if (OK != rv) {
1547++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01817)
1548++ "error while decoding the session, "
1549++ "session not loaded: %s", r->uri);
1550+ zz = NULL;
1551+ }
1552+- else {
1553+- /* having a session we cannot decode is just as good as having
1554+- none at all */
1555+- rv = ap_run_session_decode(r, zz);
1556+- if (OK != rv) {
1557+- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01817)
1558+- "error while decoding the session, "
1559+- "session not loaded: %s", r->uri);
1560+- zz = NULL;
1561+- }
1562++
1563++ /* invalidate session if session is expired */
1564++ if (zz && zz->expiry && zz->expiry < now) {
1565++ zz = NULL;
1566+ }
1567+ }
1568+
1569diff --git a/debian/patches/CVE-2019-0211.patch b/debian/patches/CVE-2019-0211.patch
1570new file mode 100644
1571index 0000000..be70aac
1572--- /dev/null
1573+++ b/debian/patches/CVE-2019-0211.patch
1574@@ -0,0 +1,249 @@
1575+From df7edb5ddae609ea1fd4285f7439f0d590d97b37 Mon Sep 17 00:00:00 2001
1576+From: Yann Ylavic <ylavic@apache.org>
1577+Date: Wed, 13 Mar 2019 08:59:54 +0000
1578+Subject: [PATCH] Merge r1855306 from trunk:
1579+
1580+MPMs unix: bind the bucket number of each child to its slot number
1581+
1582+We need not remember each child's bucket number in SHM for restarts, for the
1583+lifetime of the httpd main process the bucket number can be bound to the slot
1584+number such that: bucket = slot % num_buckets.
1585+
1586+This both simplifies the logic and helps children maintenance per bucket in
1587+threaded MPMs, where previously perform_idle_server_maintenance() could create
1588+or kill children processes for the buckets it was not in charge of.
1589+
1590+Submitted by: ylavic
1591+Reviewed by: ylavic, rpluem, jorton
1592+
1593+
1594+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855378 13f79535-47bb-0310-9956-ffa450edef68
1595+---
1596+ CHANGES | 3 +++
1597+ include/scoreboard.h | 4 +++-
1598+ server/mpm/event/event.c | 13 ++++++++-----
1599+ server/mpm/prefork/prefork.c | 19 +++++++------------
1600+ server/mpm/worker/worker.c | 10 ++++++----
1601+ 5 files changed, 27 insertions(+), 22 deletions(-)
1602+
1603+#diff --git a/CHANGES b/CHANGES
1604+#index e79251389d5..6b560802119 100644
1605+#--- a/CHANGES
1606+#+++ b/CHANGES
1607+#@@ -1,6 +1,9 @@
1608+# -*- coding: utf-8 -*-
1609+# Changes with Apache 2.4.39
1610+#
1611+#+ *) MPMs unix: bind the bucket number of each child to its slot number, for a
1612+#+ more efficient per bucket maintenance. [Yann Ylavic]
1613+#+
1614+# *) mod_auth_digest: Fix a race condition. Authentication with valid
1615+# credentials could be refused in case of concurrent accesses from
1616+# different users. PR 63124. [Simon Kappel <simon.kappel axis.com>]
1617+Index: apache2-2.4.29/include/scoreboard.h
1618+===================================================================
1619+--- apache2-2.4.29.orig/include/scoreboard.h 2019-04-03 09:22:04.140590533 -0400
1620++++ apache2-2.4.29/include/scoreboard.h 2019-04-03 09:22:04.140590533 -0400
1621+@@ -143,7 +143,9 @@ struct process_score {
1622+ apr_uint32_t lingering_close; /* async connections in lingering close */
1623+ apr_uint32_t keep_alive; /* async connections in keep alive */
1624+ apr_uint32_t suspended; /* connections suspended by some module */
1625+- int bucket; /* Listener bucket used by this child */
1626++ int bucket; /* Listener bucket used by this child; this field is DEPRECATED
1627++ * and no longer updated by the MPMs (i.e. always zero).
1628++ */
1629+ };
1630+
1631+ /* Scoreboard is now in 'local' memory, since it isn't updated once created,
1632+Index: apache2-2.4.29/server/mpm/event/event.c
1633+===================================================================
1634+--- apache2-2.4.29.orig/server/mpm/event/event.c 2019-04-03 09:22:04.140590533 -0400
1635++++ apache2-2.4.29/server/mpm/event/event.c 2019-04-03 09:22:04.140590533 -0400
1636+@@ -2553,7 +2553,6 @@ static int make_child(server_rec * s, in
1637+
1638+ ap_scoreboard_image->parent[slot].quiescing = 0;
1639+ ap_scoreboard_image->parent[slot].not_accepting = 0;
1640+- ap_scoreboard_image->parent[slot].bucket = bucket;
1641+ event_note_child_started(slot, pid);
1642+ active_daemons++;
1643+ retained->total_daemons++;
1644+@@ -2592,6 +2591,7 @@ static void perform_idle_server_maintena
1645+ * that threads_per_child is always > 0 */
1646+ int status = SERVER_DEAD;
1647+ int child_threads_active = 0;
1648++ int bucket = i % num_buckets;
1649+
1650+ if (i >= retained->max_daemons_limit &&
1651+ free_length == retained->idle_spawn_rate[child_bucket]) {
1652+@@ -2615,7 +2615,7 @@ static void perform_idle_server_maintena
1653+ */
1654+ if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
1655+ && ps->generation == retained->mpm->my_generation
1656+- && ps->bucket == child_bucket)
1657++ && bucket == child_bucket)
1658+ {
1659+ ++idle_thread_count;
1660+ }
1661+@@ -2626,7 +2626,9 @@ static void perform_idle_server_maintena
1662+ last_non_dead = i;
1663+ }
1664+ active_thread_count += child_threads_active;
1665+- if (!ps->pid && free_length < retained->idle_spawn_rate[child_bucket])
1666++ if (!ps->pid
1667++ && bucket == child_bucket
1668++ && free_length < retained->idle_spawn_rate[child_bucket])
1669+ free_slots[free_length++] = i;
1670+ else if (child_threads_active == threads_per_child)
1671+ had_healthy_child = 1;
1672+@@ -2809,13 +2811,14 @@ static void server_main_loop(int remaini
1673+ retained->total_daemons--;
1674+ if (processed_status == APEXIT_CHILDSICK) {
1675+ /* resource shortage, minimize the fork rate */
1676+- retained->idle_spawn_rate[ps->bucket] = 1;
1677++ retained->idle_spawn_rate[child_slot % num_buckets] = 1;
1678+ }
1679+ else if (remaining_children_to_start) {
1680+ /* we're still doing a 1-for-1 replacement of dead
1681+ * children with new children
1682+ */
1683+- make_child(ap_server_conf, child_slot, ps->bucket);
1684++ make_child(ap_server_conf, child_slot,
1685++ child_slot % num_buckets);
1686+ --remaining_children_to_start;
1687+ }
1688+ }
1689+Index: apache2-2.4.29/server/mpm/prefork/prefork.c
1690+===================================================================
1691+--- apache2-2.4.29.orig/server/mpm/prefork/prefork.c 2019-04-03 09:22:04.140590533 -0400
1692++++ apache2-2.4.29/server/mpm/prefork/prefork.c 2019-04-03 09:22:04.140590533 -0400
1693+@@ -637,8 +637,9 @@ static void child_main(int child_num_arg
1694+ }
1695+
1696+
1697+-static int make_child(server_rec *s, int slot, int bucket)
1698++static int make_child(server_rec *s, int slot)
1699+ {
1700++ int bucket = slot % retained->mpm->num_buckets;
1701+ int pid;
1702+
1703+ if (slot + 1 > retained->max_daemons_limit) {
1704+@@ -716,7 +717,6 @@ static int make_child(server_rec *s, int
1705+ child_main(slot, bucket);
1706+ }
1707+
1708+- ap_scoreboard_image->parent[slot].bucket = bucket;
1709+ prefork_note_child_started(slot, pid);
1710+
1711+ return 0;
1712+@@ -732,7 +732,7 @@ static void startup_children(int number_
1713+ if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
1714+ continue;
1715+ }
1716+- if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) {
1717++ if (make_child(ap_server_conf, i) < 0) {
1718+ break;
1719+ }
1720+ --number_to_start;
1721+@@ -741,8 +741,6 @@ static void startup_children(int number_
1722+
1723+ static void perform_idle_server_maintenance(apr_pool_t *p)
1724+ {
1725+- static int bucket_make_child_record = -1;
1726+- static int bucket_kill_child_record = -1;
1727+ int i;
1728+ int idle_count;
1729+ worker_score *ws;
1730+@@ -789,6 +787,7 @@ static void perform_idle_server_maintena
1731+ }
1732+ retained->max_daemons_limit = last_non_dead + 1;
1733+ if (idle_count > ap_daemons_max_free) {
1734++ static int bucket_kill_child_record = -1;
1735+ /* kill off one child... we use the pod because that'll cause it to
1736+ * shut down gracefully, in case it happened to pick up a request
1737+ * while we were counting
1738+@@ -819,10 +818,7 @@ static void perform_idle_server_maintena
1739+ idle_count, total_non_dead);
1740+ }
1741+ for (i = 0; i < free_length; ++i) {
1742+- bucket_make_child_record++;
1743+- bucket_make_child_record %= retained->mpm->num_buckets;
1744+- make_child(ap_server_conf, free_slots[i],
1745+- bucket_make_child_record);
1746++ make_child(ap_server_conf, free_slots[i]);
1747+ }
1748+ /* the next time around we want to spawn twice as many if this
1749+ * wasn't good enough, but not if we've just done a graceful
1750+@@ -867,7 +863,7 @@ static int prefork_run(apr_pool_t *_pcon
1751+
1752+ if (one_process) {
1753+ AP_MONCONTROL(1);
1754+- make_child(ap_server_conf, 0, 0);
1755++ make_child(ap_server_conf, 0);
1756+ /* NOTREACHED */
1757+ ap_assert(0);
1758+ return !OK;
1759+@@ -976,8 +972,7 @@ static int prefork_run(apr_pool_t *_pcon
1760+ /* we're still doing a 1-for-1 replacement of dead
1761+ * children with new children
1762+ */
1763+- make_child(ap_server_conf, child_slot,
1764+- ap_get_scoreboard_process(child_slot)->bucket);
1765++ make_child(ap_server_conf, child_slot);
1766+ --remaining_children_to_start;
1767+ }
1768+ #if APR_HAS_OTHER_CHILD
1769+Index: apache2-2.4.29/server/mpm/worker/worker.c
1770+===================================================================
1771+--- apache2-2.4.29.orig/server/mpm/worker/worker.c 2019-04-03 09:22:04.140590533 -0400
1772++++ apache2-2.4.29/server/mpm/worker/worker.c 2019-04-03 09:22:04.140590533 -0400
1773+@@ -1312,7 +1312,6 @@ static int make_child(server_rec *s, int
1774+ worker_note_child_lost_slot(slot, pid);
1775+ }
1776+ ap_scoreboard_image->parent[slot].quiescing = 0;
1777+- ap_scoreboard_image->parent[slot].bucket = bucket;
1778+ worker_note_child_started(slot, pid);
1779+ return 0;
1780+ }
1781+@@ -1361,6 +1360,7 @@ static void perform_idle_server_maintena
1782+ int any_dead_threads = 0;
1783+ int all_dead_threads = 1;
1784+ int child_threads_active = 0;
1785++ int bucket = i % num_buckets;
1786+
1787+ if (i >= retained->max_daemons_limit &&
1788+ totally_free_length == retained->idle_spawn_rate[child_bucket]) {
1789+@@ -1393,7 +1393,7 @@ static void perform_idle_server_maintena
1790+ if (status <= SERVER_READY &&
1791+ !ps->quiescing &&
1792+ ps->generation == retained->mpm->my_generation &&
1793+- ps->bucket == child_bucket) {
1794++ bucket == child_bucket) {
1795+ ++idle_thread_count;
1796+ }
1797+ if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
1798+@@ -1403,6 +1403,7 @@ static void perform_idle_server_maintena
1799+ }
1800+ active_thread_count += child_threads_active;
1801+ if (any_dead_threads
1802++ && bucket == child_bucket
1803+ && totally_free_length < retained->idle_spawn_rate[child_bucket]
1804+ && free_length < MAX_SPAWN_RATE / num_buckets
1805+ && (!ps->pid /* no process in the slot */
1806+@@ -1588,14 +1589,15 @@ static void server_main_loop(int remaini
1807+ ps->quiescing = 0;
1808+ if (processed_status == APEXIT_CHILDSICK) {
1809+ /* resource shortage, minimize the fork rate */
1810+- retained->idle_spawn_rate[ps->bucket] = 1;
1811++ retained->idle_spawn_rate[child_slot % num_buckets] = 1;
1812+ }
1813+ else if (remaining_children_to_start
1814+ && child_slot < ap_daemons_limit) {
1815+ /* we're still doing a 1-for-1 replacement of dead
1816+ * children with new children
1817+ */
1818+- make_child(ap_server_conf, child_slot, ps->bucket);
1819++ make_child(ap_server_conf, child_slot,
1820++ child_slot % num_buckets);
1821+ --remaining_children_to_start;
1822+ }
1823+ }
1824diff --git a/debian/patches/CVE-2019-0217.patch b/debian/patches/CVE-2019-0217.patch
1825new file mode 100644
1826index 0000000..e8f1090
1827--- /dev/null
1828+++ b/debian/patches/CVE-2019-0217.patch
1829@@ -0,0 +1,147 @@
1830+From 44b3ddc560c490c60600998fa2bf59b142d08e05 Mon Sep 17 00:00:00 2001
1831+From: Joe Orton <jorton@apache.org>
1832+Date: Tue, 12 Mar 2019 09:24:26 +0000
1833+Subject: [PATCH] Merge r1853190 from trunk:
1834+
1835+Fix a race condition. Authentication with valid credentials could be
1836+refused in case of concurrent accesses from different users.
1837+
1838+PR: 63124
1839+Submitted by: Simon Kappel <simon.kappel axis.com>
1840+Reviewed by: jailletc36, icing, jorton
1841+
1842+
1843+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855298 13f79535-47bb-0310-9956-ffa450edef68
1844+---
1845+ CHANGES | 4 ++++
1846+ modules/aaa/mod_auth_digest.c | 26 ++++++++++++--------------
1847+ 2 files changed, 16 insertions(+), 14 deletions(-)
1848+
1849+#diff --git a/CHANGES b/CHANGES
1850+#index 08fc740db30..e79251389d5 100644
1851+#--- a/CHANGES
1852+#+++ b/CHANGES
1853+#@@ -1,6 +1,10 @@
1854+# -*- coding: utf-8 -*-
1855+# Changes with Apache 2.4.39
1856+#
1857+#+ *) mod_auth_digest: Fix a race condition. Authentication with valid
1858+#+ credentials could be refused in case of concurrent accesses from
1859+#+ different users. PR 63124. [Simon Kappel <simon.kappel axis.com>]
1860+#+
1861+# *) mod_proxy_wstunnel: Fix websocket proxy over UDS.
1862+# PR 62932 <pavel dcmsys.com>
1863+#
1864+diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c
1865+index a67f06986f2..b76094114dd 100644
1866+--- a/modules/aaa/mod_auth_digest.c
1867++++ b/modules/aaa/mod_auth_digest.c
1868+@@ -92,7 +92,6 @@ typedef struct digest_config_struct {
1869+ int check_nc;
1870+ const char *algorithm;
1871+ char *uri_list;
1872+- const char *ha1;
1873+ } digest_config_rec;
1874+
1875+
1876+@@ -153,6 +152,7 @@ typedef struct digest_header_struct {
1877+ apr_time_t nonce_time;
1878+ enum hdr_sts auth_hdr_sts;
1879+ int needed_auth;
1880++ const char *ha1;
1881+ client_entry *client;
1882+ } digest_header_rec;
1883+
1884+@@ -1304,7 +1304,7 @@ static int hook_note_digest_auth_failure(request_rec *r, const char *auth_type)
1885+ */
1886+
1887+ static authn_status get_hash(request_rec *r, const char *user,
1888+- digest_config_rec *conf)
1889++ digest_config_rec *conf, const char **rethash)
1890+ {
1891+ authn_status auth_result;
1892+ char *password;
1893+@@ -1356,7 +1356,7 @@ static authn_status get_hash(request_rec *r, const char *user,
1894+ } while (current_provider);
1895+
1896+ if (auth_result == AUTH_USER_FOUND) {
1897+- conf->ha1 = password;
1898++ *rethash = password;
1899+ }
1900+
1901+ return auth_result;
1902+@@ -1483,25 +1483,24 @@ static int check_nonce(request_rec *r, digest_header_rec *resp,
1903+
1904+ /* RFC-2069 */
1905+ static const char *old_digest(const request_rec *r,
1906+- const digest_header_rec *resp, const char *ha1)
1907++ const digest_header_rec *resp)
1908+ {
1909+ const char *ha2;
1910+
1911+ ha2 = ap_md5(r->pool, (unsigned char *)apr_pstrcat(r->pool, resp->method, ":",
1912+ resp->uri, NULL));
1913+ return ap_md5(r->pool,
1914+- (unsigned char *)apr_pstrcat(r->pool, ha1, ":", resp->nonce,
1915+- ":", ha2, NULL));
1916++ (unsigned char *)apr_pstrcat(r->pool, resp->ha1, ":",
1917++ resp->nonce, ":", ha2, NULL));
1918+ }
1919+
1920+ /* RFC-2617 */
1921+ static const char *new_digest(const request_rec *r,
1922+- digest_header_rec *resp,
1923+- const digest_config_rec *conf)
1924++ digest_header_rec *resp)
1925+ {
1926+ const char *ha1, *ha2, *a2;
1927+
1928+- ha1 = conf->ha1;
1929++ ha1 = resp->ha1;
1930+
1931+ a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL);
1932+ ha2 = ap_md5(r->pool, (const unsigned char *)a2);
1933+@@ -1514,7 +1513,6 @@ static const char *new_digest(const request_rec *r,
1934+ NULL));
1935+ }
1936+
1937+-
1938+ static void copy_uri_components(apr_uri_t *dst,
1939+ apr_uri_t *src, request_rec *r) {
1940+ if (src->scheme && src->scheme[0] != '\0') {
1941+@@ -1759,7 +1757,7 @@ static int authenticate_digest_user(request_rec *r)
1942+ return HTTP_UNAUTHORIZED;
1943+ }
1944+
1945+- return_code = get_hash(r, r->user, conf);
1946++ return_code = get_hash(r, r->user, conf, &resp->ha1);
1947+
1948+ if (return_code == AUTH_USER_NOT_FOUND) {
1949+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01790)
1950+@@ -1789,7 +1787,7 @@ static int authenticate_digest_user(request_rec *r)
1951+
1952+ if (resp->message_qop == NULL) {
1953+ /* old (rfc-2069) style digest */
1954+- if (strcmp(resp->digest, old_digest(r, resp, conf->ha1))) {
1955++ if (strcmp(resp->digest, old_digest(r, resp))) {
1956+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01792)
1957+ "user %s: password mismatch: %s", r->user,
1958+ r->uri);
1959+@@ -1819,7 +1817,7 @@ static int authenticate_digest_user(request_rec *r)
1960+ return HTTP_UNAUTHORIZED;
1961+ }
1962+
1963+- exp_digest = new_digest(r, resp, conf);
1964++ exp_digest = new_digest(r, resp);
1965+ if (!exp_digest) {
1966+ /* we failed to allocate a client struct */
1967+ return HTTP_INTERNAL_SERVER_ERROR;
1968+@@ -1903,7 +1901,7 @@ static int add_auth_info(request_rec *r)
1969+
1970+ /* calculate rspauth attribute
1971+ */
1972+- ha1 = conf->ha1;
1973++ ha1 = resp->ha1;
1974+
1975+ a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL);
1976+ ha2 = ap_md5(r->pool, (const unsigned char *)a2);
1977diff --git a/debian/patches/CVE-2019-0220-1.patch b/debian/patches/CVE-2019-0220-1.patch
1978new file mode 100644
1979index 0000000..86cc667
1980--- /dev/null
1981+++ b/debian/patches/CVE-2019-0220-1.patch
1982@@ -0,0 +1,259 @@
1983+Backport of:
1984+
1985+From 9bc1917a27a2323e535aadb081e38172ae0e3fc2 Mon Sep 17 00:00:00 2001
1986+From: Stefan Eissing <icing@apache.org>
1987+Date: Mon, 18 Mar 2019 08:49:59 +0000
1988+Subject: [PATCH] Merge of r1855705 from trunk:
1989+
1990+core: merge consecutive slashes in the path
1991+
1992+
1993+
1994+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855737 13f79535-47bb-0310-9956-ffa450edef68
1995+---
1996+ CHANGES | 4 ++++
1997+ docs/manual/mod/core.xml | 26 ++++++++++++++++++++++++++
1998+ include/ap_mmn.h | 4 +++-
1999+ include/http_core.h | 2 +-
2000+ include/httpd.h | 14 ++++++++++++--
2001+ server/core.c | 13 +++++++++++++
2002+ server/request.c | 25 +++++++++----------------
2003+ server/util.c | 10 +++++++---
2004+ 8 files changed, 75 insertions(+), 23 deletions(-)
2005+
2006+#diff --git a/CHANGES b/CHANGES
2007+#index e3e8a98db24..9dd7045c232 100644
2008+#--- a/CHANGES
2009+#+++ b/CHANGES
2010+#@@ -1,6 +1,10 @@
2011+# -*- coding: utf-8 -*-
2012+# Changes with Apache 2.4.39
2013+#
2014+#+ *) core: new configuration option 'MergeSlashes on|off' that controls handling of
2015+#+ multiple, consecutive slash ('/') characters in the path component of the request URL.
2016+#+ [Eric Covener]
2017+#+
2018+# *) mod_http2: when SSL renegotiation is inhibited and a 403 ErrorDocument is
2019+# in play, the proper HTTP/2 stream reset did not trigger with H2_ERR_HTTP_1_1_REQUIRED.
2020+# Fixed. [Michael Kaufmann]
2021+#diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml
2022+#index fc664116727..460b4367621 100644
2023+#--- a/docs/manual/mod/core.xml
2024+#+++ b/docs/manual/mod/core.xml
2025+#@@ -5138,4 +5138,30 @@ recognized methods to modules.</p>
2026+# <seealso><directive module="mod_allowmethods">AllowMethods</directive></seealso>
2027+# </directivesynopsis>
2028+#
2029+#+<directivesynopsis>
2030+#+<name>MergeSlashes</name>
2031+#+<description>Controls whether the server merges consecutive slashes in URLs.
2032+#+</description>
2033+#+<syntax>MergeSlashes ON|OFF</syntax>
2034+#+<default>MergeSlashes ON</default>
2035+#+<contextlist><context>server config</context><context>virtual host</context>
2036+#+</contextlist>
2037+#+<compatibility>Added in 2.5.1</compatibility>
2038+#+
2039+#+<usage>
2040+#+ <p>By default, the server merges (or collapses) multiple consecutive slash
2041+#+ ('/') characters in the path component of the request URL.</p>
2042+#+
2043+#+ <p>When mapping URL's to the filesystem, these multiple slashes are not
2044+#+ significant. However, URL's handled other ways, such as by CGI or proxy,
2045+#+ might prefer to retain the significance of multiple consecutive slashes.
2046+#+ In these cases <directive>MergeSlashes</directive> can be set to
2047+#+ <em>OFF</em> to retain the multiple consecutive slashes. In these
2048+#+ configurations, regular expressions used in the configuration file that match
2049+#+ the path component of the URL (<directive>LocationMatch</directive>,
2050+#+ <directive>RewriteRule</directive>, ...) need to take into account multiple
2051+#+ consecutive slashes.</p>
2052+#+</usage>
2053+#+</directivesynopsis>
2054+#+
2055+# </modulesynopsis>
2056+Index: apache2-2.4.29/include/http_core.h
2057+===================================================================
2058+--- apache2-2.4.29.orig/include/http_core.h 2019-04-03 09:22:24.452651658 -0400
2059++++ apache2-2.4.29/include/http_core.h 2019-04-03 09:22:24.448651645 -0400
2060+@@ -740,7 +740,7 @@ typedef struct {
2061+ #define AP_HTTP_METHODS_LENIENT 1
2062+ #define AP_HTTP_METHODS_REGISTERED 2
2063+ char http_methods;
2064+-
2065++ unsigned int merge_slashes;
2066+ } core_server_config;
2067+
2068+ /* for AddOutputFiltersByType in core.c */
2069+Index: apache2-2.4.29/include/httpd.h
2070+===================================================================
2071+--- apache2-2.4.29.orig/include/httpd.h 2019-04-03 09:22:24.452651658 -0400
2072++++ apache2-2.4.29/include/httpd.h 2019-04-03 09:22:24.448651645 -0400
2073+@@ -1691,12 +1691,22 @@ AP_DECLARE(int) ap_unescape_url_keep2f(c
2074+ AP_DECLARE(int) ap_unescape_urlencoded(char *query);
2075+
2076+ /**
2077+- * Convert all double slashes to single slashes
2078+- * @param name The string to convert
2079++ * Convert all double slashes to single slashes, except where significant
2080++ * to the filesystem on the current platform.
2081++ * @param name The string to convert, assumed to be a filesystem path
2082+ */
2083+ AP_DECLARE(void) ap_no2slash(char *name);
2084+
2085+ /**
2086++ * Convert all double slashes to single slashes, except where significant
2087++ * to the filesystem on the current platform.
2088++ * @param name The string to convert
2089++ * @param is_fs_path if set to 0, the significance of any double-slashes is
2090++ * ignored.
2091++ */
2092++AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path);
2093++
2094++/**
2095+ * Remove all ./ and xx/../ substrings from a file name. Also remove
2096+ * any leading ../ or /../ substrings.
2097+ * @param name the file name to parse
2098+Index: apache2-2.4.29/server/core.c
2099+===================================================================
2100+--- apache2-2.4.29.orig/server/core.c 2019-04-03 09:22:24.452651658 -0400
2101++++ apache2-2.4.29/server/core.c 2019-04-03 09:22:24.448651645 -0400
2102+@@ -490,6 +490,7 @@ static void *create_core_server_config(a
2103+
2104+ conf->protocols = apr_array_make(a, 5, sizeof(const char *));
2105+ conf->protocols_honor_order = -1;
2106++ conf->merge_slashes = AP_CORE_CONFIG_UNSET;
2107+
2108+ return (void *)conf;
2109+ }
2110+@@ -555,6 +556,7 @@ static void *merge_core_server_configs(a
2111+ conf->protocols_honor_order = ((virt->protocols_honor_order < 0)?
2112+ base->protocols_honor_order :
2113+ virt->protocols_honor_order);
2114++ AP_CORE_MERGE_FLAG(merge_slashes, conf, base, virt);
2115+
2116+ return conf;
2117+ }
2118+@@ -1862,6 +1864,13 @@ static const char *set_qualify_redirect_
2119+ return NULL;
2120+ }
2121+
2122++static const char *set_core_server_flag(cmd_parms *cmd, void *s_, int flag)
2123++{
2124++ core_server_config *conf =
2125++ ap_get_core_module_config(cmd->server->module_config);
2126++ return ap_set_flag_slot(cmd, conf, flag);
2127++}
2128++
2129+ static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *const argv[])
2130+ {
2131+ core_dir_config *d = d_;
2132+@@ -4551,6 +4560,10 @@ AP_INIT_ITERATE("HttpProtocolOptions", s
2133+ "'Unsafe' or 'Strict' (default). Sets HTTP acceptance rules"),
2134+ AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF,
2135+ "Registers non-standard HTTP methods"),
2136++AP_INIT_FLAG("MergeSlashes", set_core_server_flag,
2137++ (void *)APR_OFFSETOF(core_server_config, merge_slashes),
2138++ RSRC_CONF,
2139++ "Controls whether consecutive slashes in the URI path are merged"),
2140+ { NULL }
2141+ };
2142+
2143+Index: apache2-2.4.29/server/request.c
2144+===================================================================
2145+--- apache2-2.4.29.orig/server/request.c 2019-04-03 09:22:24.452651658 -0400
2146++++ apache2-2.4.29/server/request.c 2019-04-03 09:22:24.448651645 -0400
2147+@@ -167,6 +167,8 @@ AP_DECLARE(int) ap_process_request_inter
2148+ int file_req = (r->main && r->filename);
2149+ int access_status;
2150+ core_dir_config *d;
2151++ core_server_config *sconf =
2152++ ap_get_core_module_config(r->server->module_config);
2153+
2154+ /* Ignore embedded %2F's in path for proxy requests */
2155+ if (!r->proxyreq && r->parsed_uri.path) {
2156+@@ -191,6 +193,10 @@ AP_DECLARE(int) ap_process_request_inter
2157+ }
2158+
2159+ ap_getparents(r->uri); /* OK --- shrinking transformations... */
2160++ if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) {
2161++ ap_no2slash(r->uri);
2162++ ap_no2slash(r->parsed_uri.path);
2163++ }
2164+
2165+ /* All file subrequests are a huge pain... they cannot bubble through the
2166+ * next several steps. Only file subrequests are allowed an empty uri,
2167+@@ -1411,20 +1417,7 @@ AP_DECLARE(int) ap_location_walk(request
2168+
2169+ cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r);
2170+ cached = (cache->cached != NULL);
2171+-
2172+- /* Location and LocationMatch differ on their behaviour w.r.t. multiple
2173+- * slashes. Location matches multiple slashes with a single slash,
2174+- * LocationMatch doesn't. An exception, for backwards brokenness is
2175+- * absoluteURIs... in which case neither match multiple slashes.
2176+- */
2177+- if (r->uri[0] != '/') {
2178+- entry_uri = r->uri;
2179+- }
2180+- else {
2181+- char *uri = apr_pstrdup(r->pool, r->uri);
2182+- ap_no2slash(uri);
2183+- entry_uri = uri;
2184+- }
2185++ entry_uri = r->uri;
2186+
2187+ /* If we have an cache->cached location that matches r->uri,
2188+ * and the vhost's list of locations hasn't changed, we can skip
2189+@@ -1491,7 +1484,7 @@ AP_DECLARE(int) ap_location_walk(request
2190+ pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
2191+ }
2192+
2193+- if (ap_regexec(entry_core->r, r->uri, nmatch, pmatch, 0)) {
2194++ if (ap_regexec(entry_core->r, entry_uri, nmatch, pmatch, 0)) {
2195+ continue;
2196+ }
2197+
2198+@@ -1501,7 +1494,7 @@ AP_DECLARE(int) ap_location_walk(request
2199+ apr_table_setn(r->subprocess_env,
2200+ ((const char **)entry_core->refs->elts)[i],
2201+ apr_pstrndup(r->pool,
2202+- r->uri + pmatch[i].rm_so,
2203++ entry_uri + pmatch[i].rm_so,
2204+ pmatch[i].rm_eo - pmatch[i].rm_so));
2205+ }
2206+ }
2207+Index: apache2-2.4.29/server/util.c
2208+===================================================================
2209+--- apache2-2.4.29.orig/server/util.c 2019-04-03 09:22:24.452651658 -0400
2210++++ apache2-2.4.29/server/util.c 2019-04-03 09:22:24.448651645 -0400
2211+@@ -561,16 +561,16 @@ AP_DECLARE(void) ap_getparents(char *nam
2212+ name[l] = '\0';
2213+ }
2214+ }
2215+-
2216+-AP_DECLARE(void) ap_no2slash(char *name)
2217++AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path)
2218+ {
2219++
2220+ char *d, *s;
2221+
2222+ s = d = name;
2223+
2224+ #ifdef HAVE_UNC_PATHS
2225+ /* Check for UNC names. Leave leading two slashes. */
2226+- if (s[0] == '/' && s[1] == '/')
2227++ if (is_fs_path && s[0] == '/' && s[1] == '/')
2228+ *d++ = *s++;
2229+ #endif
2230+
2231+@@ -587,6 +587,10 @@ AP_DECLARE(void) ap_no2slash(char *name)
2232+ *d = '\0';
2233+ }
2234+
2235++AP_DECLARE(void) ap_no2slash(char *name)
2236++{
2237++ ap_no2slash_ex(name, 1);
2238++}
2239+
2240+ /*
2241+ * copy at most n leading directories of s into d
2242diff --git a/debian/patches/CVE-2019-0220-2.patch b/debian/patches/CVE-2019-0220-2.patch
2243new file mode 100644
2244index 0000000..0204259
2245--- /dev/null
2246+++ b/debian/patches/CVE-2019-0220-2.patch
2247@@ -0,0 +1,50 @@
2248+From c4ef468b25718a26f2b92cbea3ca093729b79331 Mon Sep 17 00:00:00 2001
2249+From: Eric Covener <covener@apache.org>
2250+Date: Mon, 18 Mar 2019 12:10:15 +0000
2251+Subject: [PATCH] merge 1855743,1855744 ^/httpd/httpd/trunk .
2252+
2253+r->parsed_uri.path safety in recent backport
2254+
2255+*) core: fix SEGFAULT in CONNECT with recent change
2256+ 2.4.x: svn merge -c 1855743,1855744 ^/httpd/httpd/trunk .
2257+ +1: rpluem, icing, covener
2258+
2259+
2260+
2261+
2262+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855751 13f79535-47bb-0310-9956-ffa450edef68
2263+---
2264+ server/request.c | 4 +++-
2265+ server/util.c | 4 ++++
2266+ 2 files changed, 7 insertions(+), 1 deletion(-)
2267+
2268+diff --git a/server/request.c b/server/request.c
2269+index 1ce8908824b..d5c558afa30 100644
2270+--- a/server/request.c
2271++++ b/server/request.c
2272+@@ -195,7 +195,9 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r)
2273+ ap_getparents(r->uri); /* OK --- shrinking transformations... */
2274+ if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) {
2275+ ap_no2slash(r->uri);
2276+- ap_no2slash(r->parsed_uri.path);
2277++ if (r->parsed_uri.path) {
2278++ ap_no2slash(r->parsed_uri.path);
2279++ }
2280+ }
2281+
2282+ /* All file subrequests are a huge pain... they cannot bubble through the
2283+diff --git a/server/util.c b/server/util.c
2284+index 607c4850d86..f3b17f1581e 100644
2285+--- a/server/util.c
2286++++ b/server/util.c
2287+@@ -566,6 +566,10 @@ AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path)
2288+
2289+ char *d, *s;
2290+
2291++ if (!name || !*name) {
2292++ return;
2293++ }
2294++
2295+ s = d = name;
2296+
2297+ #ifdef HAVE_UNC_PATHS
2298diff --git a/debian/patches/CVE-2019-0220-3.patch b/debian/patches/CVE-2019-0220-3.patch
2299new file mode 100644
2300index 0000000..7b3ff6f
2301--- /dev/null
2302+++ b/debian/patches/CVE-2019-0220-3.patch
2303@@ -0,0 +1,43 @@
2304+From 3451fc2bf8708b0dc8cd6a7d0ac0fe5b6401befc Mon Sep 17 00:00:00 2001
2305+From: Eric Covener <covener@apache.org>
2306+Date: Tue, 19 Mar 2019 18:01:21 +0000
2307+Subject: [PATCH] *) maintainer mode fix for util.c no2slash_ex trunk
2308+ patch: http://svn.apache.org/r1855755 2.4.x patch svn merge -c 1855755
2309+ ^/httpd/httpd/trunk . +1: covener, rpluem, jim, ylavic
2310+
2311+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855853 13f79535-47bb-0310-9956-ffa450edef68
2312+---
2313+ STATUS | 6 ------
2314+ server/util.c | 2 +-
2315+ 2 files changed, 1 insertion(+), 7 deletions(-)
2316+
2317+#diff --git a/STATUS b/STATUS
2318+#index ffe5d22550c..1f8cb2f7884 100644
2319+#--- a/STATUS
2320+#+++ b/STATUS
2321+#@@ -126,12 +126,6 @@ RELEASE SHOWSTOPPERS:
2322+# PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
2323+# [ start all new proposals below, under PATCHES PROPOSED. ]
2324+#
2325+#- *) maintainer mode fix for util.c no2slash_ex
2326+#- trunk patch: http://svn.apache.org/r1855755
2327+#- 2.4.x patch svn merge -c 1855755 ^/httpd/httpd/trunk .
2328+#- +1: covener, rpluem, jim, ylavic
2329+#-
2330+#-
2331+# PATCHES PROPOSED TO BACKPORT FROM TRUNK:
2332+# [ New proposals should be added at the end of the list ]
2333+#
2334+diff --git a/server/util.c b/server/util.c
2335+index f3b17f1581e..e0c558cee2d 100644
2336+--- a/server/util.c
2337++++ b/server/util.c
2338+@@ -566,7 +566,7 @@ AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path)
2339+
2340+ char *d, *s;
2341+
2342+- if (!name || !*name) {
2343++ if (!*name) {
2344+ return;
2345+ }
2346+
2347diff --git a/debian/patches/CVE-2019-10092-1.patch b/debian/patches/CVE-2019-10092-1.patch
2348new file mode 100644
2349index 0000000..102b18e
2350--- /dev/null
2351+++ b/debian/patches/CVE-2019-10092-1.patch
2352@@ -0,0 +1,245 @@
2353+From b5aa97e7c9792ba31055507eaf9a54e1fbb17464 Mon Sep 17 00:00:00 2001
2354+From: Stefan Eissing <icing@apache.org>
2355+Date: Fri, 2 Aug 2019 09:10:06 +0000
2356+Subject: [PATCH] Merge of r1864191 from trunk:
2357+
2358+ *) core, proxy: remove request URL and headers from error docs
2359+ [Eric Covener]
2360+
2361+
2362+
2363+
2364+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1864207 13f79535-47bb-0310-9956-ffa450edef68
2365+---
2366+ CHANGES | 2 +
2367+ STATUS | 5 --
2368+ modules/http/http_protocol.c | 86 +++++++++++------------------------
2369+ modules/proxy/mod_proxy.c | 7 +--
2370+ modules/proxy/mod_proxy_ftp.c | 5 +-
2371+ modules/proxy/proxy_util.c | 5 +-
2372+ 6 files changed, 36 insertions(+), 74 deletions(-)
2373+
2374+# diff --git a/CHANGES b/CHANGES
2375+# index 01f232c613..bf00b5114b 100644
2376+# --- a/CHANGES
2377+# +++ b/CHANGES
2378+# @@ -1,6 +1,8 @@
2379+# -*- coding: utf-8 -*-
2380+# Changes with Apache 2.4.40
2381+#
2382+# + *) core: Remove request details from built-in error documents [Eric Covener]
2383+# +
2384+# *) mod_http2: core setting "LimitRequestFieldSize" is not additionally checked on
2385+# merged header fields, just as HTTP/1.1 does. [Stefan Eissing, Michael Kaufmann]
2386+#
2387+# diff --git a/STATUS b/STATUS
2388+# index a6f3548511..1ce0436916 100644
2389+# --- a/STATUS
2390+# +++ b/STATUS
2391+# @@ -150,11 +150,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
2392+# 2.4.x patch: svn merge -c 1863635 ^/httpd/httpd/trunk .
2393+# +1: jim, icing, rpluem
2394+#
2395+# - *) core, proxy: remove request URL and headers from error docs
2396+# - trunk: http://svn.apache.org/1864191
2397+# - 2.4.x: svn merge -c 1864191 ^/httpd/httpd/trunk .
2398+# - +1: covener, rpluem, icing
2399+# -
2400+#
2401+# PATCHES PROPOSED TO BACKPORT FROM TRUNK:
2402+# [ New proposals should be added at the end of the list ]
2403+diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c
2404+index e419eb6cd4..dcafa9c68a 100644
2405+--- a/modules/http/http_protocol.c
2406++++ b/modules/http/http_protocol.c
2407+@@ -1132,13 +1132,10 @@ static const char *get_canned_error_string(int status,
2408+ "\">here</a>.</p>\n",
2409+ NULL));
2410+ case HTTP_USE_PROXY:
2411+- return(apr_pstrcat(p,
2412+- "<p>This resource is only accessible "
2413+- "through the proxy\n",
2414+- ap_escape_html(r->pool, location),
2415+- "<br />\nYou will need to configure "
2416+- "your client to use that proxy.</p>\n",
2417+- NULL));
2418++ return("<p>This resource is only accessible "
2419++ "through the proxy\n"
2420++ "<br />\nYou will need to configure "
2421++ "your client to use that proxy.</p>\n");
2422+ case HTTP_PROXY_AUTHENTICATION_REQUIRED:
2423+ case HTTP_UNAUTHORIZED:
2424+ return("<p>This server could not verify that you\n"
2425+@@ -1154,34 +1151,20 @@ static const char *get_canned_error_string(int status,
2426+ "error-notes",
2427+ "</p>\n"));
2428+ case HTTP_FORBIDDEN:
2429+- s1 = apr_pstrcat(p,
2430+- "<p>You don't have permission to access ",
2431+- ap_escape_html(r->pool, r->uri),
2432+- "\non this server.<br />\n",
2433+- NULL);
2434+- return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
2435++ return(add_optional_notes(r, "<p>You don't have permission to access this resource.", "error-notes", "</p>\n"));
2436+ case HTTP_NOT_FOUND:
2437+- return(apr_pstrcat(p,
2438+- "<p>The requested URL ",
2439+- ap_escape_html(r->pool, r->uri),
2440+- " was not found on this server.</p>\n",
2441+- NULL));
2442++ return("<p>The requested URL was not found on this server.</p>\n");
2443+ case HTTP_METHOD_NOT_ALLOWED:
2444+ return(apr_pstrcat(p,
2445+ "<p>The requested method ",
2446+ ap_escape_html(r->pool, r->method),
2447+- " is not allowed for the URL ",
2448+- ap_escape_html(r->pool, r->uri),
2449+- ".</p>\n",
2450++ " is not allowed for this URL.</p>\n",
2451+ NULL));
2452+ case HTTP_NOT_ACCEPTABLE:
2453+- s1 = apr_pstrcat(p,
2454+- "<p>An appropriate representation of the "
2455+- "requested resource ",
2456+- ap_escape_html(r->pool, r->uri),
2457+- " could not be found on this server.</p>\n",
2458+- NULL);
2459+- return(add_optional_notes(r, s1, "variant-list", ""));
2460++ return(add_optional_notes(r,
2461++ "<p>An appropriate representation of the requested resource "
2462++ "could not be found on this server.</p>\n",
2463++ "variant-list", ""));
2464+ case HTTP_MULTIPLE_CHOICES:
2465+ return(add_optional_notes(r, "", "variant-list", ""));
2466+ case HTTP_LENGTH_REQUIRED:
2467+@@ -1192,18 +1175,13 @@ static const char *get_canned_error_string(int status,
2468+ NULL);
2469+ return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
2470+ case HTTP_PRECONDITION_FAILED:
2471+- return(apr_pstrcat(p,
2472+- "<p>The precondition on the request "
2473+- "for the URL ",
2474+- ap_escape_html(r->pool, r->uri),
2475+- " evaluated to false.</p>\n",
2476+- NULL));
2477++ return("<p>The precondition on the request "
2478++ "for this URL evaluated to false.</p>\n");
2479+ case HTTP_NOT_IMPLEMENTED:
2480+ s1 = apr_pstrcat(p,
2481+ "<p>",
2482+- ap_escape_html(r->pool, r->method), " to ",
2483+- ap_escape_html(r->pool, r->uri),
2484+- " not supported.<br />\n",
2485++ ap_escape_html(r->pool, r->method), " ",
2486++ " not supported for current URL.<br />\n",
2487+ NULL);
2488+ return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
2489+ case HTTP_BAD_GATEWAY:
2490+@@ -1211,29 +1189,19 @@ static const char *get_canned_error_string(int status,
2491+ "response from an upstream server.<br />" CRLF;
2492+ return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
2493+ case HTTP_VARIANT_ALSO_VARIES:
2494+- return(apr_pstrcat(p,
2495+- "<p>A variant for the requested "
2496+- "resource\n<pre>\n",
2497+- ap_escape_html(r->pool, r->uri),
2498+- "\n</pre>\nis itself a negotiable resource. "
2499+- "This indicates a configuration error.</p>\n",
2500+- NULL));
2501++ return("<p>A variant for the requested "
2502++ "resource\n<pre>\n"
2503++ "\n</pre>\nis itself a negotiable resource. "
2504++ "This indicates a configuration error.</p>\n");
2505+ case HTTP_REQUEST_TIME_OUT:
2506+ return("<p>Server timeout waiting for the HTTP request from the client.</p>\n");
2507+ case HTTP_GONE:
2508+- return(apr_pstrcat(p,
2509+- "<p>The requested resource<br />",
2510+- ap_escape_html(r->pool, r->uri),
2511+- "<br />\nis no longer available on this server "
2512+- "and there is no forwarding address.\n"
2513+- "Please remove all references to this "
2514+- "resource.</p>\n",
2515+- NULL));
2516++ return("<p>The requested resource is no longer available on this server"
2517++ " and there is no forwarding address.\n"
2518++ "Please remove all references to this resource.</p>\n");
2519+ case HTTP_REQUEST_ENTITY_TOO_LARGE:
2520+ return(apr_pstrcat(p,
2521+- "The requested resource<br />",
2522+- ap_escape_html(r->pool, r->uri), "<br />\n",
2523+- "does not allow request data with ",
2524++ "The requested resource does not allow request data with ",
2525+ ap_escape_html(r->pool, r->method),
2526+ " requests, or the amount of data provided in\n"
2527+ "the request exceeds the capacity limit.\n",
2528+@@ -1317,11 +1285,9 @@ static const char *get_canned_error_string(int status,
2529+ "the Server Name Indication (SNI) in use for this\n"
2530+ "connection.</p>\n");
2531+ case HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
2532+- s1 = apr_pstrcat(p,
2533+- "<p>Access to ", ap_escape_html(r->pool, r->uri),
2534+- "\nhas been denied for legal reasons.<br />\n",
2535+- NULL);
2536+- return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
2537++ return(add_optional_notes(r,
2538++ "<p>Access to this URL has been denied for legal reasons.<br />\n",
2539++ "error-notes", "</p>\n"));
2540+ default: /* HTTP_INTERNAL_SERVER_ERROR */
2541+ /*
2542+ * This comparison to expose error-notes could be modified to
2543+diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
2544+index 91c2b4cdd4..5d9854b11d 100644
2545+--- a/modules/proxy/mod_proxy.c
2546++++ b/modules/proxy/mod_proxy.c
2547+@@ -1049,9 +1049,10 @@ static int proxy_handler(request_rec *r)
2548+ char *end;
2549+ maxfwd = apr_strtoi64(str, &end, 10);
2550+ if (maxfwd < 0 || maxfwd == APR_INT64_MAX || *end) {
2551+- return ap_proxyerror(r, HTTP_BAD_REQUEST,
2552+- apr_psprintf(r->pool,
2553+- "Max-Forwards value '%s' could not be parsed", str));
2554++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO()
2555++ "Max-Forwards value '%s' could not be parsed", str);
2556++ return ap_proxyerror(r, HTTP_BAD_REQUEST,
2557++ "Max-Forwards request header could not be parsed");
2558+ }
2559+ else if (maxfwd == 0) {
2560+ switch (r->method_number) {
2561+diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c
2562+index 49acdcbc1c..86ce69b45c 100644
2563+--- a/modules/proxy/mod_proxy_ftp.c
2564++++ b/modules/proxy/mod_proxy_ftp.c
2565+@@ -1026,8 +1026,9 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
2566+ /* We break the URL into host, port, path-search */
2567+ if (r->parsed_uri.hostname == NULL) {
2568+ if (APR_SUCCESS != apr_uri_parse(p, url, &uri)) {
2569+- return ap_proxyerror(r, HTTP_BAD_REQUEST,
2570+- apr_psprintf(p, "URI cannot be parsed: %s", url));
2571++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO()
2572++ "URI cannot be parsed: %s", url);
2573++ return ap_proxyerror(r, HTTP_BAD_REQUEST, "URI cannot be parsed");
2574+ }
2575+ connectname = uri.hostname;
2576+ connectport = uri.port;
2577+diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
2578+index 0315668296..5482ab8a48 100644
2579+--- a/modules/proxy/proxy_util.c
2580++++ b/modules/proxy/proxy_util.c
2581+@@ -368,12 +368,9 @@ PROXY_DECLARE(char *)
2582+
2583+ PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message)
2584+ {
2585+- const char *uri = ap_escape_html(r->pool, r->uri);
2586+ apr_table_setn(r->notes, "error-notes",
2587+ apr_pstrcat(r->pool,
2588+- "The proxy server could not handle the request <em><a href=\"",
2589+- uri, "\">", ap_escape_html(r->pool, r->method), "&nbsp;", uri,
2590+- "</a></em>.<p>\n"
2591++ "The proxy server could not handle the request<p>"
2592+ "Reason: <strong>", ap_escape_html(r->pool, message),
2593+ "</strong></p>",
2594+ NULL));
2595+--
2596+2.17.1
2597+
2598diff --git a/debian/patches/CVE-2019-10092-2.patch b/debian/patches/CVE-2019-10092-2.patch
2599new file mode 100644
2600index 0000000..2eec9fb
2601--- /dev/null
2602+++ b/debian/patches/CVE-2019-10092-2.patch
2603@@ -0,0 +1,45 @@
2604+From 7106a941f8086e06d4c1b26a8dd6d2a4695eee5a Mon Sep 17 00:00:00 2001
2605+From: Eric Covener <covener@apache.org>
2606+Date: Thu, 8 Aug 2019 13:09:10 +0000
2607+Subject: [PATCH] Merge r1864699 from trunk:
2608+
2609+lognos
2610+
2611+
2612+
2613+
2614+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1864702 13f79535-47bb-0310-9956-ffa450edef68
2615+---
2616+ modules/proxy/mod_proxy.c | 2 +-
2617+ modules/proxy/mod_proxy_ftp.c | 2 +-
2618+ 2 files changed, 2 insertions(+), 2 deletions(-)
2619+
2620+diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
2621+index 5d9854b11d..8661a2dbaa 100644
2622+--- a/modules/proxy/mod_proxy.c
2623++++ b/modules/proxy/mod_proxy.c
2624+@@ -1049,7 +1049,7 @@ static int proxy_handler(request_rec *r)
2625+ char *end;
2626+ maxfwd = apr_strtoi64(str, &end, 10);
2627+ if (maxfwd < 0 || maxfwd == APR_INT64_MAX || *end) {
2628+- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO()
2629++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10188)
2630+ "Max-Forwards value '%s' could not be parsed", str);
2631+ return ap_proxyerror(r, HTTP_BAD_REQUEST,
2632+ "Max-Forwards request header could not be parsed");
2633+diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c
2634+index 86ce69b45c..7ad803b97c 100644
2635+--- a/modules/proxy/mod_proxy_ftp.c
2636++++ b/modules/proxy/mod_proxy_ftp.c
2637+@@ -1026,7 +1026,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
2638+ /* We break the URL into host, port, path-search */
2639+ if (r->parsed_uri.hostname == NULL) {
2640+ if (APR_SUCCESS != apr_uri_parse(p, url, &uri)) {
2641+- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO()
2642++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10189)
2643+ "URI cannot be parsed: %s", url);
2644+ return ap_proxyerror(r, HTTP_BAD_REQUEST, "URI cannot be parsed");
2645+ }
2646+--
2647+2.17.1
2648+
2649diff --git a/debian/patches/CVE-2019-10098.patch b/debian/patches/CVE-2019-10098.patch
2650new file mode 100644
2651index 0000000..0ad57ba
2652--- /dev/null
2653+++ b/debian/patches/CVE-2019-10098.patch
2654@@ -0,0 +1,159 @@
2655+From 3b3117e96bc9c2afaeb5b98e9b60315006679a6d Mon Sep 17 00:00:00 2001
2656+From: Stefan Eissing <icing@apache.org>
2657+Date: Fri, 2 Aug 2019 09:24:58 +0000
2658+Subject: [PATCH] Merge of r1864192 from trunk:
2659+
2660+ *) core, rewrite: Set PCRE_DOTALL by default
2661+
2662+
2663+
2664+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1864213 13f79535-47bb-0310-9956-ffa450edef68
2665+---
2666+ CHANGES | 3 +++
2667+ STATUS | 5 -----
2668+ docs/manual/mod/core.xml | 20 +++++++++++---------
2669+ server/util_pcre.c | 3 ++-
2670+ 4 files changed, 16 insertions(+), 15 deletions(-)
2671+
2672+# diff --git a/CHANGES b/CHANGES
2673+# index bf00b5114b..ad4fd27625 100644
2674+# --- a/CHANGES
2675+# +++ b/CHANGES
2676+# @@ -1,6 +1,9 @@
2677+# -*- coding: utf-8 -*-
2678+# Changes with Apache 2.4.40
2679+#
2680+# + *) core, mod_rewrite: Set PCRE_DOTALL by default. Revert via
2681+# + RegexDefaultOptions -DOTALL [Yann Ylavic]
2682+# +
2683+# *) core: Remove request details from built-in error documents [Eric Covener]
2684+#
2685+# *) mod_http2: core setting "LimitRequestFieldSize" is not additionally checked on
2686+# diff --git a/STATUS b/STATUS
2687+# index 3c3cf39f48..f9bfc678fd 100644
2688+# --- a/STATUS
2689+# +++ b/STATUS
2690+# @@ -127,11 +127,6 @@ RELEASE SHOWSTOPPERS:
2691+# PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
2692+# [ start all new proposals below, under PATCHES PROPOSED. ]
2693+#
2694+# - *) core, rewrite: Set PCRE_DOTALL by default
2695+# - trunk: http://svn.apache.org/1864192
2696+# - 2.4.x: svn merge -c 1864192 ^/httpd/httpd/trunk .
2697+# - +1: covener, rpluem, icing
2698+# -
2699+#
2700+# PATCHES PROPOSED TO BACKPORT FROM TRUNK:
2701+# [ New proposals should be added at the end of the list ]
2702+# diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml
2703+# index d9f0895af4..d4d6030dc5 100644
2704+# --- a/docs/manual/mod/core.xml
2705+# +++ b/docs/manual/mod/core.xml
2706+# @@ -4061,7 +4061,7 @@ Protocols h2 http/1.1
2707+# <name>RegexDefaultOptions</name>
2708+# <description>Allow to configure global/default options for regexes</description>
2709+# <syntax>RegexDefaultOptions [none] [+|-]<var>option</var> [[+|-]<var>option</var>] ...</syntax>
2710+# - <default>RegexDefaultOptions DOLLAR_ENDONLY</default>
2711+# + <default>RegexDefaultOptions DOTALL DOLLAR_ENDONLY</default>
2712+# <contextlist><context>server config</context></contextlist>
2713+# <compatibility>Only available from Apache 2.4.30 and later.</compatibility>
2714+#
2715+# @@ -4080,24 +4080,26 @@ Protocols h2 http/1.1
2716+# <dt><code>ICASE</code></dt>
2717+# <dd>Use a case-insensitive match.</dd>
2718+#
2719+# + <dt><code>EXTENDED</code></dt>
2720+# + <dd>Perl's /x flag, ignore (unescaped-)spaces and comments in the pattern.</dd>
2721+# +
2722+# <dt><code>DOTALL</code></dt>
2723+# - <dd>Perl's /s flag.</dd>
2724+# + <dd>Perl's /s flag, '.' matches newline characters.</dd>
2725+#
2726+# <dt><code>DOLLAR_ENDONLY</code></dt>
2727+# <dd>'$' matches at end of subject string only.</dd>
2728+# - <dd>.</dd>
2729+# </dl>
2730+# <highlight language="config">
2731+# -#
2732+# -RegexDefaultOptions +ICASE +DOLLAR_ENDONLY
2733+# +# Add the ICASE option for all regexes by default
2734+# +RegexDefaultOptions +ICASE
2735+# ...
2736+# -# Remove the ICASE option, but keep all the other already set options
2737+# -RegexDefaultOptions -ICASE
2738+# +# Remove the default DOLLAR_ENDONLY option, but keep any other one
2739+# +RegexDefaultOptions -DOLLAR_ENDONLY
2740+# ...
2741+# -# Set the default option to DOTALL, resetting any other option
2742+# +# Set the DOTALL option only, resetting any other one
2743+# RegexDefaultOptions DOTALL
2744+# ...
2745+# -# Reset all defined option
2746+# +# Reset all defined options
2747+# RegexDefaultOptions none
2748+# ...
2749+# </highlight>
2750+# diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en
2751+# index 1cc985eb65..4c0b2fd744 100644
2752+# --- a/docs/manual/mod/core.html.en
2753+# +++ b/docs/manual/mod/core.html.en
2754+# @@ -4069,7 +4069,7 @@ as if 'QualifyRedirectURL ON' was configured.</td></tr>
2755+# <table class="directive">
2756+# <tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Allow to configure global/default options for regexes</td></tr>
2757+# <tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>RegexDefaultOptions [none] [+|-]<var>option</var> [[+|-]<var>option</var>] ...</code></td></tr>
2758+# -<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>RegexDefaultOptions DOLLAR_ENDONLY</code></td></tr>
2759+# +<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>RegexDefaultOptions DOTALL DOLLAR_ENDONLY</code></td></tr>
2760+# <tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config</td></tr>
2761+# <tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Core</td></tr>
2762+# <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>core</td></tr>
2763+# @@ -4089,23 +4089,25 @@ as if 'QualifyRedirectURL ON' was configured.</td></tr>
2764+# <dt><code>ICASE</code></dt>
2765+# <dd>Use a case-insensitive match.</dd>
2766+#
2767+# + <dt><code>EXTENDED</code></dt>
2768+# + <dd>Perl's /x flag, ignore (unescaped-)spaces and comments in the pattern.</dd>
2769+# +
2770+# <dt><code>DOTALL</code></dt>
2771+# - <dd>Perl's /s flag.</dd>
2772+# + <dd>Perl's /s flag, '.' matches newline characters.</dd>
2773+#
2774+# <dt><code>DOLLAR_ENDONLY</code></dt>
2775+# <dd>'$' matches at end of subject string only.</dd>
2776+# - <dd>.</dd>
2777+# </dl>
2778+# - <pre class="prettyprint lang-config">#
2779+# -RegexDefaultOptions +ICASE +DOLLAR_ENDONLY
2780+# + <pre class="prettyprint lang-config"># Add the ICASE option for all regexes by default
2781+# +RegexDefaultOptions +ICASE
2782+# ...
2783+# -# Remove the ICASE option, but keep all the other already set options
2784+# -RegexDefaultOptions -ICASE
2785+# +# Remove the default DOLLAR_ENDONLY option, but keep any other one
2786+# +RegexDefaultOptions -DOLLAR_ENDONLY
2787+# ...
2788+# -# Set the default option to DOTALL, resetting any other option
2789+# +# Set the DOTALL option only, resetting any other one
2790+# RegexDefaultOptions DOTALL
2791+# ...
2792+# -# Reset all defined option
2793+# +# Reset all defined options
2794+# RegexDefaultOptions none
2795+# ...</pre>
2796+#
2797+diff --git a/server/util_pcre.c b/server/util_pcre.c
2798+index f2cb1bb01e..35831f500f 100644
2799+--- a/server/util_pcre.c
2800++++ b/server/util_pcre.c
2801+@@ -120,7 +120,8 @@ AP_DECLARE(void) ap_regfree(ap_regex_t *preg)
2802+ * Compile a regular expression *
2803+ *************************************************/
2804+
2805+-static int default_cflags = AP_REG_DOLLAR_ENDONLY;
2806++static int default_cflags = AP_REG_DOTALL |
2807++ AP_REG_DOLLAR_ENDONLY;
2808+
2809+ AP_DECLARE(int) ap_regcomp_get_default_cflags(void)
2810+ {
2811+--
2812+2.17.1
2813+
2814diff --git a/debian/patches/CVE-2020-11993-pre1.patch b/debian/patches/CVE-2020-11993-pre1.patch
2815new file mode 100644
2816index 0000000..25d6669
2817--- /dev/null
2818+++ b/debian/patches/CVE-2020-11993-pre1.patch
2819@@ -0,0 +1,406 @@
2820+Backport of:
2821+
2822+From 3060a9dd4d160af2e82829ce801a3a89127e36a1 Mon Sep 17 00:00:00 2001
2823+From: Jim Jagielski <jim@apache.org>
2824+Date: Thu, 30 Jan 2020 15:14:40 +0000
2825+Subject: [PATCH] Merge r1871810 from trunk:
2826+
2827+ *) mod_http2: Fixed rare cases where a h2 worker could deadlock the main connection.
2828+
2829+
2830+Submitted by: icing
2831+Reviewed by: icing, jim, steffenal
2832+
2833+
2834+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1873368 13f79535-47bb-0310-9956-ffa450edef68
2835+---
2836+ CHANGES | 3 ++
2837+ STATUS | 4 --
2838+ modules/http2/h2_mplx.c | 54 ++++++++++++--------
2839+ modules/http2/h2_session.c | 2 +-
2840+ modules/http2/h2_util.c | 89 ++++++++++-----------------------
2841+ modules/http2/h2_util.h | 2 -
2842+ modules/http2/h2_version.h | 4 +-
2843+ modules/http2/h2_workers.c | 1 -
2844+ modules/http2/mod_proxy_http2.c | 8 +++
2845+ 9 files changed, 72 insertions(+), 95 deletions(-)
2846+
2847+#diff --git a/CHANGES b/CHANGES
2848+#index ded0ecce34c..e12ef389501 100644
2849+#--- a/CHANGES
2850+#+++ b/CHANGES
2851+#@@ -5,6 +5,9 @@ Changes with Apache 2.4.42
2852+# r:notes_table, r:subprocess_env_table as read-only native table alternatives
2853+# that can be iterated over. [Eric Covener]
2854+#
2855+#+ *) mod_http2: Fixed rare cases where a h2 worker could deadlock the main connection.
2856+#+ [Yann Ylavic, Stefan Eissing]
2857+#+
2858+# *) mod_lua: Accept nil assignments to the exposed tables (r.subprocess_env,
2859+# r.headers_out, etc) to remove the key from the table. PR63971.
2860+# [Eric Covener]
2861+#diff --git a/STATUS b/STATUS
2862+#index 991ed406b23..a610953ed89 100644
2863+#--- a/STATUS
2864+#+++ b/STATUS
2865+#@@ -132,10 +132,6 @@ RELEASE SHOWSTOPPERS:
2866+# PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
2867+# [ start all new proposals below, under PATCHES PROPOSED. ]
2868+#
2869+#- *) mod_http2: Fixed rare cases where a h2 worker could deadlock the main connection.
2870+#- trunk patch: http://svn.apache.org/r1871810
2871+#- 2.4.x patch: svn merge -c 1871810 ^/httpd/httpd/trunk
2872+#- +1: icing, jim, steffenal(tested with 1.15.5-git)
2873+#
2874+# PATCHES PROPOSED TO BACKPORT FROM TRUNK:
2875+# [ New proposals should be added at the end of the list ]
2876+--- a/modules/http2/h2_mplx.c
2877++++ b/modules/http2/h2_mplx.c
2878+@@ -75,13 +75,13 @@ apr_status_t h2_mplx_child_init(apr_pool
2879+ #define H2_MPLX_ENTER_ALWAYS(m) \
2880+ apr_thread_mutex_lock(m->lock)
2881+
2882+-#define H2_MPLX_ENTER_MAYBE(m, lock) \
2883+- if (lock) apr_thread_mutex_lock(m->lock)
2884++#define H2_MPLX_ENTER_MAYBE(m, dolock) \
2885++ if (dolock) apr_thread_mutex_lock(m->lock)
2886+
2887+-#define H2_MPLX_LEAVE_MAYBE(m, lock) \
2888+- if (lock) apr_thread_mutex_unlock(m->lock)
2889++#define H2_MPLX_LEAVE_MAYBE(m, dolock) \
2890++ if (dolock) apr_thread_mutex_unlock(m->lock)
2891+
2892+-static void check_data_for(h2_mplx *m, h2_stream *stream, int lock);
2893++static void check_data_for(h2_mplx *m, h2_stream *stream, int mplx_is_locked);
2894+
2895+ static void stream_output_consumed(void *ctx,
2896+ h2_bucket_beam *beam, apr_off_t length)
2897+@@ -104,6 +104,7 @@ static void stream_joined(h2_mplx *m, h2
2898+ {
2899+ ap_assert(!h2_task_has_started(stream->task) || stream->task->worker_done);
2900+
2901++ h2_ififo_remove(m->readyq, stream->id);
2902+ h2_ihash_remove(m->shold, stream->id);
2903+ h2_ihash_add(m->spurge, stream);
2904+ }
2905+@@ -125,14 +126,16 @@ static void stream_cleanup(h2_mplx *m, h
2906+
2907+ h2_ihash_remove(m->streams, stream->id);
2908+ h2_iq_remove(m->q, stream->id);
2909+- h2_ififo_remove(m->readyq, stream->id);
2910+- h2_ihash_add(m->shold, stream);
2911+
2912+ if (!h2_task_has_started(stream->task) || stream->task->done_done) {
2913+ stream_joined(m, stream);
2914+ }
2915+- else if (stream->task) {
2916+- stream->task->c->aborted = 1;
2917++ else {
2918++ h2_ififo_remove(m->readyq, stream->id);
2919++ h2_ihash_add(m->shold, stream);
2920++ if (stream->task) {
2921++ stream->task->c->aborted = 1;
2922++ }
2923+ }
2924+ }
2925+
2926+@@ -509,12 +512,11 @@ static void output_produced(void *ctx, h
2927+ h2_stream *stream = ctx;
2928+ h2_mplx *m = stream->session->mplx;
2929+
2930+- check_data_for(m, stream, 1);
2931++ check_data_for(m, stream, 0);
2932+ }
2933+
2934+ static apr_status_t out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam)
2935+ {
2936+- apr_status_t status = APR_SUCCESS;
2937+ h2_stream *stream = h2_ihash_get(m->streams, stream_id);
2938+
2939+ if (!stream || !stream->task || m->aborted) {
2940+@@ -528,7 +530,7 @@ static apr_status_t out_open(h2_mplx *m,
2941+ h2_beam_log(beam, m->c, APLOG_TRACE2, "out_open");
2942+ }
2943+ else {
2944+- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, m->c,
2945++ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
2946+ "h2_mplx(%s): out open", stream->task->id);
2947+ }
2948+
2949+@@ -540,8 +542,8 @@ static apr_status_t out_open(h2_mplx *m,
2950+
2951+ /* we might see some file buckets in the output, see
2952+ * if we have enough handles reserved. */
2953+- check_data_for(m, stream, 0);
2954+- return status;
2955++ check_data_for(m, stream, 1);
2956++ return APR_SUCCESS;
2957+ }
2958+
2959+ apr_status_t h2_mplx_out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam)
2960+@@ -583,7 +585,7 @@ static apr_status_t out_close(h2_mplx *m
2961+ status = h2_beam_close(task->output.beam);
2962+ h2_beam_log(task->output.beam, m->c, APLOG_TRACE2, "out_close");
2963+ output_consumed_signal(m, task);
2964+- check_data_for(m, stream, 0);
2965++ check_data_for(m, stream, 1);
2966+ return status;
2967+ }
2968+
2969+@@ -617,15 +619,23 @@ apr_status_t h2_mplx_out_trywait(h2_mplx
2970+ return status;
2971+ }
2972+
2973+-static void check_data_for(h2_mplx *m, h2_stream *stream, int lock)
2974++static void check_data_for(h2_mplx *m, h2_stream *stream, int mplx_is_locked)
2975+ {
2976++ /* If m->lock is already held, we must release during h2_ififo_push()
2977++ * which can wait on its not_full condition, causing a deadlock because
2978++ * no one would then be able to acquire m->lock to empty the fifo.
2979++ */
2980++ H2_MPLX_LEAVE_MAYBE(m, mplx_is_locked);
2981+ if (h2_ififo_push(m->readyq, stream->id) == APR_SUCCESS) {
2982++ H2_MPLX_ENTER_ALWAYS(m);
2983+ apr_atomic_set32(&m->event_pending, 1);
2984+- H2_MPLX_ENTER_MAYBE(m, lock);
2985+ if (m->added_output) {
2986+ apr_thread_cond_signal(m->added_output);
2987+ }
2988+- H2_MPLX_LEAVE_MAYBE(m, lock);
2989++ H2_MPLX_LEAVE_MAYBE(m, !mplx_is_locked);
2990++ }
2991++ else {
2992++ H2_MPLX_ENTER_MAYBE(m, mplx_is_locked);
2993+ }
2994+ }
2995+
2996+@@ -678,7 +688,7 @@ apr_status_t h2_mplx_process(h2_mplx *m,
2997+ h2_ihash_add(m->streams, stream);
2998+ if (h2_stream_is_ready(stream)) {
2999+ /* already have a response */
3000+- check_data_for(m, stream, 0);
3001++ check_data_for(m, stream, 1);
3002+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
3003+ H2_STRM_MSG(stream, "process, add to readyq"));
3004+ }
3005+@@ -809,7 +819,7 @@ static void task_done(h2_mplx *m, h2_tas
3006+ }
3007+
3008+ /* more data will not arrive, resume the stream */
3009+- check_data_for(m, stream, 0);
3010++ check_data_for(m, stream, 1);
3011+ }
3012+ }
3013+ else if ((stream = h2_ihash_get(m->shold, task->stream_id)) != NULL) {
3014+@@ -1062,7 +1072,7 @@ apr_status_t h2_mplx_idle(h2_mplx *m)
3015+ h2_beam_is_closed(stream->output),
3016+ (long)h2_beam_get_buffered(stream->output));
3017+ h2_ihash_add(m->streams, stream);
3018+- check_data_for(m, stream, 0);
3019++ check_data_for(m, stream, 1);
3020+ stream->out_checked = 1;
3021+ status = APR_EAGAIN;
3022+ }
3023+@@ -1114,7 +1124,7 @@ apr_status_t h2_mplx_dispatch_master_eve
3024+
3025+ apr_status_t h2_mplx_keep_active(h2_mplx *m, h2_stream *stream)
3026+ {
3027+- check_data_for(m, stream, 1);
3028++ check_data_for(m, stream, 0);
3029+ return APR_SUCCESS;
3030+ }
3031+
3032+--- a/modules/http2/h2_session.c
3033++++ b/modules/http2/h2_session.c
3034+@@ -2141,7 +2141,7 @@ apr_status_t h2_session_process(h2_sessi
3035+ break;
3036+
3037+ case H2_SESSION_ST_IDLE:
3038+- if (session->idle_until && (apr_time_now() + session->idle_delay) > session->idle_until) {
3039++ if (session->idle_until && (now + session->idle_delay) > session->idle_until) {
3040+ ap_log_cerror( APLOG_MARK, APLOG_TRACE1, status, c,
3041+ H2_SSSN_MSG(session, "idle, timeout reached, closing"));
3042+ if (session->idle_delay) {
3043+--- a/modules/http2/h2_util.c
3044++++ b/modules/http2/h2_util.c
3045+@@ -638,15 +638,6 @@ apr_status_t h2_fifo_term(h2_fifo *fifo)
3046+ apr_status_t rv;
3047+ if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
3048+ fifo->aborted = 1;
3049+- apr_thread_mutex_unlock(fifo->lock);
3050+- }
3051+- return rv;
3052+-}
3053+-
3054+-apr_status_t h2_fifo_interrupt(h2_fifo *fifo)
3055+-{
3056+- apr_status_t rv;
3057+- if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
3058+ apr_thread_cond_broadcast(fifo->not_empty);
3059+ apr_thread_cond_broadcast(fifo->not_full);
3060+ apr_thread_mutex_unlock(fifo->lock);
3061+@@ -710,10 +701,6 @@ static apr_status_t fifo_push(h2_fifo *f
3062+ {
3063+ apr_status_t rv;
3064+
3065+- if (fifo->aborted) {
3066+- return APR_EOF;
3067+- }
3068+-
3069+ if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
3070+ rv = fifo_push_int(fifo, elem, block);
3071+ apr_thread_mutex_unlock(fifo->lock);
3072+@@ -754,10 +741,6 @@ static apr_status_t fifo_pull(h2_fifo *f
3073+ {
3074+ apr_status_t rv;
3075+
3076+- if (fifo->aborted) {
3077+- return APR_EOF;
3078+- }
3079+-
3080+ if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
3081+ rv = pull_head(fifo, pelem, block);
3082+ apr_thread_mutex_unlock(fifo->lock);
3083+@@ -946,15 +929,6 @@ apr_status_t h2_ififo_term(h2_ififo *fif
3084+ apr_status_t rv;
3085+ if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
3086+ fifo->aborted = 1;
3087+- apr_thread_mutex_unlock(fifo->lock);
3088+- }
3089+- return rv;
3090+-}
3091+-
3092+-apr_status_t h2_ififo_interrupt(h2_ififo *fifo)
3093+-{
3094+- apr_status_t rv;
3095+- if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
3096+ apr_thread_cond_broadcast(fifo->not_empty);
3097+ apr_thread_cond_broadcast(fifo->not_full);
3098+ apr_thread_mutex_unlock(fifo->lock);
3099+@@ -1018,10 +992,6 @@ static apr_status_t ififo_push(h2_ififo
3100+ {
3101+ apr_status_t rv;
3102+
3103+- if (fifo->aborted) {
3104+- return APR_EOF;
3105+- }
3106+-
3107+ if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
3108+ rv = ififo_push_int(fifo, id, block);
3109+ apr_thread_mutex_unlock(fifo->lock);
3110+@@ -1062,10 +1032,6 @@ static apr_status_t ififo_pull(h2_ififo
3111+ {
3112+ apr_status_t rv;
3113+
3114+- if (fifo->aborted) {
3115+- return APR_EOF;
3116+- }
3117+-
3118+ if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
3119+ rv = ipull_head(fifo, pi, block);
3120+ apr_thread_mutex_unlock(fifo->lock);
3121+@@ -1088,10 +1054,6 @@ static apr_status_t ififo_peek(h2_ififo
3122+ apr_status_t rv;
3123+ int id;
3124+
3125+- if (fifo->aborted) {
3126+- return APR_EOF;
3127+- }
3128+-
3129+ if (APR_SUCCESS == (rv = apr_thread_mutex_lock(fifo->lock))) {
3130+ if (APR_SUCCESS == (rv = ipull_head(fifo, &id, block))) {
3131+ switch (fn(id, ctx)) {
3132+@@ -1117,39 +1079,40 @@ apr_status_t h2_ififo_try_peek(h2_ififo
3133+ return ififo_peek(fifo, fn, ctx, 0);
3134+ }
3135+
3136+-apr_status_t h2_ififo_remove(h2_ififo *fifo, int id)
3137++static apr_status_t ififo_remove(h2_ififo *fifo, int id)
3138+ {
3139+- apr_status_t rv;
3140++ int rc, i;
3141+
3142+ if (fifo->aborted) {
3143+ return APR_EOF;
3144+ }
3145+
3146+- if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
3147+- int i, rc;
3148+- int e;
3149+-
3150+- rc = 0;
3151+- for (i = 0; i < fifo->count; ++i) {
3152+- e = fifo->elems[inth_index(fifo, i)];
3153+- if (e == id) {
3154+- ++rc;
3155+- }
3156+- else if (rc) {
3157+- fifo->elems[inth_index(fifo, i-rc)] = e;
3158+- }
3159+- }
3160+- if (rc) {
3161+- fifo->count -= rc;
3162+- if (fifo->count + rc == fifo->nelems) {
3163+- apr_thread_cond_broadcast(fifo->not_full);
3164+- }
3165+- rv = APR_SUCCESS;
3166++ rc = 0;
3167++ for (i = 0; i < fifo->count; ++i) {
3168++ int e = fifo->elems[inth_index(fifo, i)];
3169++ if (e == id) {
3170++ ++rc;
3171+ }
3172+- else {
3173+- rv = APR_EAGAIN;
3174++ else if (rc) {
3175++ fifo->elems[inth_index(fifo, i-rc)] = e;
3176+ }
3177+-
3178++ }
3179++ if (!rc) {
3180++ return APR_EAGAIN;
3181++ }
3182++ fifo->count -= rc;
3183++ if (fifo->count + rc == fifo->nelems) {
3184++ apr_thread_cond_broadcast(fifo->not_full);
3185++ }
3186++ return APR_SUCCESS;
3187++}
3188++
3189++apr_status_t h2_ififo_remove(h2_ififo *fifo, int id)
3190++{
3191++ apr_status_t rv;
3192++
3193++ if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
3194++ rv = ififo_remove(fifo, id);
3195+ apr_thread_mutex_unlock(fifo->lock);
3196+ }
3197+ return rv;
3198+--- a/modules/http2/h2_util.h
3199++++ b/modules/http2/h2_util.h
3200+@@ -209,7 +209,6 @@ apr_status_t h2_fifo_create(h2_fifo **pf
3201+ apr_status_t h2_fifo_set_create(h2_fifo **pfifo, apr_pool_t *pool, int capacity);
3202+
3203+ apr_status_t h2_fifo_term(h2_fifo *fifo);
3204+-apr_status_t h2_fifo_interrupt(h2_fifo *fifo);
3205+
3206+ int h2_fifo_count(h2_fifo *fifo);
3207+
3208+@@ -280,7 +279,6 @@ apr_status_t h2_ififo_create(h2_ififo **
3209+ apr_status_t h2_ififo_set_create(h2_ififo **pfifo, apr_pool_t *pool, int capacity);
3210+
3211+ apr_status_t h2_ififo_term(h2_ififo *fifo);
3212+-apr_status_t h2_ififo_interrupt(h2_ififo *fifo);
3213+
3214+ int h2_ififo_count(h2_ififo *fifo);
3215+
3216+--- a/modules/http2/h2_workers.c
3217++++ b/modules/http2/h2_workers.c
3218+@@ -269,7 +269,6 @@ static apr_status_t workers_pool_cleanup
3219+ }
3220+
3221+ h2_fifo_term(workers->mplxs);
3222+- h2_fifo_interrupt(workers->mplxs);
3223+
3224+ cleanup_zombies(workers);
3225+ }
3226diff --git a/debian/patches/CVE-2020-11993.patch b/debian/patches/CVE-2020-11993.patch
3227new file mode 100644
3228index 0000000..1002f87
3229--- /dev/null
3230+++ b/debian/patches/CVE-2020-11993.patch
3231@@ -0,0 +1,1905 @@
3232+Backport of:
3233+
3234+From 63a0a87efa0925514d15c211b508f6594669888c Mon Sep 17 00:00:00 2001
3235+From: Graham Leggett <minfrin@apache.org>
3236+Date: Wed, 8 Jul 2020 11:53:48 +0000
3237+Subject: [PATCH] *) mod_http2: connection terminology renamed to
3238+ master/secondary. trunk patch: http://svn.apache.org/r1878926
3239+ http://svn.apache.org/r1879156 2.4.x patch:
3240+ https://svn.apache.org/repos/asf/httpd/httpd/patches/2.4.x/h2-master-secondary.patch
3241+ +1: icing, ylavic, minfrin ylavic: nitpicking, mixed
3242+ "H2_secondary_IN" and "H2_secondary_OUT" case to register the
3243+ filters, but not for adding them. IIRC filters names are case
3244+ insentive so shouldn't matter, just popped at my eyes.. icing: updated
3245+ patch and added r1879156 to fix the eye bleed. jailletc36: CHANGES could
3246+ also be looked at if it makes sense to update the terminology
3247+ also here
3248+
3249+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1879642 13f79535-47bb-0310-9956-ffa450edef68
3250+---
3251+ CHANGES | 3 +
3252+ STATUS | 11 --
3253+ modules/http2/h2_conn.c | 52 +++----
3254+ modules/http2/h2_conn.h | 8 +-
3255+ modules/http2/h2_filter.c | 4 +-
3256+ modules/http2/h2_h2.c | 10 +-
3257+ modules/http2/h2_mplx.c | 283 +++++++++++++++++++------------------
3258+ modules/http2/h2_mplx.h | 160 ++++++---------------
3259+ modules/http2/h2_request.c | 7 +-
3260+ modules/http2/h2_session.c | 30 ++--
3261+ modules/http2/h2_session.h | 2 +-
3262+ modules/http2/h2_stream.c | 2 +-
3263+ modules/http2/h2_task.c | 68 ++++-----
3264+ modules/http2/h2_task.h | 2 +-
3265+ modules/http2/h2_workers.c | 6 +-
3266+ modules/http2/mod_http2.c | 4 +-
3267+ 16 files changed, 288 insertions(+), 364 deletions(-)
3268+
3269+#diff --git a/CHANGES b/CHANGES
3270+#index 50432a7ca09..31ad6741715 100644
3271+#--- a/CHANGES
3272+#+++ b/CHANGES
3273+#@@ -1,6 +1,9 @@
3274+# -*- coding: utf-8 -*-
3275+# Changes with Apache 2.4.44
3276+#
3277+#+ *) mod_http2: The module now handles master/secondary connections and has marked
3278+#+ methods according to use. [Stefan Eissing]
3279+#+
3280+# *) core: Drop an invalid Last-Modified header value coming
3281+# from a FCGI/CGI script instead of replacing it with Unix epoch.
3282+# [Luca Toscano]
3283+#diff --git a/STATUS b/STATUS
3284+#index c4d0dde0534..72220708a70 100644
3285+#--- a/STATUS
3286+#+++ b/STATUS
3287+#@@ -135,17 +135,6 @@ RELEASE SHOWSTOPPERS:
3288+# PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
3289+# [ start all new proposals below, under PATCHES PROPOSED. ]
3290+#
3291+#- *) mod_http2: connection terminology renamed to master/secondary.
3292+#- trunk patch: http://svn.apache.org/r1878926
3293+#- http://svn.apache.org/r1879156
3294+#- 2.4.x patch: https://svn.apache.org/repos/asf/httpd/httpd/patches/2.4.x/h2-master-secondary.patch
3295+#- +1: icing, ylavic, minfrin
3296+#- ylavic: nitpicking, mixed "H2_secondary_IN" and "H2_secondary_OUT" case to
3297+#- register the filters, but not for adding them. IIRC filters names
3298+#- are case insentive so shouldn't matter, just popped at my eyes..
3299+#- icing: updated patch and added r1879156 to fix the eye bleed.
3300+#- jailletc36: CHANGES could also be looked at if it makes sense to update the terminology
3301+#- also here
3302+#
3303+# PATCHES PROPOSED TO BACKPORT FROM TRUNK:
3304+# [ New proposals should be added at the end of the list ]
3305+--- a/modules/http2/h2_conn.c
3306++++ b/modules/http2/h2_conn.c
3307+@@ -138,7 +138,7 @@ apr_status_t h2_conn_child_init(apr_pool
3308+ ap_register_input_filter("H2_IN", h2_filter_core_input,
3309+ NULL, AP_FTYPE_CONNECTION);
3310+
3311+- status = h2_mplx_child_init(pool, s);
3312++ status = h2_mplx_m_child_init(pool, s);
3313+
3314+ if (status == APR_SUCCESS) {
3315+ status = apr_socket_create(&dummy_socket, APR_INET, SOCK_STREAM,
3316+@@ -260,7 +260,7 @@ apr_status_t h2_conn_pre_close(struct h2
3317+ return DONE;
3318+ }
3319+
3320+-conn_rec *h2_slave_create(conn_rec *master, int slave_id, apr_pool_t *parent)
3321++conn_rec *h2_secondary_create(conn_rec *master, int sec_id, apr_pool_t *parent)
3322+ {
3323+ apr_allocator_t *allocator;
3324+ apr_status_t status;
3325+@@ -271,7 +271,7 @@ conn_rec *h2_slave_create(conn_rec *mast
3326+
3327+ ap_assert(master);
3328+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, master,
3329+- "h2_stream(%ld-%d): create slave", master->id, slave_id);
3330++ "h2_stream(%ld-%d): create secondary", master->id, sec_id);
3331+
3332+ /* We create a pool with its own allocator to be used for
3333+ * processing a request. This is the only way to have the processing
3334+@@ -284,18 +284,18 @@ conn_rec *h2_slave_create(conn_rec *mast
3335+ status = apr_pool_create_ex(&pool, parent, NULL, allocator);
3336+ if (status != APR_SUCCESS) {
3337+ ap_log_cerror(APLOG_MARK, APLOG_ERR, status, master,
3338+- APLOGNO(10004) "h2_session(%ld-%d): create slave pool",
3339+- master->id, slave_id);
3340++ APLOGNO(10004) "h2_session(%ld-%d): create secondary pool",
3341++ master->id, sec_id);
3342+ return NULL;
3343+ }
3344+ apr_allocator_owner_set(allocator, pool);
3345+- apr_pool_tag(pool, "h2_slave_conn");
3346++ apr_pool_tag(pool, "h2_secondary_conn");
3347+
3348+ c = (conn_rec *) apr_palloc(pool, sizeof(conn_rec));
3349+ if (c == NULL) {
3350+ ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, master,
3351+- APLOGNO(02913) "h2_session(%ld-%d): create slave",
3352+- master->id, slave_id);
3353++ APLOGNO(02913) "h2_session(%ld-%d): create secondary",
3354++ master->id, sec_id);
3355+ apr_pool_destroy(pool);
3356+ return NULL;
3357+ }
3358+@@ -322,19 +322,19 @@ conn_rec *h2_slave_create(conn_rec *mast
3359+ c->clogging_input_filters = 1;
3360+ c->log = NULL;
3361+ c->log_id = apr_psprintf(pool, "%ld-%d",
3362+- master->id, slave_id);
3363++ master->id, sec_id);
3364+ c->aborted = 0;
3365+- /* We cannot install the master connection socket on the slaves, as
3366++ /* We cannot install the master connection socket on the secondary, as
3367+ * modules mess with timeouts/blocking of the socket, with
3368+ * unwanted side effects to the master connection processing.
3369+- * Fortunately, since we never use the slave socket, we can just install
3370++ * Fortunately, since we never use the secondary socket, we can just install
3371+ * a single, process-wide dummy and everyone is happy.
3372+ */
3373+ ap_set_module_config(c->conn_config, &core_module, dummy_socket);
3374+ /* TODO: these should be unique to this thread */
3375+ c->sbh = master->sbh;
3376+- /* TODO: not all mpm modules have learned about slave connections yet.
3377+- * copy their config from master to slave.
3378++ /* TODO: not all mpm modules have learned about secondary connections yet.
3379++ * copy their config from master to secondary.
3380+ */
3381+ if ((mpm = h2_conn_mpm_module()) != NULL) {
3382+ cfg = ap_get_module_config(master->conn_config, mpm);
3383+@@ -342,38 +342,38 @@ conn_rec *h2_slave_create(conn_rec *mast
3384+ }
3385+
3386+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
3387+- "h2_slave(%s): created", c->log_id);
3388++ "h2_secondary(%s): created", c->log_id);
3389+ return c;
3390+ }
3391+
3392+-void h2_slave_destroy(conn_rec *slave)
3393++void h2_secondary_destroy(conn_rec *secondary)
3394+ {
3395+- ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, slave,
3396+- "h2_slave(%s): destroy", slave->log_id);
3397+- slave->sbh = NULL;
3398+- apr_pool_destroy(slave->pool);
3399++ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, secondary,
3400++ "h2_secondary(%s): destroy", secondary->log_id);
3401++ secondary->sbh = NULL;
3402++ apr_pool_destroy(secondary->pool);
3403+ }
3404+
3405+-apr_status_t h2_slave_run_pre_connection(conn_rec *slave, apr_socket_t *csd)
3406++apr_status_t h2_secondary_run_pre_connection(conn_rec *secondary, apr_socket_t *csd)
3407+ {
3408+- if (slave->keepalives == 0) {
3409++ if (secondary->keepalives == 0) {
3410+ /* Simulate that we had already a request on this connection. Some
3411+ * hooks trigger special behaviour when keepalives is 0.
3412+ * (Not necessarily in pre_connection, but later. Set it here, so it
3413+ * is in place.) */
3414+- slave->keepalives = 1;
3415++ secondary->keepalives = 1;
3416+ /* We signal that this connection will be closed after the request.
3417+ * Which is true in that sense that we throw away all traffic data
3418+- * on this slave connection after each requests. Although we might
3419++ * on this secondary connection after each requests. Although we might
3420+ * reuse internal structures like memory pools.
3421+ * The wanted effect of this is that httpd does not try to clean up
3422+ * any dangling data on this connection when a request is done. Which
3423+ * is unneccessary on a h2 stream.
3424+ */
3425+- slave->keepalive = AP_CONN_CLOSE;
3426+- return ap_run_pre_connection(slave, csd);
3427++ secondary->keepalive = AP_CONN_CLOSE;
3428++ return ap_run_pre_connection(secondary, csd);
3429+ }
3430+- ap_assert(slave->output_filters);
3431++ ap_assert(secondary->output_filters);
3432+ return APR_SUCCESS;
3433+ }
3434+
3435+--- a/modules/http2/h2_conn.h
3436++++ b/modules/http2/h2_conn.h
3437+@@ -68,10 +68,10 @@ h2_mpm_type_t h2_conn_mpm_type(void);
3438+ const char *h2_conn_mpm_name(void);
3439+ int h2_mpm_supported(void);
3440+
3441+-conn_rec *h2_slave_create(conn_rec *master, int slave_id, apr_pool_t *parent);
3442+-void h2_slave_destroy(conn_rec *slave);
3443++conn_rec *h2_secondary_create(conn_rec *master, int sec_id, apr_pool_t *parent);
3444++void h2_secondary_destroy(conn_rec *secondary);
3445+
3446+-apr_status_t h2_slave_run_pre_connection(conn_rec *slave, apr_socket_t *csd);
3447+-void h2_slave_run_connection(conn_rec *slave);
3448++apr_status_t h2_secondary_run_pre_connection(conn_rec *secondary, apr_socket_t *csd);
3449++void h2_secondary_run_connection(conn_rec *secondary);
3450+
3451+ #endif /* defined(__mod_h2__h2_conn__) */
3452+--- a/modules/http2/h2_filter.c
3453++++ b/modules/http2/h2_filter.c
3454+@@ -370,7 +370,7 @@ static void add_streams(apr_bucket_briga
3455+ x.s = s;
3456+ x.idx = 0;
3457+ bbout(bb, " \"streams\": {");
3458+- h2_mplx_stream_do(s->mplx, add_stream, &x);
3459++ h2_mplx_m_stream_do(s->mplx, add_stream, &x);
3460+ bbout(bb, "\n }%s\n", last? "" : ",");
3461+ }
3462+
3463+@@ -433,7 +433,7 @@ static void add_stats(apr_bucket_brigade
3464+ static apr_status_t h2_status_insert(h2_task *task, apr_bucket *b)
3465+ {
3466+ h2_mplx *m = task->mplx;
3467+- h2_stream *stream = h2_mplx_stream_get(m, task->stream_id);
3468++ h2_stream *stream = h2_mplx_t_stream_get(m, task);
3469+ h2_session *s;
3470+ conn_rec *c;
3471+
3472+--- a/modules/http2/h2_h2.c
3473++++ b/modules/http2/h2_h2.c
3474+@@ -668,7 +668,7 @@ static int h2_h2_pre_close_conn(conn_rec
3475+ {
3476+ h2_ctx *ctx;
3477+
3478+- /* slave connection? */
3479++ /* secondary connection? */
3480+ if (c->master) {
3481+ return DECLINED;
3482+ }
3483+@@ -712,7 +712,7 @@ static void check_push(request_rec *r, c
3484+
3485+ static int h2_h2_post_read_req(request_rec *r)
3486+ {
3487+- /* slave connection? */
3488++ /* secondary connection? */
3489+ if (r->connection->master) {
3490+ struct h2_task *task = h2_ctx_get_task(r->connection);
3491+ /* This hook will get called twice on internal redirects. Take care
3492+@@ -731,7 +731,7 @@ static int h2_h2_post_read_req(request_r
3493+ ap_add_output_filter("H2_RESPONSE", task, r, r->connection);
3494+
3495+ for (f = r->input_filters; f; f = f->next) {
3496+- if (!strcmp("H2_SLAVE_IN", f->frec->name)) {
3497++ if (!strcmp("H2_SECONDARY_IN", f->frec->name)) {
3498+ f->r = r;
3499+ break;
3500+ }
3501+@@ -745,7 +745,7 @@ static int h2_h2_post_read_req(request_r
3502+
3503+ static int h2_h2_late_fixups(request_rec *r)
3504+ {
3505+- /* slave connection? */
3506++ /* secondary connection? */
3507+ if (r->connection->master) {
3508+ struct h2_task *task = h2_ctx_get_task(r->connection);
3509+ if (task) {
3510+@@ -753,7 +753,7 @@ static int h2_h2_late_fixups(request_rec
3511+ task->output.copy_files = h2_config_rgeti(r, H2_CONF_COPY_FILES);
3512+ if (task->output.copy_files) {
3513+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, task->c,
3514+- "h2_slave_out(%s): copy_files on", task->id);
3515++ "h2_secondary_out(%s): copy_files on", task->id);
3516+ h2_beam_on_file_beam(task->output.beam, h2_beam_no_files, NULL);
3517+ }
3518+ check_push(r, "late_fixup");
3519+--- a/modules/http2/h2_mplx.c
3520++++ b/modules/http2/h2_mplx.c
3521+@@ -56,10 +56,18 @@ typedef struct {
3522+ apr_size_t count;
3523+ } stream_iter_ctx;
3524+
3525+-static apr_status_t mplx_be_happy(h2_mplx *m);
3526+-static apr_status_t mplx_be_annoyed(h2_mplx *m);
3527++/**
3528++ * Naming convention for static functions:
3529++ * - m_*: function only called from the master connection
3530++ * - s_*: function only called from a secondary connection
3531++ * - t_*: function only called from a h2_task holder
3532++ * - mst_*: function called from everyone
3533++ */
3534+
3535+-apr_status_t h2_mplx_child_init(apr_pool_t *pool, server_rec *s)
3536++static apr_status_t s_mplx_be_happy(h2_mplx *m, h2_task *task);
3537++static apr_status_t m_be_annoyed(h2_mplx *m);
3538++
3539++apr_status_t h2_mplx_m_child_init(apr_pool_t *pool, server_rec *s)
3540+ {
3541+ return APR_SUCCESS;
3542+ }
3543+@@ -81,26 +89,25 @@ apr_status_t h2_mplx_child_init(apr_pool
3544+ #define H2_MPLX_LEAVE_MAYBE(m, dolock) \
3545+ if (dolock) apr_thread_mutex_unlock(m->lock)
3546+
3547+-static void check_data_for(h2_mplx *m, h2_stream *stream, int mplx_is_locked);
3548++static void mst_check_data_for(h2_mplx *m, h2_stream *stream, int mplx_is_locked);
3549+
3550+-static void stream_output_consumed(void *ctx,
3551+- h2_bucket_beam *beam, apr_off_t length)
3552++static void mst_stream_output_consumed(void *ctx, h2_bucket_beam *beam, apr_off_t length)
3553+ {
3554+ }
3555+
3556+-static void stream_input_ev(void *ctx, h2_bucket_beam *beam)
3557++static void mst_stream_input_ev(void *ctx, h2_bucket_beam *beam)
3558+ {
3559+ h2_stream *stream = ctx;
3560+ h2_mplx *m = stream->session->mplx;
3561+ apr_atomic_set32(&m->event_pending, 1);
3562+ }
3563+
3564+-static void stream_input_consumed(void *ctx, h2_bucket_beam *beam, apr_off_t length)
3565++static void m_stream_input_consumed(void *ctx, h2_bucket_beam *beam, apr_off_t length)
3566+ {
3567+ h2_stream_in_consumed(ctx, length);
3568+ }
3569+
3570+-static void stream_joined(h2_mplx *m, h2_stream *stream)
3571++static void ms_stream_joined(h2_mplx *m, h2_stream *stream)
3572+ {
3573+ ap_assert(!h2_task_has_started(stream->task) || stream->task->worker_done);
3574+
3575+@@ -109,7 +116,7 @@ static void stream_joined(h2_mplx *m, h2
3576+ h2_ihash_add(m->spurge, stream);
3577+ }
3578+
3579+-static void stream_cleanup(h2_mplx *m, h2_stream *stream)
3580++static void m_stream_cleanup(h2_mplx *m, h2_stream *stream)
3581+ {
3582+ ap_assert(stream->state == H2_SS_CLEANUP);
3583+
3584+@@ -128,7 +135,7 @@ static void stream_cleanup(h2_mplx *m, h
3585+ h2_iq_remove(m->q, stream->id);
3586+
3587+ if (!h2_task_has_started(stream->task) || stream->task->done_done) {
3588+- stream_joined(m, stream);
3589++ ms_stream_joined(m, stream);
3590+ }
3591+ else {
3592+ h2_ififo_remove(m->readyq, stream->id);
3593+@@ -150,8 +157,8 @@ static void stream_cleanup(h2_mplx *m, h
3594+ * their HTTP/1 cousins, the separate allocator seems to work better
3595+ * than protecting a shared h2_session one with an own lock.
3596+ */
3597+-h2_mplx *h2_mplx_create(conn_rec *c, server_rec *s, apr_pool_t *parent,
3598+- h2_workers *workers)
3599++h2_mplx *h2_mplx_m_create(conn_rec *c, server_rec *s, apr_pool_t *parent,
3600++ h2_workers *workers)
3601+ {
3602+ apr_status_t status = APR_SUCCESS;
3603+ apr_allocator_t *allocator;
3604+@@ -165,7 +172,7 @@ h2_mplx *h2_mplx_create(conn_rec *c, ser
3605+ m->s = s;
3606+
3607+ /* We create a pool with its own allocator to be used for
3608+- * processing slave connections. This is the only way to have the
3609++ * processing secondary connections. This is the only way to have the
3610+ * processing independant of its parent pool in the sense that it
3611+ * can work in another thread. Also, the new allocator needs its own
3612+ * mutex to synchronize sub-pools.
3613+@@ -217,12 +224,12 @@ h2_mplx *h2_mplx_create(conn_rec *c, ser
3614+ m->last_mood_change = apr_time_now();
3615+ m->mood_update_interval = apr_time_from_msec(100);
3616+
3617+- m->spare_slaves = apr_array_make(m->pool, 10, sizeof(conn_rec*));
3618++ m->spare_secondary = apr_array_make(m->pool, 10, sizeof(conn_rec*));
3619+ }
3620+ return m;
3621+ }
3622+
3623+-int h2_mplx_shutdown(h2_mplx *m)
3624++int h2_mplx_m_shutdown(h2_mplx *m)
3625+ {
3626+ int max_stream_started = 0;
3627+
3628+@@ -236,7 +243,7 @@ int h2_mplx_shutdown(h2_mplx *m)
3629+ return max_stream_started;
3630+ }
3631+
3632+-static int input_consumed_signal(h2_mplx *m, h2_stream *stream)
3633++static int m_input_consumed_signal(h2_mplx *m, h2_stream *stream)
3634+ {
3635+ if (stream->input) {
3636+ return h2_beam_report_consumption(stream->input);
3637+@@ -244,12 +251,12 @@ static int input_consumed_signal(h2_mplx
3638+ return 0;
3639+ }
3640+
3641+-static int report_consumption_iter(void *ctx, void *val)
3642++static int m_report_consumption_iter(void *ctx, void *val)
3643+ {
3644+ h2_stream *stream = val;
3645+ h2_mplx *m = ctx;
3646+
3647+- input_consumed_signal(m, stream);
3648++ m_input_consumed_signal(m, stream);
3649+ if (stream->state == H2_SS_CLOSED_L
3650+ && (!stream->task || stream->task->worker_done)) {
3651+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c,
3652+@@ -260,7 +267,7 @@ static int report_consumption_iter(void
3653+ return 1;
3654+ }
3655+
3656+-static int output_consumed_signal(h2_mplx *m, h2_task *task)
3657++static int s_output_consumed_signal(h2_mplx *m, h2_task *task)
3658+ {
3659+ if (task->output.beam) {
3660+ return h2_beam_report_consumption(task->output.beam);
3661+@@ -268,7 +275,7 @@ static int output_consumed_signal(h2_mpl
3662+ return 0;
3663+ }
3664+
3665+-static int stream_destroy_iter(void *ctx, void *val)
3666++static int m_stream_destroy_iter(void *ctx, void *val)
3667+ {
3668+ h2_mplx *m = ctx;
3669+ h2_stream *stream = val;
3670+@@ -278,7 +285,7 @@ static int stream_destroy_iter(void *ctx
3671+
3672+ if (stream->input) {
3673+ /* Process outstanding events before destruction */
3674+- input_consumed_signal(m, stream);
3675++ m_input_consumed_signal(m, stream);
3676+ h2_beam_log(stream->input, m->c, APLOG_TRACE2, "stream_destroy");
3677+ h2_beam_destroy(stream->input);
3678+ stream->input = NULL;
3679+@@ -286,12 +293,12 @@ static int stream_destroy_iter(void *ctx
3680+
3681+ if (stream->task) {
3682+ h2_task *task = stream->task;
3683+- conn_rec *slave;
3684+- int reuse_slave = 0;
3685++ conn_rec *secondary;
3686++ int reuse_secondary = 0;
3687+
3688+ stream->task = NULL;
3689+- slave = task->c;
3690+- if (slave) {
3691++ secondary = task->c;
3692++ if (secondary) {
3693+ /* On non-serialized requests, the IO logging has not accounted for any
3694+ * meta data send over the network: response headers and h2 frame headers. we
3695+ * counted this on the stream and need to add this now.
3696+@@ -300,26 +307,25 @@ static int stream_destroy_iter(void *ctx
3697+ if (task->request && !task->request->serialize && h2_task_logio_add_bytes_out) {
3698+ apr_off_t unaccounted = stream->out_frame_octets - stream->out_data_octets;
3699+ if (unaccounted > 0) {
3700+- h2_task_logio_add_bytes_out(slave, unaccounted);
3701++ h2_task_logio_add_bytes_out(secondary, unaccounted);
3702+ }
3703+ }
3704+
3705+- if (m->s->keep_alive_max == 0 || slave->keepalives < m->s->keep_alive_max) {
3706+- reuse_slave = ((m->spare_slaves->nelts < (m->limit_active * 3 / 2))
3707+- && !task->rst_error);
3708++ if (m->s->keep_alive_max == 0 || secondary->keepalives < m->s->keep_alive_max) {
3709++ reuse_secondary = ((m->spare_secondary->nelts < (m->limit_active * 3 / 2))
3710++ && !task->rst_error);
3711+ }
3712+
3713+- task->c = NULL;
3714+- if (reuse_slave) {
3715++ if (reuse_secondary) {
3716+ h2_beam_log(task->output.beam, m->c, APLOG_DEBUG,
3717+- APLOGNO(03385) "h2_task_destroy, reuse slave");
3718++ APLOGNO(03385) "h2_task_destroy, reuse secondary");
3719+ h2_task_destroy(task);
3720+- APR_ARRAY_PUSH(m->spare_slaves, conn_rec*) = slave;
3721++ APR_ARRAY_PUSH(m->spare_secondary, conn_rec*) = secondary;
3722+ }
3723+ else {
3724+ h2_beam_log(task->output.beam, m->c, APLOG_TRACE1,
3725+- "h2_task_destroy, destroy slave");
3726+- h2_slave_destroy(slave);
3727++ "h2_task_destroy, destroy secondary");
3728++ h2_secondary_destroy(secondary);
3729+ }
3730+ }
3731+ }
3732+@@ -327,11 +333,11 @@ static int stream_destroy_iter(void *ctx
3733+ return 0;
3734+ }
3735+
3736+-static void purge_streams(h2_mplx *m, int lock)
3737++static void m_purge_streams(h2_mplx *m, int lock)
3738+ {
3739+ if (!h2_ihash_empty(m->spurge)) {
3740+ H2_MPLX_ENTER_MAYBE(m, lock);
3741+- while (!h2_ihash_iter(m->spurge, stream_destroy_iter, m)) {
3742++ while (!h2_ihash_iter(m->spurge, m_stream_destroy_iter, m)) {
3743+ /* repeat until empty */
3744+ }
3745+ H2_MPLX_LEAVE_MAYBE(m, lock);
3746+@@ -343,13 +349,13 @@ typedef struct {
3747+ void *ctx;
3748+ } stream_iter_ctx_t;
3749+
3750+-static int stream_iter_wrap(void *ctx, void *stream)
3751++static int m_stream_iter_wrap(void *ctx, void *stream)
3752+ {
3753+ stream_iter_ctx_t *x = ctx;
3754+ return x->cb(stream, x->ctx);
3755+ }
3756+
3757+-apr_status_t h2_mplx_stream_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx)
3758++apr_status_t h2_mplx_m_stream_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx)
3759+ {
3760+ stream_iter_ctx_t x;
3761+
3762+@@ -357,13 +363,13 @@ apr_status_t h2_mplx_stream_do(h2_mplx *
3763+
3764+ x.cb = cb;
3765+ x.ctx = ctx;
3766+- h2_ihash_iter(m->streams, stream_iter_wrap, &x);
3767++ h2_ihash_iter(m->streams, m_stream_iter_wrap, &x);
3768+
3769+ H2_MPLX_LEAVE(m);
3770+ return APR_SUCCESS;
3771+ }
3772+
3773+-static int report_stream_iter(void *ctx, void *val) {
3774++static int m_report_stream_iter(void *ctx, void *val) {
3775+ h2_mplx *m = ctx;
3776+ h2_stream *stream = val;
3777+ h2_task *task = stream->task;
3778+@@ -388,7 +394,7 @@ static int report_stream_iter(void *ctx,
3779+ return 1;
3780+ }
3781+
3782+-static int unexpected_stream_iter(void *ctx, void *val) {
3783++static int m_unexpected_stream_iter(void *ctx, void *val) {
3784+ h2_mplx *m = ctx;
3785+ h2_stream *stream = val;
3786+ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, /* NO APLOGNO */
3787+@@ -397,7 +403,7 @@ static int unexpected_stream_iter(void *
3788+ return 1;
3789+ }
3790+
3791+-static int stream_cancel_iter(void *ctx, void *val) {
3792++static int m_stream_cancel_iter(void *ctx, void *val) {
3793+ h2_mplx *m = ctx;
3794+ h2_stream *stream = val;
3795+
3796+@@ -411,11 +417,11 @@ static int stream_cancel_iter(void *ctx,
3797+ h2_stream_rst(stream, H2_ERR_NO_ERROR);
3798+ /* All connection data has been sent, simulate cleanup */
3799+ h2_stream_dispatch(stream, H2_SEV_EOS_SENT);
3800+- stream_cleanup(m, stream);
3801++ m_stream_cleanup(m, stream);
3802+ return 0;
3803+ }
3804+
3805+-void h2_mplx_release_and_join(h2_mplx *m, apr_thread_cond_t *wait)
3806++void h2_mplx_m_release_and_join(h2_mplx *m, apr_thread_cond_t *wait)
3807+ {
3808+ apr_status_t status;
3809+ int i, wait_secs = 60, old_aborted;
3810+@@ -429,7 +435,7 @@ void h2_mplx_release_and_join(h2_mplx *m
3811+
3812+ H2_MPLX_ENTER_ALWAYS(m);
3813+
3814+- /* While really terminating any slave connections, treat the master
3815++ /* While really terminating any secondary connections, treat the master
3816+ * connection as aborted. It's not as if we could send any more data
3817+ * at this point. */
3818+ old_aborted = m->c->aborted;
3819+@@ -441,7 +447,7 @@ void h2_mplx_release_and_join(h2_mplx *m
3820+ "h2_mplx(%ld): release, %d/%d/%d streams (total/hold/purge), %d active tasks",
3821+ m->id, (int)h2_ihash_count(m->streams),
3822+ (int)h2_ihash_count(m->shold), (int)h2_ihash_count(m->spurge), m->tasks_active);
3823+- while (!h2_ihash_iter(m->streams, stream_cancel_iter, m)) {
3824++ while (!h2_ihash_iter(m->streams, m_stream_cancel_iter, m)) {
3825+ /* until empty */
3826+ }
3827+
3828+@@ -463,7 +469,7 @@ void h2_mplx_release_and_join(h2_mplx *m
3829+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, APLOGNO(03198)
3830+ "h2_mplx(%ld): waited %d sec for %d tasks",
3831+ m->id, i*wait_secs, (int)h2_ihash_count(m->shold));
3832+- h2_ihash_iter(m->shold, report_stream_iter, m);
3833++ h2_ihash_iter(m->shold, m_report_stream_iter, m);
3834+ }
3835+ }
3836+ m->join_wait = NULL;
3837+@@ -474,7 +480,7 @@ void h2_mplx_release_and_join(h2_mplx *m
3838+ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, APLOGNO(03516)
3839+ "h2_mplx(%ld): unexpected %d streams in hold",
3840+ m->id, (int)h2_ihash_count(m->shold));
3841+- h2_ihash_iter(m->shold, unexpected_stream_iter, m);
3842++ h2_ihash_iter(m->shold, m_unexpected_stream_iter, m);
3843+ }
3844+
3845+ m->c->aborted = old_aborted;
3846+@@ -483,39 +489,39 @@ void h2_mplx_release_and_join(h2_mplx *m
3847+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c, "h2_mplx(%ld): released", m->id);
3848+ }
3849+
3850+-apr_status_t h2_mplx_stream_cleanup(h2_mplx *m, h2_stream *stream)
3851++apr_status_t h2_mplx_m_stream_cleanup(h2_mplx *m, h2_stream *stream)
3852+ {
3853+ H2_MPLX_ENTER(m);
3854+
3855+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
3856+ H2_STRM_MSG(stream, "cleanup"));
3857+- stream_cleanup(m, stream);
3858++ m_stream_cleanup(m, stream);
3859+
3860+ H2_MPLX_LEAVE(m);
3861+ return APR_SUCCESS;
3862+ }
3863+
3864+-h2_stream *h2_mplx_stream_get(h2_mplx *m, int id)
3865++h2_stream *h2_mplx_t_stream_get(h2_mplx *m, h2_task *task)
3866+ {
3867+ h2_stream *s = NULL;
3868+
3869+ H2_MPLX_ENTER_ALWAYS(m);
3870+
3871+- s = h2_ihash_get(m->streams, id);
3872++ s = h2_ihash_get(m->streams, task->stream_id);
3873+
3874+ H2_MPLX_LEAVE(m);
3875+ return s;
3876+ }
3877+
3878+-static void output_produced(void *ctx, h2_bucket_beam *beam, apr_off_t bytes)
3879++static void mst_output_produced(void *ctx, h2_bucket_beam *beam, apr_off_t bytes)
3880+ {
3881+ h2_stream *stream = ctx;
3882+ h2_mplx *m = stream->session->mplx;
3883+
3884+- check_data_for(m, stream, 0);
3885++ mst_check_data_for(m, stream, 0);
3886+ }
3887+
3888+-static apr_status_t out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam)
3889++static apr_status_t t_out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam)
3890+ {
3891+ h2_stream *stream = h2_ihash_get(m->streams, stream_id);
3892+
3893+@@ -527,26 +533,26 @@ static apr_status_t out_open(h2_mplx *m,
3894+ stream->output = beam;
3895+
3896+ if (APLOGctrace2(m->c)) {
3897+- h2_beam_log(beam, m->c, APLOG_TRACE2, "out_open");
3898++ h2_beam_log(beam, stream->task->c, APLOG_TRACE2, "out_open");
3899+ }
3900+ else {
3901+- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
3902++ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->task->c,
3903+ "h2_mplx(%s): out open", stream->task->id);
3904+ }
3905+
3906+- h2_beam_on_consumed(stream->output, NULL, stream_output_consumed, stream);
3907+- h2_beam_on_produced(stream->output, output_produced, stream);
3908++ h2_beam_on_consumed(stream->output, NULL, mst_stream_output_consumed, stream);
3909++ h2_beam_on_produced(stream->output, mst_output_produced, stream);
3910+ if (stream->task->output.copy_files) {
3911+ h2_beam_on_file_beam(stream->output, h2_beam_no_files, NULL);
3912+ }
3913+
3914+ /* we might see some file buckets in the output, see
3915+ * if we have enough handles reserved. */
3916+- check_data_for(m, stream, 1);
3917++ mst_check_data_for(m, stream, 1);
3918+ return APR_SUCCESS;
3919+ }
3920+
3921+-apr_status_t h2_mplx_out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam)
3922++apr_status_t h2_mplx_t_out_open(h2_mplx *m, int stream_id, h2_bucket_beam *beam)
3923+ {
3924+ apr_status_t status;
3925+
3926+@@ -556,14 +562,14 @@ apr_status_t h2_mplx_out_open(h2_mplx *m
3927+ status = APR_ECONNABORTED;
3928+ }
3929+ else {
3930+- status = out_open(m, stream_id, beam);
3931++ status = t_out_open(m, stream_id, beam);
3932+ }
3933+
3934+ H2_MPLX_LEAVE(m);
3935+ return status;
3936+ }
3937+
3938+-static apr_status_t out_close(h2_mplx *m, h2_task *task)
3939++static apr_status_t s_out_close(h2_mplx *m, h2_task *task)
3940+ {
3941+ apr_status_t status = APR_SUCCESS;
3942+ h2_stream *stream;
3943+@@ -580,17 +586,17 @@ static apr_status_t out_close(h2_mplx *m
3944+ return APR_ECONNABORTED;
3945+ }
3946+
3947+- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, m->c,
3948++ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, task->c,
3949+ "h2_mplx(%s): close", task->id);
3950+ status = h2_beam_close(task->output.beam);
3951+- h2_beam_log(task->output.beam, m->c, APLOG_TRACE2, "out_close");
3952+- output_consumed_signal(m, task);
3953+- check_data_for(m, stream, 1);
3954++ h2_beam_log(task->output.beam, task->c, APLOG_TRACE2, "out_close");
3955++ s_output_consumed_signal(m, task);
3956++ mst_check_data_for(m, stream, 1);
3957+ return status;
3958+ }
3959+
3960+-apr_status_t h2_mplx_out_trywait(h2_mplx *m, apr_interval_time_t timeout,
3961+- apr_thread_cond_t *iowait)
3962++apr_status_t h2_mplx_m_out_trywait(h2_mplx *m, apr_interval_time_t timeout,
3963++ apr_thread_cond_t *iowait)
3964+ {
3965+ apr_status_t status;
3966+
3967+@@ -599,12 +605,12 @@ apr_status_t h2_mplx_out_trywait(h2_mplx
3968+ if (m->aborted) {
3969+ status = APR_ECONNABORTED;
3970+ }
3971+- else if (h2_mplx_has_master_events(m)) {
3972++ else if (h2_mplx_m_has_master_events(m)) {
3973+ status = APR_SUCCESS;
3974+ }
3975+ else {
3976+- purge_streams(m, 0);
3977+- h2_ihash_iter(m->streams, report_consumption_iter, m);
3978++ m_purge_streams(m, 0);
3979++ h2_ihash_iter(m->streams, m_report_consumption_iter, m);
3980+ m->added_output = iowait;
3981+ status = apr_thread_cond_timedwait(m->added_output, m->lock, timeout);
3982+ if (APLOGctrace2(m->c)) {
3983+@@ -619,7 +625,7 @@ apr_status_t h2_mplx_out_trywait(h2_mplx
3984+ return status;
3985+ }
3986+
3987+-static void check_data_for(h2_mplx *m, h2_stream *stream, int mplx_is_locked)
3988++static void mst_check_data_for(h2_mplx *m, h2_stream *stream, int mplx_is_locked)
3989+ {
3990+ /* If m->lock is already held, we must release during h2_ififo_push()
3991+ * which can wait on its not_full condition, causing a deadlock because
3992+@@ -639,7 +645,7 @@ static void check_data_for(h2_mplx *m, h
3993+ }
3994+ }
3995+
3996+-apr_status_t h2_mplx_reprioritize(h2_mplx *m, h2_stream_pri_cmp *cmp, void *ctx)
3997++apr_status_t h2_mplx_m_reprioritize(h2_mplx *m, h2_stream_pri_cmp *cmp, void *ctx)
3998+ {
3999+ apr_status_t status;
4000+
4001+@@ -659,22 +665,22 @@ apr_status_t h2_mplx_reprioritize(h2_mpl
4002+ return status;
4003+ }
4004+
4005+-static void register_if_needed(h2_mplx *m)
4006++static void ms_register_if_needed(h2_mplx *m, int from_master)
4007+ {
4008+ if (!m->aborted && !m->is_registered && !h2_iq_empty(m->q)) {
4009+ apr_status_t status = h2_workers_register(m->workers, m);
4010+ if (status == APR_SUCCESS) {
4011+ m->is_registered = 1;
4012+ }
4013+- else {
4014++ else if (from_master) {
4015+ ap_log_cerror(APLOG_MARK, APLOG_ERR, status, m->c, APLOGNO(10021)
4016+ "h2_mplx(%ld): register at workers", m->id);
4017+ }
4018+ }
4019+ }
4020+
4021+-apr_status_t h2_mplx_process(h2_mplx *m, struct h2_stream *stream,
4022+- h2_stream_pri_cmp *cmp, void *ctx)
4023++apr_status_t h2_mplx_m_process(h2_mplx *m, struct h2_stream *stream,
4024++ h2_stream_pri_cmp *cmp, void *ctx)
4025+ {
4026+ apr_status_t status;
4027+
4028+@@ -688,13 +694,13 @@ apr_status_t h2_mplx_process(h2_mplx *m,
4029+ h2_ihash_add(m->streams, stream);
4030+ if (h2_stream_is_ready(stream)) {
4031+ /* already have a response */
4032+- check_data_for(m, stream, 1);
4033++ mst_check_data_for(m, stream, 1);
4034+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
4035+ H2_STRM_MSG(stream, "process, add to readyq"));
4036+ }
4037+ else {
4038+ h2_iq_add(m->q, stream->id, cmp, ctx);
4039+- register_if_needed(m);
4040++ ms_register_if_needed(m, 1);
4041+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
4042+ H2_STRM_MSG(stream, "process, added to q"));
4043+ }
4044+@@ -704,7 +710,7 @@ apr_status_t h2_mplx_process(h2_mplx *m,
4045+ return status;
4046+ }
4047+
4048+-static h2_task *next_stream_task(h2_mplx *m)
4049++static h2_task *s_next_stream_task(h2_mplx *m)
4050+ {
4051+ h2_stream *stream;
4052+ int sid;
4053+@@ -713,15 +719,15 @@ static h2_task *next_stream_task(h2_mplx
4054+
4055+ stream = h2_ihash_get(m->streams, sid);
4056+ if (stream) {
4057+- conn_rec *slave, **pslave;
4058++ conn_rec *secondary, **psecondary;
4059+
4060+- pslave = (conn_rec **)apr_array_pop(m->spare_slaves);
4061+- if (pslave) {
4062+- slave = *pslave;
4063+- slave->aborted = 0;
4064++ psecondary = (conn_rec **)apr_array_pop(m->spare_secondary);
4065++ if (psecondary) {
4066++ secondary = *psecondary;
4067++ secondary->aborted = 0;
4068+ }
4069+ else {
4070+- slave = h2_slave_create(m->c, stream->id, m->pool);
4071++ secondary = h2_secondary_create(m->c, stream->id, m->pool);
4072+ }
4073+
4074+ if (!stream->task) {
4075+@@ -729,16 +735,16 @@ static h2_task *next_stream_task(h2_mplx
4076+ m->max_stream_started = sid;
4077+ }
4078+ if (stream->input) {
4079+- h2_beam_on_consumed(stream->input, stream_input_ev,
4080+- stream_input_consumed, stream);
4081++ h2_beam_on_consumed(stream->input, mst_stream_input_ev,
4082++ m_stream_input_consumed, stream);
4083+ }
4084+
4085+- stream->task = h2_task_create(slave, stream->id,
4086++ stream->task = h2_task_create(secondary, stream->id,
4087+ stream->request, m, stream->input,
4088+ stream->session->s->timeout,
4089+ m->stream_max_mem);
4090+ if (!stream->task) {
4091+- ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, slave,
4092++ ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, secondary,
4093+ H2_STRM_LOG(APLOGNO(02941), stream,
4094+ "create task"));
4095+ return NULL;
4096+@@ -753,7 +759,7 @@ static h2_task *next_stream_task(h2_mplx
4097+ return NULL;
4098+ }
4099+
4100+-apr_status_t h2_mplx_pop_task(h2_mplx *m, h2_task **ptask)
4101++apr_status_t h2_mplx_s_pop_task(h2_mplx *m, h2_task **ptask)
4102+ {
4103+ apr_status_t rv = APR_EOF;
4104+
4105+@@ -769,7 +775,7 @@ apr_status_t h2_mplx_pop_task(h2_mplx *m
4106+ rv = APR_EOF;
4107+ }
4108+ else {
4109+- *ptask = next_stream_task(m);
4110++ *ptask = s_next_stream_task(m);
4111+ rv = (*ptask != NULL && !h2_iq_empty(m->q))? APR_EAGAIN : APR_SUCCESS;
4112+ }
4113+ if (APR_EAGAIN != rv) {
4114+@@ -779,22 +785,22 @@ apr_status_t h2_mplx_pop_task(h2_mplx *m
4115+ return rv;
4116+ }
4117+
4118+-static void task_done(h2_mplx *m, h2_task *task)
4119++static void s_task_done(h2_mplx *m, h2_task *task)
4120+ {
4121+ h2_stream *stream;
4122+
4123+- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
4124++ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, task->c,
4125+ "h2_mplx(%ld): task(%s) done", m->id, task->id);
4126+- out_close(m, task);
4127++ s_out_close(m, task);
4128+
4129+ task->worker_done = 1;
4130+ task->done_at = apr_time_now();
4131+- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
4132++ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, task->c,
4133+ "h2_mplx(%s): request done, %f ms elapsed", task->id,
4134+ (task->done_at - task->started_at) / 1000.0);
4135+
4136+ if (task->c && !task->c->aborted && task->started_at > m->last_mood_change) {
4137+- mplx_be_happy(m);
4138++ s_mplx_be_happy(m, task);
4139+ }
4140+
4141+ ap_assert(task->done_done == 0);
4142+@@ -806,60 +812,60 @@ static void task_done(h2_mplx *m, h2_tas
4143+ /* reset and schedule again */
4144+ h2_task_redo(task);
4145+ h2_iq_add(m->q, stream->id, NULL, NULL);
4146+- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, m->c,
4147++ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, task->c,
4148+ H2_STRM_MSG(stream, "redo, added to q"));
4149+ }
4150+ else {
4151+ /* stream not cleaned up, stay around */
4152+ task->done_done = 1;
4153+- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
4154++ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, task->c,
4155+ H2_STRM_MSG(stream, "task_done, stream open"));
4156+ if (stream->input) {
4157+ h2_beam_leave(stream->input);
4158+ }
4159+
4160+ /* more data will not arrive, resume the stream */
4161+- check_data_for(m, stream, 1);
4162++ mst_check_data_for(m, stream, 1);
4163+ }
4164+ }
4165+ else if ((stream = h2_ihash_get(m->shold, task->stream_id)) != NULL) {
4166+ /* stream is done, was just waiting for this. */
4167+ task->done_done = 1;
4168+- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
4169++ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, task->c,
4170+ H2_STRM_MSG(stream, "task_done, in hold"));
4171+ if (stream->input) {
4172+ h2_beam_leave(stream->input);
4173+ }
4174+- stream_joined(m, stream);
4175++ ms_stream_joined(m, stream);
4176+ }
4177+ else if ((stream = h2_ihash_get(m->spurge, task->stream_id)) != NULL) {
4178+- ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c,
4179++ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, task->c,
4180+ H2_STRM_LOG(APLOGNO(03517), stream, "already in spurge"));
4181+ ap_assert("stream should not be in spurge" == NULL);
4182+ }
4183+ else {
4184+- ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, m->c, APLOGNO(03518)
4185++ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, task->c, APLOGNO(03518)
4186+ "h2_mplx(%s): task_done, stream not found",
4187+ task->id);
4188+ ap_assert("stream should still be available" == NULL);
4189+ }
4190+ }
4191+
4192+-void h2_mplx_task_done(h2_mplx *m, h2_task *task, h2_task **ptask)
4193++void h2_mplx_s_task_done(h2_mplx *m, h2_task *task, h2_task **ptask)
4194+ {
4195+ H2_MPLX_ENTER_ALWAYS(m);
4196+
4197+ --m->tasks_active;
4198+- task_done(m, task);
4199++ s_task_done(m, task);
4200+
4201+ if (m->join_wait) {
4202+ apr_thread_cond_signal(m->join_wait);
4203+ }
4204+ if (ptask) {
4205+ /* caller wants another task */
4206+- *ptask = next_stream_task(m);
4207++ *ptask = s_next_stream_task(m);
4208+ }
4209+- register_if_needed(m);
4210++ ms_register_if_needed(m, 0);
4211+
4212+ H2_MPLX_LEAVE(m);
4213+ }
4214+@@ -868,7 +874,7 @@ void h2_mplx_task_done(h2_mplx *m, h2_ta
4215+ * h2_mplx DoS protection
4216+ ******************************************************************************/
4217+
4218+-static int timed_out_busy_iter(void *data, void *val)
4219++static int m_timed_out_busy_iter(void *data, void *val)
4220+ {
4221+ stream_iter_ctx *ctx = data;
4222+ h2_stream *stream = val;
4223+@@ -881,17 +887,17 @@ static int timed_out_busy_iter(void *dat
4224+ return 1;
4225+ }
4226+
4227+-static h2_stream *get_timed_out_busy_stream(h2_mplx *m)
4228++static h2_stream *m_get_timed_out_busy_stream(h2_mplx *m)
4229+ {
4230+ stream_iter_ctx ctx;
4231+ ctx.m = m;
4232+ ctx.stream = NULL;
4233+ ctx.now = apr_time_now();
4234+- h2_ihash_iter(m->streams, timed_out_busy_iter, &ctx);
4235++ h2_ihash_iter(m->streams, m_timed_out_busy_iter, &ctx);
4236+ return ctx.stream;
4237+ }
4238+
4239+-static int latest_repeatable_unsubmitted_iter(void *data, void *val)
4240++static int m_latest_repeatable_unsubmitted_iter(void *data, void *val)
4241+ {
4242+ stream_iter_ctx *ctx = data;
4243+ h2_stream *stream = val;
4244+@@ -917,7 +923,7 @@ leave:
4245+ return 1;
4246+ }
4247+
4248+-static apr_status_t assess_task_to_throttle(h2_task **ptask, h2_mplx *m)
4249++static apr_status_t m_assess_task_to_throttle(h2_task **ptask, h2_mplx *m)
4250+ {
4251+ stream_iter_ctx ctx;
4252+
4253+@@ -927,7 +933,7 @@ static apr_status_t assess_task_to_throt
4254+ ctx.m = m;
4255+ ctx.stream = NULL;
4256+ ctx.count = 0;
4257+- h2_ihash_iter(m->streams, latest_repeatable_unsubmitted_iter, &ctx);
4258++ h2_ihash_iter(m->streams, m_latest_repeatable_unsubmitted_iter, &ctx);
4259+ if (m->tasks_active - ctx.count > m->limit_active) {
4260+ /* we are above the limit of running tasks, accounting for the ones
4261+ * already throttled. */
4262+@@ -936,7 +942,7 @@ static apr_status_t assess_task_to_throt
4263+ return APR_EAGAIN;
4264+ }
4265+ /* above limit, be seeing no candidate for easy throttling */
4266+- if (get_timed_out_busy_stream(m)) {
4267++ if (m_get_timed_out_busy_stream(m)) {
4268+ /* Too many busy workers, unable to cancel enough streams
4269+ * and with a busy, timed out stream, we tell the client
4270+ * to go away... */
4271+@@ -946,7 +952,7 @@ static apr_status_t assess_task_to_throt
4272+ return APR_SUCCESS;
4273+ }
4274+
4275+-static apr_status_t unschedule_slow_tasks(h2_mplx *m)
4276++static apr_status_t m_unschedule_slow_tasks(h2_mplx *m)
4277+ {
4278+ h2_task *task;
4279+ apr_status_t rv;
4280+@@ -954,7 +960,7 @@ static apr_status_t unschedule_slow_task
4281+ /* Try to get rid of streams that occupy workers. Look for safe requests
4282+ * that are repeatable. If none found, fail the connection.
4283+ */
4284+- while (APR_EAGAIN == (rv = assess_task_to_throttle(&task, m))) {
4285++ while (APR_EAGAIN == (rv = m_assess_task_to_throttle(&task, m))) {
4286+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
4287+ "h2_mplx(%s): unschedule, resetting task for redo later",
4288+ task->id);
4289+@@ -965,7 +971,7 @@ static apr_status_t unschedule_slow_task
4290+ return rv;
4291+ }
4292+
4293+-static apr_status_t mplx_be_happy(h2_mplx *m)
4294++static apr_status_t s_mplx_be_happy(h2_mplx *m, h2_task *task)
4295+ {
4296+ apr_time_t now;
4297+
4298+@@ -977,14 +983,14 @@ static apr_status_t mplx_be_happy(h2_mpl
4299+ m->limit_active = H2MIN(m->limit_active * 2, m->max_active);
4300+ m->last_mood_change = now;
4301+ m->irritations_since = 0;
4302+- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
4303++ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, task->c,
4304+ "h2_mplx(%ld): mood update, increasing worker limit to %d",
4305+ m->id, m->limit_active);
4306+ }
4307+ return APR_SUCCESS;
4308+ }
4309+
4310+-static apr_status_t mplx_be_annoyed(h2_mplx *m)
4311++static apr_status_t m_be_annoyed(h2_mplx *m)
4312+ {
4313+ apr_status_t status = APR_SUCCESS;
4314+ apr_time_t now;
4315+@@ -1015,12 +1021,12 @@ static apr_status_t mplx_be_annoyed(h2_m
4316+ }
4317+
4318+ if (m->tasks_active > m->limit_active) {
4319+- status = unschedule_slow_tasks(m);
4320++ status = m_unschedule_slow_tasks(m);
4321+ }
4322+ return status;
4323+ }
4324+
4325+-apr_status_t h2_mplx_idle(h2_mplx *m)
4326++apr_status_t h2_mplx_m_idle(h2_mplx *m)
4327+ {
4328+ apr_status_t status = APR_SUCCESS;
4329+ apr_size_t scount;
4330+@@ -1042,7 +1048,7 @@ apr_status_t h2_mplx_idle(h2_mplx *m)
4331+ * of busy workers we allow for this connection until it
4332+ * well behaves.
4333+ */
4334+- status = mplx_be_annoyed(m);
4335++ status = m_be_annoyed(m);
4336+ }
4337+ else if (!h2_iq_empty(m->q)) {
4338+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
4339+@@ -1072,14 +1078,14 @@ apr_status_t h2_mplx_idle(h2_mplx *m)
4340+ h2_beam_is_closed(stream->output),
4341+ (long)h2_beam_get_buffered(stream->output));
4342+ h2_ihash_add(m->streams, stream);
4343+- check_data_for(m, stream, 1);
4344++ mst_check_data_for(m, stream, 1);
4345+ stream->out_checked = 1;
4346+ status = APR_EAGAIN;
4347+ }
4348+ }
4349+ }
4350+ }
4351+- register_if_needed(m);
4352++ ms_register_if_needed(m, 1);
4353+
4354+ H2_MPLX_LEAVE(m);
4355+ return status;
4356+@@ -1089,14 +1095,13 @@ apr_status_t h2_mplx_idle(h2_mplx *m)
4357+ * mplx master events dispatching
4358+ ******************************************************************************/
4359+
4360+-int h2_mplx_has_master_events(h2_mplx *m)
4361++int h2_mplx_m_has_master_events(h2_mplx *m)
4362+ {
4363+ return apr_atomic_read32(&m->event_pending) > 0;
4364+ }
4365+
4366+-apr_status_t h2_mplx_dispatch_master_events(h2_mplx *m,
4367+- stream_ev_callback *on_resume,
4368+- void *on_ctx)
4369++apr_status_t h2_mplx_m_dispatch_master_events(h2_mplx *m, stream_ev_callback *on_resume,
4370++ void *on_ctx)
4371+ {
4372+ h2_stream *stream;
4373+ int n, id;
4374+@@ -1106,8 +1111,8 @@ apr_status_t h2_mplx_dispatch_master_eve
4375+ apr_atomic_set32(&m->event_pending, 0);
4376+
4377+ /* update input windows for streams */
4378+- h2_ihash_iter(m->streams, report_consumption_iter, m);
4379+- purge_streams(m, 1);
4380++ h2_ihash_iter(m->streams, m_report_consumption_iter, m);
4381++ m_purge_streams(m, 1);
4382+
4383+ n = h2_ififo_count(m->readyq);
4384+ while (n > 0
4385+@@ -1122,13 +1127,13 @@ apr_status_t h2_mplx_dispatch_master_eve
4386+ return APR_SUCCESS;
4387+ }
4388+
4389+-apr_status_t h2_mplx_keep_active(h2_mplx *m, h2_stream *stream)
4390++apr_status_t h2_mplx_m_keep_active(h2_mplx *m, h2_stream *stream)
4391+ {
4392+- check_data_for(m, stream, 0);
4393++ mst_check_data_for(m, stream, 0);
4394+ return APR_SUCCESS;
4395+ }
4396+
4397+-int h2_mplx_awaits_data(h2_mplx *m)
4398++int h2_mplx_m_awaits_data(h2_mplx *m)
4399+ {
4400+ int waiting = 1;
4401+
4402+@@ -1145,7 +1150,7 @@ int h2_mplx_awaits_data(h2_mplx *m)
4403+ return waiting;
4404+ }
4405+
4406+-apr_status_t h2_mplx_client_rst(h2_mplx *m, int stream_id)
4407++apr_status_t h2_mplx_m_client_rst(h2_mplx *m, int stream_id)
4408+ {
4409+ h2_stream *stream;
4410+ apr_status_t status = APR_SUCCESS;
4411+@@ -1153,7 +1158,7 @@ apr_status_t h2_mplx_client_rst(h2_mplx
4412+ H2_MPLX_ENTER_ALWAYS(m);
4413+ stream = h2_ihash_get(m->streams, stream_id);
4414+ if (stream && stream->task) {
4415+- status = mplx_be_annoyed(m);
4416++ status = m_be_annoyed(m);
4417+ }
4418+ H2_MPLX_LEAVE(m);
4419+ return status;
4420+--- a/modules/http2/h2_mplx.h
4421++++ b/modules/http2/h2_mplx.h
4422+@@ -31,8 +31,10 @@
4423+ * queued in the multiplexer. If a task thread tries to write more
4424+ * data, it is blocked until space becomes available.
4425+ *
4426+- * Writing input is never blocked. In order to use flow control on the input,
4427+- * the mplx can be polled for input data consumption.
4428++ * Naming Convention:
4429++ * "h2_mplx_m_" are methods only to be called by the main connection
4430++ * "h2_mplx_s_" are method only to be called by a secondary connection
4431++ * "h2_mplx_t_" are method only to be called by a task handler (can be master or secondary)
4432+ */
4433+
4434+ struct apr_pool_t;
4435+@@ -88,25 +90,23 @@ struct h2_mplx {
4436+ apr_size_t stream_max_mem;
4437+
4438+ apr_pool_t *spare_io_pool;
4439+- apr_array_header_t *spare_slaves; /* spare slave connections */
4440++ apr_array_header_t *spare_secondary; /* spare secondary connections */
4441+
4442+ struct h2_workers *workers;
4443+ };
4444+
4445+-
4446+-
4447+ /*******************************************************************************
4448+- * Object lifecycle and information.
4449++ * From the main connection processing: h2_mplx_m_*
4450+ ******************************************************************************/
4451+
4452+-apr_status_t h2_mplx_child_init(apr_pool_t *pool, server_rec *s);
4453++apr_status_t h2_mplx_m_child_init(apr_pool_t *pool, server_rec *s);
4454+
4455+ /**
4456+ * Create the multiplexer for the given HTTP2 session.
4457+ * Implicitly has reference count 1.
4458+ */
4459+-h2_mplx *h2_mplx_create(conn_rec *c, server_rec *s, apr_pool_t *master,
4460+- struct h2_workers *workers);
4461++h2_mplx *h2_mplx_m_create(conn_rec *c, server_rec *s, apr_pool_t *master,
4462++ struct h2_workers *workers);
4463+
4464+ /**
4465+ * Decreases the reference counter of this mplx and waits for it
4466+@@ -116,26 +116,14 @@ h2_mplx *h2_mplx_create(conn_rec *c, ser
4467+ * @param m the mplx to be released and destroyed
4468+ * @param wait condition var to wait on for ref counter == 0
4469+ */
4470+-void h2_mplx_release_and_join(h2_mplx *m, struct apr_thread_cond_t *wait);
4471+-
4472+-apr_status_t h2_mplx_pop_task(h2_mplx *m, struct h2_task **ptask);
4473+-
4474+-void h2_mplx_task_done(h2_mplx *m, struct h2_task *task, struct h2_task **ptask);
4475++void h2_mplx_m_release_and_join(h2_mplx *m, struct apr_thread_cond_t *wait);
4476+
4477+ /**
4478+ * Shut down the multiplexer gracefully. Will no longer schedule new streams
4479+ * but let the ongoing ones finish normally.
4480+ * @return the highest stream id being/been processed
4481+ */
4482+-int h2_mplx_shutdown(h2_mplx *m);
4483+-
4484+-int h2_mplx_is_busy(h2_mplx *m);
4485+-
4486+-/*******************************************************************************
4487+- * IO lifetime of streams.
4488+- ******************************************************************************/
4489+-
4490+-struct h2_stream *h2_mplx_stream_get(h2_mplx *m, int id);
4491++int h2_mplx_m_shutdown(h2_mplx *m);
4492+
4493+ /**
4494+ * Notifies mplx that a stream has been completely handled on the main
4495+@@ -144,20 +132,16 @@ struct h2_stream *h2_mplx_stream_get(h2_
4496+ * @param m the mplx itself
4497+ * @param stream the stream ready for cleanup
4498+ */
4499+-apr_status_t h2_mplx_stream_cleanup(h2_mplx *m, struct h2_stream *stream);
4500++apr_status_t h2_mplx_m_stream_cleanup(h2_mplx *m, struct h2_stream *stream);
4501+
4502+ /**
4503+ * Waits on output data from any stream in this session to become available.
4504+ * Returns APR_TIMEUP if no data arrived in the given time.
4505+ */
4506+-apr_status_t h2_mplx_out_trywait(h2_mplx *m, apr_interval_time_t timeout,
4507+- struct apr_thread_cond_t *iowait);
4508+-
4509+-apr_status_t h2_mplx_keep_active(h2_mplx *m, struct h2_stream *stream);
4510++apr_status_t h2_mplx_m_out_trywait(h2_mplx *m, apr_interval_time_t timeout,
4511++ struct apr_thread_cond_t *iowait);
4512+
4513+-/*******************************************************************************
4514+- * Stream processing.
4515+- ******************************************************************************/
4516++apr_status_t h2_mplx_m_keep_active(h2_mplx *m, struct h2_stream *stream);
4517+
4518+ /**
4519+ * Process a stream request.
4520+@@ -168,8 +152,8 @@ apr_status_t h2_mplx_keep_active(h2_mplx
4521+ * @param cmp the stream priority compare function
4522+ * @param ctx context data for the compare function
4523+ */
4524+-apr_status_t h2_mplx_process(h2_mplx *m, struct h2_stream *stream,
4525+- h2_stream_pri_cmp *cmp, void *ctx);
4526++apr_status_t h2_mplx_m_process(h2_mplx *m, struct h2_stream *stream,
4527++ h2_stream_pri_cmp *cmp, void *ctx);
4528+
4529+ /**
4530+ * Stream priorities have changed, reschedule pending requests.
4531+@@ -178,7 +162,7 @@ apr_status_t h2_mplx_process(h2_mplx *m,
4532+ * @param cmp the stream priority compare function
4533+ * @param ctx context data for the compare function
4534+ */
4535+-apr_status_t h2_mplx_reprioritize(h2_mplx *m, h2_stream_pri_cmp *cmp, void *ctx);
4536++apr_status_t h2_mplx_m_reprioritize(h2_mplx *m, h2_stream_pri_cmp *cmp, void *ctx);
4537+
4538+ typedef apr_status_t stream_ev_callback(void *ctx, struct h2_stream *stream);
4539+
4540+@@ -186,7 +170,7 @@ typedef apr_status_t stream_ev_callback(
4541+ * Check if the multiplexer has events for the master connection pending.
4542+ * @return != 0 iff there are events pending
4543+ */
4544+-int h2_mplx_has_master_events(h2_mplx *m);
4545++int h2_mplx_m_has_master_events(h2_mplx *m);
4546+
4547+ /**
4548+ * Dispatch events for the master connection, such as
4549+@@ -194,108 +178,46 @@ int h2_mplx_has_master_events(h2_mplx *m
4550+ * @param on_resume new output data has arrived for a suspended stream
4551+ * @param ctx user supplied argument to invocation.
4552+ */
4553+-apr_status_t h2_mplx_dispatch_master_events(h2_mplx *m,
4554+- stream_ev_callback *on_resume,
4555+- void *ctx);
4556++apr_status_t h2_mplx_m_dispatch_master_events(h2_mplx *m, stream_ev_callback *on_resume,
4557++ void *ctx);
4558+
4559+-int h2_mplx_awaits_data(h2_mplx *m);
4560++int h2_mplx_m_awaits_data(h2_mplx *m);
4561+
4562+ typedef int h2_mplx_stream_cb(struct h2_stream *s, void *ctx);
4563+
4564+-apr_status_t h2_mplx_stream_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx);
4565++apr_status_t h2_mplx_m_stream_do(h2_mplx *m, h2_mplx_stream_cb *cb, void *ctx);
4566+
4567+-apr_status_t h2_mplx_client_rst(h2_mplx *m, int stream_id);
4568+-
4569+-/*******************************************************************************
4570+- * Output handling of streams.
4571+- ******************************************************************************/
4572++apr_status_t h2_mplx_m_client_rst(h2_mplx *m, int stream_id);
4573+
4574+ /**
4575+- * Opens the output for the given stream with the specified response.
4576++ * Master connection has entered idle mode.
4577++ * @param m the mplx instance of the master connection
4578++ * @return != SUCCESS iff connection should be terminated
4579+ */
4580+-apr_status_t h2_mplx_out_open(h2_mplx *mplx, int stream_id,
4581+- struct h2_bucket_beam *beam);
4582++apr_status_t h2_mplx_m_idle(h2_mplx *m);
4583+
4584+ /*******************************************************************************
4585+- * h2_mplx list Manipulation.
4586++ * From a secondary connection processing: h2_mplx_s_*
4587+ ******************************************************************************/
4588++apr_status_t h2_mplx_s_pop_task(h2_mplx *m, struct h2_task **ptask);
4589++void h2_mplx_s_task_done(h2_mplx *m, struct h2_task *task, struct h2_task **ptask);
4590+
4591+-/**
4592+- * The magic pointer value that indicates the head of a h2_mplx list
4593+- * @param b The mplx list
4594+- * @return The magic pointer value
4595+- */
4596+-#define H2_MPLX_LIST_SENTINEL(b) APR_RING_SENTINEL((b), h2_mplx, link)
4597+-
4598+-/**
4599+- * Determine if the mplx list is empty
4600+- * @param b The list to check
4601+- * @return true or false
4602+- */
4603+-#define H2_MPLX_LIST_EMPTY(b) APR_RING_EMPTY((b), h2_mplx, link)
4604+-
4605+-/**
4606+- * Return the first mplx in a list
4607+- * @param b The list to query
4608+- * @return The first mplx in the list
4609+- */
4610+-#define H2_MPLX_LIST_FIRST(b) APR_RING_FIRST(b)
4611+-
4612+-/**
4613+- * Return the last mplx in a list
4614+- * @param b The list to query
4615+- * @return The last mplx int he list
4616+- */
4617+-#define H2_MPLX_LIST_LAST(b) APR_RING_LAST(b)
4618+-
4619+-/**
4620+- * Insert a single mplx at the front of a list
4621+- * @param b The list to add to
4622+- * @param e The mplx to insert
4623+- */
4624+-#define H2_MPLX_LIST_INSERT_HEAD(b, e) do { \
4625+-h2_mplx *ap__b = (e); \
4626+-APR_RING_INSERT_HEAD((b), ap__b, h2_mplx, link); \
4627+-} while (0)
4628+-
4629+-/**
4630+- * Insert a single mplx at the end of a list
4631+- * @param b The list to add to
4632+- * @param e The mplx to insert
4633+- */
4634+-#define H2_MPLX_LIST_INSERT_TAIL(b, e) do { \
4635+-h2_mplx *ap__b = (e); \
4636+-APR_RING_INSERT_TAIL((b), ap__b, h2_mplx, link); \
4637+-} while (0)
4638++/*******************************************************************************
4639++ * From a h2_task owner: h2_mplx_s_*
4640++ * (a task is transfered from master to secondary connection and back in
4641++ * its normal lifetime).
4642++ ******************************************************************************/
4643+
4644+ /**
4645+- * Get the next mplx in the list
4646+- * @param e The current mplx
4647+- * @return The next mplx
4648+- */
4649+-#define H2_MPLX_NEXT(e) APR_RING_NEXT((e), link)
4650+-/**
4651+- * Get the previous mplx in the list
4652+- * @param e The current mplx
4653+- * @return The previous mplx
4654++ * Opens the output for the given stream with the specified response.
4655+ */
4656+-#define H2_MPLX_PREV(e) APR_RING_PREV((e), link)
4657++apr_status_t h2_mplx_t_out_open(h2_mplx *mplx, int stream_id,
4658++ struct h2_bucket_beam *beam);
4659+
4660+ /**
4661+- * Remove a mplx from its list
4662+- * @param e The mplx to remove
4663++ * Get the stream that belongs to the given task.
4664+ */
4665+-#define H2_MPLX_REMOVE(e) APR_RING_REMOVE((e), link)
4666+-
4667+-/*******************************************************************************
4668+- * h2_mplx DoS protection
4669+- ******************************************************************************/
4670++struct h2_stream *h2_mplx_t_stream_get(h2_mplx *m, struct h2_task *task);
4671+
4672+-/**
4673+- * Master connection has entered idle mode.
4674+- * @param m the mplx instance of the master connection
4675+- * @return != SUCCESS iff connection should be terminated
4676+- */
4677+-apr_status_t h2_mplx_idle(h2_mplx *m);
4678+
4679+ #endif /* defined(__mod_h2__h2_mplx__) */
4680+--- a/modules/http2/h2_request.c
4681++++ b/modules/http2/h2_request.c
4682+@@ -288,6 +288,9 @@ request_rec *h2_request_create_rec(const
4683+ if (r->method_number == M_GET && r->method[0] == 'H') {
4684+ r->header_only = 1;
4685+ }
4686++ r->the_request = apr_psprintf(r->pool, "%s %s HTTP/2.0",
4687++ req->method, req->path ? req->path : "");
4688++ r->headers_in = apr_table_clone(r->pool, req->headers);
4689+
4690+ rpath = (req->path ? req->path : "");
4691+ ap_parse_uri(r, rpath);
4692+@@ -304,7 +307,9 @@ request_rec *h2_request_create_rec(const
4693+ */
4694+ r->hostname = NULL;
4695+ ap_update_vhost_from_headers(r);
4696+-
4697++ r->protocol = "HTTP/2.0";
4698++ r->proto_num = HTTP_VERSION(2, 0);
4699++
4700+ /* we may have switched to another server */
4701+ r->per_dir_config = r->server->lookup_defaults;
4702+
4703+--- a/modules/http2/h2_session.c
4704++++ b/modules/http2/h2_session.c
4705+@@ -106,7 +106,7 @@ static int rst_unprocessed_stream(h2_str
4706+
4707+ static void cleanup_unprocessed_streams(h2_session *session)
4708+ {
4709+- h2_mplx_stream_do(session->mplx, rst_unprocessed_stream, session);
4710++ h2_mplx_m_stream_do(session->mplx, rst_unprocessed_stream, session);
4711+ }
4712+
4713+ static h2_stream *h2_session_open_stream(h2_session *session, int stream_id,
4714+@@ -397,7 +397,7 @@ static int on_frame_recv_cb(nghttp2_sess
4715+ else {
4716+ /* A stream reset on a request it sent us. Could happen in a browser
4717+ * when the user navigates away or cancels loading - maybe. */
4718+- h2_mplx_client_rst(session->mplx, frame->hd.stream_id);
4719++ h2_mplx_m_client_rst(session->mplx, frame->hd.stream_id);
4720+ ++session->streams_reset;
4721+ }
4722+ break;
4723+@@ -467,7 +467,7 @@ static int on_frame_recv_cb(nghttp2_sess
4724+ }
4725+
4726+ static int h2_session_continue_data(h2_session *session) {
4727+- if (h2_mplx_has_master_events(session->mplx)) {
4728++ if (h2_mplx_m_has_master_events(session->mplx)) {
4729+ return 0;
4730+ }
4731+ if (h2_conn_io_needs_flush(&session->io)) {
4732+@@ -729,7 +729,7 @@ static apr_status_t h2_session_shutdown(
4733+ * Remove all streams greater than this number without submitting
4734+ * a RST_STREAM frame, since that should be clear from the GOAWAY
4735+ * we send. */
4736+- session->local.accepted_max = h2_mplx_shutdown(session->mplx);
4737++ session->local.accepted_max = h2_mplx_m_shutdown(session->mplx);
4738+ session->local.error = error;
4739+ }
4740+ else {
4741+@@ -779,7 +779,7 @@ static apr_status_t session_cleanup(h2_s
4742+ }
4743+
4744+ transit(session, trigger, H2_SESSION_ST_CLEANUP);
4745+- h2_mplx_release_and_join(session->mplx, session->iowait);
4746++ h2_mplx_m_release_and_join(session->mplx, session->iowait);
4747+ session->mplx = NULL;
4748+
4749+ ap_assert(session->ngh2);
4750+@@ -800,7 +800,7 @@ static apr_status_t session_pool_cleanup
4751+ /* if the session is still there, now is the last chance
4752+ * to perform cleanup. Normally, cleanup should have happened
4753+ * earlier in the connection pre_close. Main reason is that
4754+- * any ongoing requests on slave connections might still access
4755++ * any ongoing requests on secondary connections might still access
4756+ * data which has, at this time, already been freed. An example
4757+ * is mod_ssl that uses request hooks. */
4758+ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c,
4759+@@ -893,7 +893,7 @@ apr_status_t h2_session_create(h2_sessio
4760+ session->monitor->on_state_event = on_stream_state_event;
4761+ session->monitor->on_event = on_stream_event;
4762+
4763+- session->mplx = h2_mplx_create(c, s, session->pool, workers);
4764++ session->mplx = h2_mplx_m_create(c, s, session->pool, workers);
4765+
4766+ /* connection input filter that feeds the session */
4767+ session->cin = h2_filter_cin_create(session);
4768+@@ -1552,7 +1552,7 @@ static void h2_session_in_flush(h2_sessi
4769+ if (stream) {
4770+ ap_assert(!stream->scheduled);
4771+ if (h2_stream_prep_processing(stream) == APR_SUCCESS) {
4772+- h2_mplx_process(session->mplx, stream, stream_pri_cmp, session);
4773++ h2_mplx_m_process(session->mplx, stream, stream_pri_cmp, session);
4774+ }
4775+ else {
4776+ h2_stream_rst(stream, H2_ERR_INTERNAL_ERROR);
4777+@@ -1824,7 +1824,7 @@ static void h2_session_ev_no_io(h2_sessi
4778+ session->open_streams);
4779+ h2_conn_io_flush(&session->io);
4780+ if (session->open_streams > 0) {
4781+- if (h2_mplx_awaits_data(session->mplx)) {
4782++ if (h2_mplx_m_awaits_data(session->mplx)) {
4783+ /* waiting for at least one stream to produce data */
4784+ transit(session, "no io", H2_SESSION_ST_WAIT);
4785+ }
4786+@@ -1983,7 +1983,7 @@ static void on_stream_state_enter(void *
4787+ break;
4788+ case H2_SS_CLEANUP:
4789+ nghttp2_session_set_stream_user_data(session->ngh2, stream->id, NULL);
4790+- h2_mplx_stream_cleanup(session->mplx, stream);
4791++ h2_mplx_m_stream_cleanup(session->mplx, stream);
4792+ break;
4793+ default:
4794+ break;
4795+@@ -2073,7 +2073,7 @@ static void dispatch_event(h2_session *s
4796+ static apr_status_t dispatch_master(h2_session *session) {
4797+ apr_status_t status;
4798+
4799+- status = h2_mplx_dispatch_master_events(session->mplx,
4800++ status = h2_mplx_m_dispatch_master_events(session->mplx,
4801+ on_stream_resume, session);
4802+ if (status == APR_EAGAIN) {
4803+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, status, session->c,
4804+@@ -2175,7 +2175,7 @@ apr_status_t h2_session_process(h2_sessi
4805+ session->have_read = 1;
4806+ }
4807+ else if (APR_STATUS_IS_EAGAIN(status) || APR_STATUS_IS_TIMEUP(status)) {
4808+- status = h2_mplx_idle(session->mplx);
4809++ status = h2_mplx_m_idle(session->mplx);
4810+ if (status == APR_EAGAIN) {
4811+ break;
4812+ }
4813+@@ -2205,7 +2205,7 @@ apr_status_t h2_session_process(h2_sessi
4814+ /* We wait in smaller increments, using a 1 second timeout.
4815+ * That gives us the chance to check for MPMQ_STOPPING often.
4816+ */
4817+- status = h2_mplx_idle(session->mplx);
4818++ status = h2_mplx_m_idle(session->mplx);
4819+ if (status == APR_EAGAIN) {
4820+ break;
4821+ }
4822+@@ -2319,7 +2319,7 @@ apr_status_t h2_session_process(h2_sessi
4823+ "h2_session: wait for data, %ld micros",
4824+ (long)session->wait_us);
4825+ }
4826+- status = h2_mplx_out_trywait(session->mplx, session->wait_us,
4827++ status = h2_mplx_m_out_trywait(session->mplx, session->wait_us,
4828+ session->iowait);
4829+ if (status == APR_SUCCESS) {
4830+ session->wait_us = 0;
4831+@@ -2356,7 +2356,7 @@ apr_status_t h2_session_process(h2_sessi
4832+ dispatch_event(session, H2_SESSION_EV_NGH2_DONE, 0, NULL);
4833+ }
4834+ if (session->reprioritize) {
4835+- h2_mplx_reprioritize(session->mplx, stream_pri_cmp, session);
4836++ h2_mplx_m_reprioritize(session->mplx, stream_pri_cmp, session);
4837+ session->reprioritize = 0;
4838+ }
4839+ }
4840+--- a/modules/http2/h2_session.h
4841++++ b/modules/http2/h2_session.h
4842+@@ -132,7 +132,7 @@ typedef struct h2_session {
4843+ const char *last_status_msg; /* the one already reported */
4844+
4845+ struct h2_iqueue *in_pending; /* all streams with input pending */
4846+- struct h2_iqueue *in_process; /* all streams ready for processing on slave */
4847++ struct h2_iqueue *in_process; /* all streams ready for processing on a secondary */
4848+
4849+ } h2_session;
4850+
4851+--- a/modules/http2/h2_stream.c
4852++++ b/modules/http2/h2_stream.c
4853+@@ -903,7 +903,7 @@ apr_status_t h2_stream_out_prepare(h2_st
4854+
4855+ if (status == APR_EAGAIN) {
4856+ /* TODO: ugly, someone needs to retrieve the response first */
4857+- h2_mplx_keep_active(stream->session->mplx, stream);
4858++ h2_mplx_m_keep_active(stream->session->mplx, stream);
4859+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
4860+ H2_STRM_MSG(stream, "prep, response eagain"));
4861+ return status;
4862+--- a/modules/http2/h2_task.c
4863++++ b/modules/http2/h2_task.c
4864+@@ -86,7 +86,7 @@ static apr_status_t open_output(h2_task
4865+ task->request->authority,
4866+ task->request->path);
4867+ task->output.opened = 1;
4868+- return h2_mplx_out_open(task->mplx, task->stream_id, task->output.beam);
4869++ return h2_mplx_t_out_open(task->mplx, task->stream_id, task->output.beam);
4870+ }
4871+
4872+ static apr_status_t send_out(h2_task *task, apr_bucket_brigade* bb, int block)
4873+@@ -126,8 +126,8 @@ static apr_status_t send_out(h2_task *ta
4874+ * request_rec out filter chain) into the h2_mplx for further sending
4875+ * on the master connection.
4876+ */
4877+-static apr_status_t slave_out(h2_task *task, ap_filter_t* f,
4878+- apr_bucket_brigade* bb)
4879++static apr_status_t secondary_out(h2_task *task, ap_filter_t* f,
4880++ apr_bucket_brigade* bb)
4881+ {
4882+ apr_bucket *b;
4883+ apr_status_t rv = APR_SUCCESS;
4884+@@ -175,7 +175,7 @@ send:
4885+ if (APR_SUCCESS == rv) {
4886+ /* could not write all, buffer the rest */
4887+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, task->c, APLOGNO(03405)
4888+- "h2_slave_out(%s): saving brigade", task->id);
4889++ "h2_secondary_out(%s): saving brigade", task->id);
4890+ ap_assert(NULL);
4891+ rv = ap_save_brigade(f, &task->output.bb, &bb, task->pool);
4892+ flush = 1;
4893+@@ -189,7 +189,7 @@ send:
4894+ }
4895+ out:
4896+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, task->c,
4897+- "h2_slave_out(%s): slave_out leave", task->id);
4898++ "h2_secondary_out(%s): secondary_out leave", task->id);
4899+ return rv;
4900+ }
4901+
4902+@@ -202,14 +202,14 @@ static apr_status_t output_finish(h2_tas
4903+ }
4904+
4905+ /*******************************************************************************
4906+- * task slave connection filters
4907++ * task secondary connection filters
4908+ ******************************************************************************/
4909+
4910+-static apr_status_t h2_filter_slave_in(ap_filter_t* f,
4911+- apr_bucket_brigade* bb,
4912+- ap_input_mode_t mode,
4913+- apr_read_type_e block,
4914+- apr_off_t readbytes)
4915++static apr_status_t h2_filter_secondary_in(ap_filter_t* f,
4916++ apr_bucket_brigade* bb,
4917++ ap_input_mode_t mode,
4918++ apr_read_type_e block,
4919++ apr_off_t readbytes)
4920+ {
4921+ h2_task *task;
4922+ apr_status_t status = APR_SUCCESS;
4923+@@ -224,7 +224,7 @@ static apr_status_t h2_filter_slave_in(a
4924+
4925+ if (trace1) {
4926+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
4927+- "h2_slave_in(%s): read, mode=%d, block=%d, readbytes=%ld",
4928++ "h2_secondary_in(%s): read, mode=%d, block=%d, readbytes=%ld",
4929+ task->id, mode, block, (long)readbytes);
4930+ }
4931+
4932+@@ -254,7 +254,7 @@ static apr_status_t h2_filter_slave_in(a
4933+ /* Get more input data for our request. */
4934+ if (trace1) {
4935+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c,
4936+- "h2_slave_in(%s): get more data from mplx, block=%d, "
4937++ "h2_secondary_in(%s): get more data from mplx, block=%d, "
4938+ "readbytes=%ld", task->id, block, (long)readbytes);
4939+ }
4940+ if (task->input.beam) {
4941+@@ -267,7 +267,7 @@ static apr_status_t h2_filter_slave_in(a
4942+
4943+ if (trace1) {
4944+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, f->c,
4945+- "h2_slave_in(%s): read returned", task->id);
4946++ "h2_secondary_in(%s): read returned", task->id);
4947+ }
4948+ if (APR_STATUS_IS_EAGAIN(status)
4949+ && (mode == AP_MODE_GETLINE || block == APR_BLOCK_READ)) {
4950+@@ -306,7 +306,7 @@ static apr_status_t h2_filter_slave_in(a
4951+ if (APR_BRIGADE_EMPTY(task->input.bb)) {
4952+ if (trace1) {
4953+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
4954+- "h2_slave_in(%s): no data", task->id);
4955++ "h2_secondary_in(%s): no data", task->id);
4956+ }
4957+ return (block == APR_NONBLOCK_READ)? APR_EAGAIN : APR_EOF;
4958+ }
4959+@@ -334,7 +334,7 @@ static apr_status_t h2_filter_slave_in(a
4960+ buffer[len] = 0;
4961+ if (trace1) {
4962+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c,
4963+- "h2_slave_in(%s): getline: %s",
4964++ "h2_secondary_in(%s): getline: %s",
4965+ task->id, buffer);
4966+ }
4967+ }
4968+@@ -344,7 +344,7 @@ static apr_status_t h2_filter_slave_in(a
4969+ * to support it. Seems to work. */
4970+ ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_ENOTIMPL, f->c,
4971+ APLOGNO(03472)
4972+- "h2_slave_in(%s), unsupported READ mode %d",
4973++ "h2_secondary_in(%s), unsupported READ mode %d",
4974+ task->id, mode);
4975+ status = APR_ENOTIMPL;
4976+ }
4977+@@ -352,19 +352,19 @@ static apr_status_t h2_filter_slave_in(a
4978+ if (trace1) {
4979+ apr_brigade_length(bb, 0, &bblen);
4980+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, f->c,
4981+- "h2_slave_in(%s): %ld data bytes", task->id, (long)bblen);
4982++ "h2_secondary_in(%s): %ld data bytes", task->id, (long)bblen);
4983+ }
4984+ return status;
4985+ }
4986+
4987+-static apr_status_t h2_filter_slave_output(ap_filter_t* filter,
4988+- apr_bucket_brigade* brigade)
4989++static apr_status_t h2_filter_secondary_output(ap_filter_t* filter,
4990++ apr_bucket_brigade* brigade)
4991+ {
4992+ h2_task *task = h2_ctx_get_task(filter->c);
4993+ apr_status_t status;
4994+
4995+ ap_assert(task);
4996+- status = slave_out(task, filter, brigade);
4997++ status = secondary_out(task, filter, brigade);
4998+ if (status != APR_SUCCESS) {
4999+ h2_task_rst(task, H2_ERR_INTERNAL_ERROR);
5000+ }
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches