[arch-commits] Commit in apache/repos (16 files)

Anatol Pomozov anatolik at archlinux.org
Wed Jul 5 17:14:17 UTC 2017


    Date: Wednesday, July 5, 2017 @ 17:14:16
  Author: anatolik
Revision: 299700

archrelease: copy trunk to testing-i686, testing-x86_64

Added:
  apache/repos/testing-i686/
  apache/repos/testing-i686/PKGBUILD
    (from rev 299699, apache/trunk/PKGBUILD)
  apache/repos/testing-i686/apache.tmpfiles.conf
    (from rev 299699, apache/trunk/apache.tmpfiles.conf)
  apache/repos/testing-i686/arch.layout
    (from rev 299699, apache/trunk/arch.layout)
  apache/repos/testing-i686/httpd.logrotate
    (from rev 299699, apache/trunk/httpd.logrotate)
  apache/repos/testing-i686/httpd.service
    (from rev 299699, apache/trunk/httpd.service)
  apache/repos/testing-i686/nohttp2forprefork.patch
    (from rev 299699, apache/trunk/nohttp2forprefork.patch)
  apache/repos/testing-i686/openssl-malloc-init.patch
    (from rev 299699, apache/trunk/openssl-malloc-init.patch)
  apache/repos/testing-x86_64/
  apache/repos/testing-x86_64/PKGBUILD
    (from rev 299699, apache/trunk/PKGBUILD)
  apache/repos/testing-x86_64/apache.tmpfiles.conf
    (from rev 299699, apache/trunk/apache.tmpfiles.conf)
  apache/repos/testing-x86_64/arch.layout
    (from rev 299699, apache/trunk/arch.layout)
  apache/repos/testing-x86_64/httpd.logrotate
    (from rev 299699, apache/trunk/httpd.logrotate)
  apache/repos/testing-x86_64/httpd.service
    (from rev 299699, apache/trunk/httpd.service)
  apache/repos/testing-x86_64/nohttp2forprefork.patch
    (from rev 299699, apache/trunk/nohttp2forprefork.patch)
  apache/repos/testing-x86_64/openssl-malloc-init.patch
    (from rev 299699, apache/trunk/openssl-malloc-init.patch)

------------------------------------------+
 testing-i686/PKGBUILD                    |  128 +++++++
 testing-i686/apache.tmpfiles.conf        |    1 
 testing-i686/arch.layout                 |   22 +
 testing-i686/httpd.logrotate             |    7 
 testing-i686/httpd.service               |   15 
 testing-i686/nohttp2forprefork.patch     |  506 +++++++++++++++++++++++++++++
 testing-i686/openssl-malloc-init.patch   |   20 +
 testing-x86_64/PKGBUILD                  |  128 +++++++
 testing-x86_64/apache.tmpfiles.conf      |    1 
 testing-x86_64/arch.layout               |   22 +
 testing-x86_64/httpd.logrotate           |    7 
 testing-x86_64/httpd.service             |   15 
 testing-x86_64/nohttp2forprefork.patch   |  506 +++++++++++++++++++++++++++++
 testing-x86_64/openssl-malloc-init.patch |   20 +
 14 files changed, 1398 insertions(+)

Copied: apache/repos/testing-i686/PKGBUILD (from rev 299699, apache/trunk/PKGBUILD)
===================================================================
--- testing-i686/PKGBUILD	                        (rev 0)
+++ testing-i686/PKGBUILD	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,128 @@
+# $Id$
+# Maintainer: Jan de Groot <jgc at archlinux.org>
+# Contributor: Andrea Scarpino <andrea at archlinux.org>
+# Contributor: Pierre Schmitz <pierre at archlinux.de>
+
+pkgname=apache
+pkgver=2.4.26
+pkgrel=2
+pkgdesc='A high performance Unix-based HTTP server'
+arch=('i686' 'x86_64')
+url='http://www.apache.org/dist/httpd'
+license=('APACHE')
+backup=(
+    etc/httpd/conf/httpd.conf
+    etc/httpd/conf/extra/httpd-{autoindex,dav,default,info,languages}.conf
+    etc/httpd/conf/extra/httpd-{manual,mpm,multilang-errordoc}.conf
+    etc/httpd/conf/extra/httpd-{ssl,userdir,vhosts}.conf
+    etc/httpd/conf/extra/proxy-html.conf
+    etc/httpd/conf/{mime.types,magic}
+    etc/logrotate.d/httpd
+)
+depends=('zlib' 'apr-util' 'pcre' 'libnghttp2' 'openssl')
+makedepends=('libxml2' 'lua')
+optdepends=(
+    'lua: for mod_lua module'
+    'libxml2: for mod_proxy_html, mod_xml2enc modules'
+    'lynx: apachectl status'
+)
+source=(
+    https://www.apache.org/dist/httpd/httpd-${pkgver}.tar.bz2{,.asc}
+    openssl-malloc-init.patch
+    apache.tmpfiles.conf
+    httpd.logrotate
+    httpd.service
+    arch.layout
+    nohttp2forprefork.patch # https://github.com/apache/httpd/commit/ab03196a879f4064f618a9a45d63c67a67f4b901
+)
+sha256sums=('a07eb52fafc879e0149d31882f7da63173e72df4478db4dc69f7a775b663d387'
+            'SKIP'
+            'd305f8b52ac2a9bbda7bb0776496471e69e9d30642740f594d00086a8c7e344c'
+            '63da1a420f4714a3e7af2672d28384419cc7eedbe7bf35baebd02938fabc15bf'
+            '0bbbfae23a917b2fce0bf8f900f60319b50769224a96314e9301a75ccd078e16'
+            'f574bac6d5f398e7a649fc0e1ca66ff01ad4ef34dac71258e93d8a9d9a2b3960'
+            'dda05c6e76f12624e418ca18a36f2e90ec1c5b1cc52fed7142fce6076ec413f3'
+            '25d297199c536ccfdb2c4d92988a74113ac2e14261090b5c1d3ac01537c5c742')
+validpgpkeys=('A93D62ECC3C8EA12DB220EC934EA76E6791485A8') # Jim Jagielski
+
+prepare() {
+  cd httpd-${pkgver}
+
+  # set default user
+  sed -e 's#User daemon#User http#' \
+      -e 's#Group daemon#Group http#' \
+      -i docs/conf/httpd.conf.in
+
+  cat "${srcdir}/arch.layout" >> config.layout
+
+  # https://github.com/openssl/openssl/issues/2865
+  patch -Np1 -i ../openssl-malloc-init.patch
+
+  # https://bugs.archlinux.org/task/54666
+  patch -Np1 -i ../nohttp2forprefork.patch
+}
+
+build() {
+  cd httpd-${pkgver}
+
+  ./configure --sbindir=/usr/bin \
+      --enable-layout=Arch \
+      --enable-mpms-shared=all \
+      --enable-modules=all \
+      --enable-mods-shared=all \
+      --enable-so \
+      --enable-suexec \
+      --with-suexec-caller=http \
+      --with-suexec-docroot=/srv/http \
+      --with-suexec-logfile=/var/log/httpd/suexec.log \
+      --with-suexec-bin=/usr/bin/suexec \
+      --with-suexec-uidmin=99 --with-suexec-gidmin=99 \
+      --enable-ldap --enable-authnz-ldap --enable-authnz-fcgi \
+      --enable-cache --enable-disk-cache --enable-mem-cache --enable-file-cache \
+      --enable-ssl --with-ssl \
+      --enable-deflate --enable-cgi --enable-cgid \
+      --enable-proxy --enable-proxy-connect \
+      --enable-proxy-http --enable-proxy-ftp \
+      --enable-dbd --enable-imagemap --enable-ident --enable-cern-meta \
+      --enable-lua --enable-xml2enc --enable-http2 \
+      --with-apr=/usr/bin/apr-1-config \
+      --with-apr-util=/usr/bin/apu-1-config \
+      --with-pcre=/usr
+
+  make
+}
+
+package() {
+  cd httpd-${pkgver}
+
+  make DESTDIR="${pkgdir}" install
+   
+  install -D -m644 "${srcdir}/httpd.logrotate" "${pkgdir}/etc/logrotate.d/httpd"
+  install -D -m644 "${srcdir}/apache.tmpfiles.conf" "${pkgdir}/usr/lib/tmpfiles.d/apache.conf"
+  install -D -m644 "${srcdir}/httpd.service" "${pkgdir}/usr/lib/systemd/system/httpd.service"	
+  install -D -m644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
+
+  # symlinks for /etc/httpd
+  # do we really need this symlink?
+  ln -fs /usr/lib/httpd/modules "${pkgdir}/etc/httpd/modules"
+
+  # set sane defaults
+  sed -e 's#/usr/lib/httpd/modules/#modules/#' \
+      -e 's|#\(LoadModule negotiation_module \)|\1|' \
+      -e 's|#\(LoadModule include_module \)|\1|' \
+      -e 's|#\(LoadModule userdir_module \)|\1|' \
+      -e 's|#\(LoadModule slotmem_shm_module \)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-multilang-errordoc.conf\)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-autoindex.conf\)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-languages.conf\)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-userdir.conf\)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-default.conf\)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-mpm.conf\)|\1|' \
+      -i "${pkgdir}/etc/httpd/conf/httpd.conf"
+
+  # cleanup
+  rm -r "${pkgdir}/usr/share/httpd/manual"
+  rm -r "${pkgdir}/etc/httpd/conf/original"
+  rm -r "${pkgdir}/srv/"
+  rm -r "${pkgdir}/run"
+}

Copied: apache/repos/testing-i686/apache.tmpfiles.conf (from rev 299699, apache/trunk/apache.tmpfiles.conf)
===================================================================
--- testing-i686/apache.tmpfiles.conf	                        (rev 0)
+++ testing-i686/apache.tmpfiles.conf	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1 @@
+d /run/httpd 0755 root root -

Copied: apache/repos/testing-i686/arch.layout (from rev 299699, apache/trunk/arch.layout)
===================================================================
--- testing-i686/arch.layout	                        (rev 0)
+++ testing-i686/arch.layout	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,22 @@
+<Layout Arch>
+	prefix:          /etc/httpd
+	exec_prefix:     /usr
+	bindir:          /usr/bin
+	sbindir:         /usr/bin
+	libdir:          /usr/lib/httpd
+	libexecdir:      /usr/lib/httpd/modules
+	mandir:          /usr/share/man
+	sysconfdir:      /etc/httpd/conf
+	datadir:         /usr/share/httpd
+	installbuilddir: /usr/lib/httpd/build
+	errordir:        /usr/share/httpd/error
+	iconsdir:        /usr/share/httpd/icons
+	htdocsdir:       /srv/http
+	manualdir:       /usr/share/httpd/manual
+	cgidir:          /srv/http/cgi-bin
+	includedir:      /usr/include/httpd
+	localstatedir:   /var
+	runtimedir:      /run/httpd
+	logfiledir:      /var/log/httpd
+	proxycachedir:   /var/cache/httpd
+</Layout>
\ No newline at end of file

Copied: apache/repos/testing-i686/httpd.logrotate (from rev 299699, apache/trunk/httpd.logrotate)
===================================================================
--- testing-i686/httpd.logrotate	                        (rev 0)
+++ testing-i686/httpd.logrotate	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,7 @@
+/var/log/httpd/*log {
+   missingok
+   sharedscripts
+   postrotate
+      /usr/bin/systemctl reload httpd.service 2>/dev/null || true
+   endscript
+}

Copied: apache/repos/testing-i686/httpd.service (from rev 299699, apache/trunk/httpd.service)
===================================================================
--- testing-i686/httpd.service	                        (rev 0)
+++ testing-i686/httpd.service	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,15 @@
+[Unit]
+Description=Apache Web Server
+After=network.target remote-fs.target nss-lookup.target
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/httpd -k start -DFOREGROUND
+ExecStop=/usr/bin/httpd -k graceful-stop
+ExecReload=/usr/bin/httpd -k graceful
+PrivateTmp=true
+LimitNOFILE=infinity
+KillMode=mixed
+
+[Install]
+WantedBy=multi-user.target

Copied: apache/repos/testing-i686/nohttp2forprefork.patch (from rev 299699, apache/trunk/nohttp2forprefork.patch)
===================================================================
--- testing-i686/nohttp2forprefork.patch	                        (rev 0)
+++ testing-i686/nohttp2forprefork.patch	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,506 @@
+From ab03196a879f4064f618a9a45d63c67a67f4b901 Mon Sep 17 00:00:00 2001
+From: Jim Jagielski <jim at apache.org>
+Date: Tue, 4 Jul 2017 12:34:15 +0000
+Subject: [PATCH] Merge r1800689 from trunk:
+
+On the trunk:
+
+mod_http2: disable and give warning when mpm_prefork is encountered.
+     The server will continue to work, but HTTP/2 will no longer be negotiated.
+
+
+Submitted by: icing
+Reviewed by: icing, ylavic, jim
+
+
+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1800774 13f79535-47bb-0310-9956-ffa450edef68
+---
+ modules/http2/h2_conn.c    |  21 +++++++-
+ modules/http2/h2_conn.h    |   3 +-
+ modules/http2/h2_mplx.c    |  37 +++++++-------
+ modules/http2/h2_mplx.h    |   2 +-
+ modules/http2/h2_session.c |   7 +--
+ modules/http2/h2_stream.c  |  14 +++++-
+ modules/http2/h2_switch.c  |   8 +++
+ modules/http2/h2_util.c    | 118 +++++++++++++++++++++------------------------
+ modules/http2/h2_workers.c |   7 +--
+ modules/http2/mod_http2.c  |  12 +++++
+ 12 files changed, 139 insertions(+), 99 deletions(-)
+
+diff --git a/modules/http2/h2_conn.c b/modules/http2/h2_conn.c
+index fcf6bad4d41..e2502c2f167 100644
+--- a/modules/http2/h2_conn.c
++++ b/modules/http2/h2_conn.c
+@@ -47,6 +47,7 @@ static struct h2_workers *workers;
+ static h2_mpm_type_t mpm_type = H2_MPM_UNKNOWN;
+ static module *mpm_module;
+ static int async_mpm;
++static int mpm_supported = 1;
+ static apr_socket_t *dummy_socket;
+ 
+ static void check_modules(int force) 
+@@ -76,11 +77,18 @@ static void check_modules(int force)
+             else if (!strcmp("prefork.c", m->name)) {
+                 mpm_type = H2_MPM_PREFORK;
+                 mpm_module = m;
++                /* While http2 can work really well on prefork, it collides
++                 * today's use case for prefork: runnning single-thread app engines
++                 * like php. If we restrict h2_workers to 1 per process, php will
++                 * work fine, but browser will be limited to 1 active request at a
++                 * time. */
++                mpm_supported = 0;
+                 break;
+             }
+             else if (!strcmp("simple_api.c", m->name)) {
+                 mpm_type = H2_MPM_SIMPLE;
+                 mpm_module = m;
++                mpm_supported = 0;
+                 break;
+             }
+             else if (!strcmp("mpm_winnt.c", m->name)) {
+@@ -107,7 +115,6 @@ apr_status_t h2_conn_child_init(apr_pool_t *pool, server_rec *s)
+     int idle_secs = 0;
+ 
+     check_modules(1);
+-    
+     ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads_per_child);
+     
+     status = ap_mpm_query(AP_MPMQ_IS_ASYNC, &async_mpm);
+@@ -157,6 +164,18 @@ h2_mpm_type_t h2_conn_mpm_type(void)
+     return mpm_type;
+ }
+ 
++const char *h2_conn_mpm_name(void)
++{
++    check_modules(0);
++    return mpm_module? mpm_module->name : "unknown";
++}
++
++int h2_mpm_supported(void)
++{
++    check_modules(0);
++    return mpm_supported;
++}
++
+ static module *h2_conn_mpm_module(void)
+ {
+     check_modules(0);
+diff --git a/modules/http2/h2_conn.h b/modules/http2/h2_conn.h
+index 79948644ae8..7111a6cd69c 100644
+--- a/modules/http2/h2_conn.h
++++ b/modules/http2/h2_conn.h
+@@ -64,7 +64,8 @@ typedef enum {
+ 
+ /* Returns the type of MPM module detected */
+ h2_mpm_type_t h2_conn_mpm_type(void);
+-
++const char *h2_conn_mpm_name(void);
++int h2_mpm_supported(void);
+ 
+ conn_rec *h2_slave_create(conn_rec *master, int slave_id, apr_pool_t *parent);
+ void h2_slave_destroy(conn_rec *slave);
+diff --git a/modules/http2/h2_mplx.c b/modules/http2/h2_mplx.c
+index b73bd0d5bfd..214d84ed1f9 100644
+--- a/modules/http2/h2_mplx.c
++++ b/modules/http2/h2_mplx.c
+@@ -481,9 +481,6 @@ void h2_mplx_release_and_join(h2_mplx *m, apr_thread_cond_t *wait)
+     
+     H2_MPLX_LEAVE(m);
+ 
+-    /* 5. unregister again, now that our workers are done */
+-    h2_workers_unregister(m->workers, m);
+-
+     ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
+                   "h2_mplx(%ld): released", m->id);
+ }
+@@ -662,7 +659,7 @@ apr_status_t h2_mplx_reprioritize(h2_mplx *m, h2_stream_pri_cmp *cmp, void *ctx)
+ 
+ static void register_if_needed(h2_mplx *m) 
+ {
+-    if (!m->is_registered && !h2_iq_empty(m->q)) {
++    if (!m->aborted && !m->is_registered && !h2_iq_empty(m->q)) {
+         apr_status_t status = h2_workers_register(m->workers, m); 
+         if (status == APR_SUCCESS) {
+             m->is_registered = 1;
+@@ -755,25 +752,27 @@ static h2_task *next_stream_task(h2_mplx *m)
+     return NULL;
+ }
+ 
+-h2_task *h2_mplx_pop_task(h2_mplx *m, int *has_more)
++apr_status_t h2_mplx_pop_task(h2_mplx *m, h2_task **ptask)
+ {
+-    h2_task *task = NULL;
++    apr_status_t rv = APR_EOF;
+     
+-    H2_MPLX_ENTER_ALWAYS(m);
+-
+-    *has_more = 0;
+-    if (!m->aborted) {
+-        task = next_stream_task(m);
+-        if (task != NULL && !h2_iq_empty(m->q)) {
+-            *has_more = 1;
+-        }
+-        else {
+-            m->is_registered = 0; /* h2_workers will discard this mplx */
+-        }
++    *ptask = NULL;
++    if (APR_SUCCESS != (rv = apr_thread_mutex_lock(m->lock))) {
++        return rv;
++    }
++    
++    if (m->aborted) {
++        rv = APR_EOF;
++    }
++    else {
++        *ptask = next_stream_task(m);
++        rv = (*ptask != NULL && !h2_iq_empty(m->q))? APR_EAGAIN : APR_SUCCESS;
++    }
++    if (APR_EAGAIN != rv) {
++        m->is_registered = 0; /* h2_workers will discard this mplx */
+     }
+-
+     H2_MPLX_LEAVE(m);
+-    return task;
++    return rv;
+ }
+ 
+ static void task_done(h2_mplx *m, h2_task *task, h2_req_engine *ngn)
+diff --git a/modules/http2/h2_mplx.h b/modules/http2/h2_mplx.h
+index 61b1b99aba7..d56c65289c2 100644
+--- a/modules/http2/h2_mplx.h
++++ b/modules/http2/h2_mplx.h
+@@ -124,7 +124,7 @@ h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *master,
+  */ 
+ void h2_mplx_release_and_join(h2_mplx *m, struct apr_thread_cond_t *wait);
+ 
+-struct h2_task *h2_mplx_pop_task(h2_mplx *mplx, int *has_more);
++apr_status_t h2_mplx_pop_task(h2_mplx *m, struct h2_task **ptask);
+ 
+ void h2_mplx_task_done(h2_mplx *m, struct h2_task *task, struct h2_task **ptask);
+ 
+diff --git a/modules/http2/h2_session.c b/modules/http2/h2_session.c
+index bc24bb41cdb..da85d7053fd 100644
+--- a/modules/http2/h2_session.c
++++ b/modules/http2/h2_session.c
+@@ -326,6 +326,7 @@ static int on_frame_recv_cb(nghttp2_session *ng2s,
+ {
+     h2_session *session = (h2_session *)userp;
+     h2_stream *stream;
++    apr_status_t rv = APR_SUCCESS;
+     
+     if (APLOGcdebug(session->c)) {
+         char buffer[256];
+@@ -346,7 +347,7 @@ static int on_frame_recv_cb(nghttp2_session *ng2s,
+              * trailers */
+             stream = h2_session_stream_get(session, frame->hd.stream_id);
+             if (stream) {
+-                h2_stream_recv_frame(stream, NGHTTP2_HEADERS, frame->hd.flags);
++                rv = h2_stream_recv_frame(stream, NGHTTP2_HEADERS, frame->hd.flags);
+             }
+             break;
+         case NGHTTP2_DATA:
+@@ -356,7 +357,7 @@ static int on_frame_recv_cb(nghttp2_session *ng2s,
+                               H2_STRM_LOG(APLOGNO(02923), stream, 
+                               "DATA, len=%ld, flags=%d"), 
+                               (long)frame->hd.length, frame->hd.flags);
+-                h2_stream_recv_frame(stream, NGHTTP2_DATA, frame->hd.flags);
++                rv = h2_stream_recv_frame(stream, NGHTTP2_DATA, frame->hd.flags);
+             }
+             break;
+         case NGHTTP2_PRIORITY:
+@@ -411,7 +412,7 @@ static int on_frame_recv_cb(nghttp2_session *ng2s,
+             }
+             break;
+     }
+-    return 0;
++    return (APR_SUCCESS == rv)? 0 : NGHTTP2_ERR_PROTO;
+ }
+ 
+ static int h2_session_continue_data(h2_session *session) {
+diff --git a/modules/http2/h2_stream.c b/modules/http2/h2_stream.c
+index 4cd2132207e..925f3d6d81d 100644
+--- a/modules/http2/h2_stream.c
++++ b/modules/http2/h2_stream.c
+@@ -444,7 +444,13 @@ apr_status_t h2_stream_recv_frame(h2_stream *stream, int ftype, int flags)
+             else {
+                 /* request HEADER */
+                 ap_assert(stream->request == NULL);
+-                ap_assert(stream->rtmp != NULL);
++                if (stream->rtmp == NULL) {
++                    /* This can only happen, if the stream has received no header
++                     * name/value pairs at all. The lastest nghttp2 version have become
++                     * pretty good at detecting this early. In any case, we have
++                     * to abort the connection here, since this is clearly a protocol error */
++                    return APR_EINVAL;
++                }
+                 status = h2_request_end_headers(stream->rtmp, stream->pool, eos);
+                 if (status != APR_SUCCESS) {
+                     return status;
+@@ -739,9 +745,13 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
+         status = h2_request_add_header(stream->rtmp, stream->pool,
+                                        name, nlen, value, vlen);
+     }
+-    else  {
++    else if (H2_SS_OPEN == stream->state) {
+         status = add_trailer(stream, name, nlen, value, vlen);
+     }
++    else {
++        status = APR_EINVAL;
++    }
++    
+     if (status != APR_SUCCESS) {
+         ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c,
+                       H2_STRM_MSG(stream, "header %s not accepted"), name);
+diff --git a/modules/http2/h2_switch.c b/modules/http2/h2_switch.c
+index 8a8d56e59ef..5b1247ec700 100644
+--- a/modules/http2/h2_switch.c
++++ b/modules/http2/h2_switch.c
+@@ -55,6 +55,10 @@ static int h2_protocol_propose(conn_rec *c, request_rec *r,
+     const char **protos = is_tls? h2_tls_protos : h2_clear_protos;
+     
+     (void)s;
++    if (!h2_mpm_supported()) {
++        return DECLINED;
++    }
++    
+     if (strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))) {
+         /* We do not know how to switch from anything else but http/1.1.
+          */
+@@ -127,6 +131,10 @@ static int h2_protocol_switch(conn_rec *c, request_rec *r, server_rec *s,
+     const char **p = protos;
+     
+     (void)s;
++    if (!h2_mpm_supported()) {
++        return DECLINED;
++    }
++
+     while (*p) {
+         if (!strcmp(*p, protocol)) {
+             found = 1;
+diff --git a/modules/http2/h2_util.c b/modules/http2/h2_util.c
+index 01b506ac854..04a9311424e 100644
+--- a/modules/http2/h2_util.c
++++ b/modules/http2/h2_util.c
+@@ -695,16 +695,47 @@ int h2_fifo_count(h2_fifo *fifo)
+ 
+ static apr_status_t check_not_empty(h2_fifo *fifo, int block)
+ {
+-    if (fifo->count == 0) {
++    while (fifo->count == 0) {
+         if (!block) {
+             return APR_EAGAIN;
+         }
+-        while (fifo->count == 0) {
+-            if (fifo->aborted) {
+-                return APR_EOF;
++        if (fifo->aborted) {
++            return APR_EOF;
++        }
++        apr_thread_cond_wait(fifo->not_empty, fifo->lock);
++    }
++    return APR_SUCCESS;
++}
++
++static apr_status_t fifo_push_int(h2_fifo *fifo, void *elem, int block)
++{
++    if (fifo->aborted) {
++        return APR_EOF;
++    }
++
++    if (fifo->set && index_of(fifo, elem) >= 0) {
++        /* set mode, elem already member */
++        return APR_EEXIST;
++    }
++    else if (fifo->count == fifo->nelems) {
++        if (block) {
++            while (fifo->count == fifo->nelems) {
++                if (fifo->aborted) {
++                    return APR_EOF;
++                }
++                apr_thread_cond_wait(fifo->not_full, fifo->lock);
+             }
+-            apr_thread_cond_wait(fifo->not_empty, fifo->lock);
+         }
++        else {
++            return APR_EAGAIN;
++        }
++    }
++    
++    ap_assert(fifo->count < fifo->nelems);
++    fifo->elems[nth_index(fifo, fifo->count)] = elem;
++    ++fifo->count;
++    if (fifo->count == 1) {
++        apr_thread_cond_broadcast(fifo->not_empty);
+     }
+     return APR_SUCCESS;
+ }
+@@ -718,33 +749,7 @@ static apr_status_t fifo_push(h2_fifo *fifo, void *elem, int block)
+     }
+ 
+     if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
+-        if (fifo->set && index_of(fifo, elem) >= 0) {
+-            /* set mode, elem already member */
+-            apr_thread_mutex_unlock(fifo->lock);
+-            return APR_EEXIST;
+-        }
+-        else if (fifo->count == fifo->nelems) {
+-            if (block) {
+-                while (fifo->count == fifo->nelems) {
+-                    if (fifo->aborted) {
+-                        apr_thread_mutex_unlock(fifo->lock);
+-                        return APR_EOF;
+-                    }
+-                    apr_thread_cond_wait(fifo->not_full, fifo->lock);
+-                }
+-            }
+-            else {
+-                apr_thread_mutex_unlock(fifo->lock);
+-                return APR_EAGAIN;
+-            }
+-        }
+-        
+-        ap_assert(fifo->count < fifo->nelems);
+-        fifo->elems[nth_index(fifo, fifo->count)] = elem;
+-        ++fifo->count;
+-        if (fifo->count == 1) {
+-            apr_thread_cond_broadcast(fifo->not_empty);
+-        }
++        rv = fifo_push_int(fifo, elem, block);
+         apr_thread_mutex_unlock(fifo->lock);
+     }
+     return rv;
+@@ -760,12 +765,15 @@ apr_status_t h2_fifo_try_push(h2_fifo *fifo, void *elem)
+     return fifo_push(fifo, elem, 0);
+ }
+ 
+-static void *pull_head(h2_fifo *fifo)
++static apr_status_t pull_head(h2_fifo *fifo, void **pelem, int block)
+ {
+-    void *elem;
++    apr_status_t rv;
+     
+-    ap_assert(fifo->count > 0);
+-    elem = fifo->elems[fifo->head];
++    if ((rv = check_not_empty(fifo, block)) != APR_SUCCESS) {
++        *pelem = NULL;
++        return rv;
++    }
++    *pelem = fifo->elems[fifo->head];
+     --fifo->count;
+     if (fifo->count > 0) {
+         fifo->head = nth_index(fifo, 1);
+@@ -773,7 +781,7 @@ static void *pull_head(h2_fifo *fifo)
+             apr_thread_cond_broadcast(fifo->not_full);
+         }
+     }
+-    return elem;
++    return APR_SUCCESS;
+ }
+ 
+ static apr_status_t fifo_pull(h2_fifo *fifo, void **pelem, int block)
+@@ -785,15 +793,7 @@ static apr_status_t fifo_pull(h2_fifo *fifo, void **pelem, int block)
+     }
+     
+     if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
+-        if ((rv = check_not_empty(fifo, block)) != APR_SUCCESS) {
+-            apr_thread_mutex_unlock(fifo->lock);
+-            *pelem = NULL;
+-            return rv;
+-        }
+-
+-        ap_assert(fifo->count > 0);
+-        *pelem = pull_head(fifo);
+-
++        rv = pull_head(fifo, pelem, block);
+         apr_thread_mutex_unlock(fifo->lock);
+     }
+     return rv;
+@@ -818,25 +818,17 @@ static apr_status_t fifo_peek(h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx, int
+         return APR_EOF;
+     }
+     
+-    if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
+-        if ((rv = check_not_empty(fifo, block)) != APR_SUCCESS) {
+-            apr_thread_mutex_unlock(fifo->lock);
+-            return rv;
++    if (APR_SUCCESS == (rv = apr_thread_mutex_lock(fifo->lock))) {
++        if (APR_SUCCESS == (rv = pull_head(fifo, &elem, block))) {
++            switch (fn(elem, ctx)) {
++                case H2_FIFO_OP_PULL:
++                    break;
++                case H2_FIFO_OP_REPUSH:
++                    rv = fifo_push_int(fifo, elem, block);
++                    break;
++            }
+         }
+-
+-        ap_assert(fifo->count > 0);
+-        elem = pull_head(fifo);
+-        
+         apr_thread_mutex_unlock(fifo->lock);
+-
+-        switch (fn(elem, ctx)) {
+-            case H2_FIFO_OP_PULL:
+-                break;
+-            case H2_FIFO_OP_REPUSH:
+-                return h2_fifo_push(fifo, elem);
+-                break;
+-        }
+-        
+     }
+     return rv;
+ }
+diff --git a/modules/http2/h2_workers.c b/modules/http2/h2_workers.c
+index 0bbb65223f7..5abddd4a1d5 100644
+--- a/modules/http2/h2_workers.c
++++ b/modules/http2/h2_workers.c
+@@ -150,15 +150,16 @@ static void cleanup_zombies(h2_workers *workers)
+ 
+ static apr_status_t slot_pull_task(h2_slot *slot, h2_mplx *m)
+ {
+-    int has_more;
+-    slot->task = h2_mplx_pop_task(m, &has_more);
++    apr_status_t rv;
++    
++    rv = h2_mplx_pop_task(m, &slot->task);
+     if (slot->task) {
+         /* Ok, we got something to give back to the worker for execution. 
+          * If we still have idle workers, we let the worker be sticky, 
+          * e.g. making it poll the task's h2_mplx instance for more work 
+          * before asking back here. */
+         slot->sticks = slot->workers->max_workers;
+-        return has_more? APR_EAGAIN : APR_SUCCESS;            
++        return rv;            
+     }
+     slot->sticks = 0;
+     return APR_EOF;
+diff --git a/modules/http2/mod_http2.c b/modules/http2/mod_http2.c
+index ea399c91a28..420e74c3363 100644
+--- a/modules/http2/mod_http2.c
++++ b/modules/http2/mod_http2.c
+@@ -65,6 +65,7 @@ typedef struct {
+ } features;
+ 
+ static features myfeats;
++static int mpm_warned;
+ 
+ /* The module initialization. Called once as apache hook, before any multi
+  * processing (threaded or not) happens. It is typically at least called twice, 
+@@ -141,6 +142,17 @@ static int h2_post_config(apr_pool_t *p, apr_pool_t *plog,
+             break;
+     }
+     
++    if (!h2_mpm_supported() && !mpm_warned) {
++        mpm_warned = 1;
++        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10034)
++                     "The mpm module (%s) is not supported by mod_http2. The mpm determines "
++                     "how things are processed in your server. HTTP/2 has more demands in "
++                     "this regard and the currently selected mpm will just not do. "
++                     "This is an advisory warning. Your server will continue to work, but "
++                     "the HTTP/2 protocol will be inactive.", 
++                     h2_conn_mpm_name());
++    }
++    
+     status = h2_h2_init(p, s);
+     if (status == APR_SUCCESS) {
+         status = h2_switch_init(p, s);

Copied: apache/repos/testing-i686/openssl-malloc-init.patch (from rev 299699, apache/trunk/openssl-malloc-init.patch)
===================================================================
--- testing-i686/openssl-malloc-init.patch	                        (rev 0)
+++ testing-i686/openssl-malloc-init.patch	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,20 @@
+--- httpd-2.4.25/support/ab.c.orig	2017-05-21 21:59:17.131193359 +0000
++++ httpd-2.4.25/support/ab.c	2017-05-21 22:01:34.704322361 +0000
+@@ -2496,6 +2496,8 @@
+         heartbeatres = 0;
+ 
+ #ifdef USE_SSL
++    SSL_load_error_strings();
++    SSL_library_init();
+ #ifdef RSAREF
+     R_malloc_init();
+ #else
+@@ -2505,8 +2507,6 @@
+     OPENSSL_malloc_init();
+ #endif
+ #endif
+-    SSL_load_error_strings();
+-    SSL_library_init();
+     bio_out=BIO_new_fp(stdout,BIO_NOCLOSE);
+     bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+ 

Copied: apache/repos/testing-x86_64/PKGBUILD (from rev 299699, apache/trunk/PKGBUILD)
===================================================================
--- testing-x86_64/PKGBUILD	                        (rev 0)
+++ testing-x86_64/PKGBUILD	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,128 @@
+# $Id$
+# Maintainer: Jan de Groot <jgc at archlinux.org>
+# Contributor: Andrea Scarpino <andrea at archlinux.org>
+# Contributor: Pierre Schmitz <pierre at archlinux.de>
+
+pkgname=apache
+pkgver=2.4.26
+pkgrel=2
+pkgdesc='A high performance Unix-based HTTP server'
+arch=('i686' 'x86_64')
+url='http://www.apache.org/dist/httpd'
+license=('APACHE')
+backup=(
+    etc/httpd/conf/httpd.conf
+    etc/httpd/conf/extra/httpd-{autoindex,dav,default,info,languages}.conf
+    etc/httpd/conf/extra/httpd-{manual,mpm,multilang-errordoc}.conf
+    etc/httpd/conf/extra/httpd-{ssl,userdir,vhosts}.conf
+    etc/httpd/conf/extra/proxy-html.conf
+    etc/httpd/conf/{mime.types,magic}
+    etc/logrotate.d/httpd
+)
+depends=('zlib' 'apr-util' 'pcre' 'libnghttp2' 'openssl')
+makedepends=('libxml2' 'lua')
+optdepends=(
+    'lua: for mod_lua module'
+    'libxml2: for mod_proxy_html, mod_xml2enc modules'
+    'lynx: apachectl status'
+)
+source=(
+    https://www.apache.org/dist/httpd/httpd-${pkgver}.tar.bz2{,.asc}
+    openssl-malloc-init.patch
+    apache.tmpfiles.conf
+    httpd.logrotate
+    httpd.service
+    arch.layout
+    nohttp2forprefork.patch # https://github.com/apache/httpd/commit/ab03196a879f4064f618a9a45d63c67a67f4b901
+)
+sha256sums=('a07eb52fafc879e0149d31882f7da63173e72df4478db4dc69f7a775b663d387'
+            'SKIP'
+            'd305f8b52ac2a9bbda7bb0776496471e69e9d30642740f594d00086a8c7e344c'
+            '63da1a420f4714a3e7af2672d28384419cc7eedbe7bf35baebd02938fabc15bf'
+            '0bbbfae23a917b2fce0bf8f900f60319b50769224a96314e9301a75ccd078e16'
+            'f574bac6d5f398e7a649fc0e1ca66ff01ad4ef34dac71258e93d8a9d9a2b3960'
+            'dda05c6e76f12624e418ca18a36f2e90ec1c5b1cc52fed7142fce6076ec413f3'
+            '25d297199c536ccfdb2c4d92988a74113ac2e14261090b5c1d3ac01537c5c742')
+validpgpkeys=('A93D62ECC3C8EA12DB220EC934EA76E6791485A8') # Jim Jagielski
+
+prepare() {
+  cd httpd-${pkgver}
+
+  # set default user
+  sed -e 's#User daemon#User http#' \
+      -e 's#Group daemon#Group http#' \
+      -i docs/conf/httpd.conf.in
+
+  cat "${srcdir}/arch.layout" >> config.layout
+
+  # https://github.com/openssl/openssl/issues/2865
+  patch -Np1 -i ../openssl-malloc-init.patch
+
+  # https://bugs.archlinux.org/task/54666
+  patch -Np1 -i ../nohttp2forprefork.patch
+}
+
+build() {
+  cd httpd-${pkgver}
+
+  ./configure --sbindir=/usr/bin \
+      --enable-layout=Arch \
+      --enable-mpms-shared=all \
+      --enable-modules=all \
+      --enable-mods-shared=all \
+      --enable-so \
+      --enable-suexec \
+      --with-suexec-caller=http \
+      --with-suexec-docroot=/srv/http \
+      --with-suexec-logfile=/var/log/httpd/suexec.log \
+      --with-suexec-bin=/usr/bin/suexec \
+      --with-suexec-uidmin=99 --with-suexec-gidmin=99 \
+      --enable-ldap --enable-authnz-ldap --enable-authnz-fcgi \
+      --enable-cache --enable-disk-cache --enable-mem-cache --enable-file-cache \
+      --enable-ssl --with-ssl \
+      --enable-deflate --enable-cgi --enable-cgid \
+      --enable-proxy --enable-proxy-connect \
+      --enable-proxy-http --enable-proxy-ftp \
+      --enable-dbd --enable-imagemap --enable-ident --enable-cern-meta \
+      --enable-lua --enable-xml2enc --enable-http2 \
+      --with-apr=/usr/bin/apr-1-config \
+      --with-apr-util=/usr/bin/apu-1-config \
+      --with-pcre=/usr
+
+  make
+}
+
+package() {
+  cd httpd-${pkgver}
+
+  make DESTDIR="${pkgdir}" install
+   
+  install -D -m644 "${srcdir}/httpd.logrotate" "${pkgdir}/etc/logrotate.d/httpd"
+  install -D -m644 "${srcdir}/apache.tmpfiles.conf" "${pkgdir}/usr/lib/tmpfiles.d/apache.conf"
+  install -D -m644 "${srcdir}/httpd.service" "${pkgdir}/usr/lib/systemd/system/httpd.service"	
+  install -D -m644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
+
+  # symlinks for /etc/httpd
+  # do we really need this symlink?
+  ln -fs /usr/lib/httpd/modules "${pkgdir}/etc/httpd/modules"
+
+  # set sane defaults
+  sed -e 's#/usr/lib/httpd/modules/#modules/#' \
+      -e 's|#\(LoadModule negotiation_module \)|\1|' \
+      -e 's|#\(LoadModule include_module \)|\1|' \
+      -e 's|#\(LoadModule userdir_module \)|\1|' \
+      -e 's|#\(LoadModule slotmem_shm_module \)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-multilang-errordoc.conf\)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-autoindex.conf\)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-languages.conf\)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-userdir.conf\)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-default.conf\)|\1|' \
+      -e 's|#\(Include conf/extra/httpd-mpm.conf\)|\1|' \
+      -i "${pkgdir}/etc/httpd/conf/httpd.conf"
+
+  # cleanup
+  rm -r "${pkgdir}/usr/share/httpd/manual"
+  rm -r "${pkgdir}/etc/httpd/conf/original"
+  rm -r "${pkgdir}/srv/"
+  rm -r "${pkgdir}/run"
+}

Copied: apache/repos/testing-x86_64/apache.tmpfiles.conf (from rev 299699, apache/trunk/apache.tmpfiles.conf)
===================================================================
--- testing-x86_64/apache.tmpfiles.conf	                        (rev 0)
+++ testing-x86_64/apache.tmpfiles.conf	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1 @@
+d /run/httpd 0755 root root -

Copied: apache/repos/testing-x86_64/arch.layout (from rev 299699, apache/trunk/arch.layout)
===================================================================
--- testing-x86_64/arch.layout	                        (rev 0)
+++ testing-x86_64/arch.layout	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,22 @@
+<Layout Arch>
+	prefix:          /etc/httpd
+	exec_prefix:     /usr
+	bindir:          /usr/bin
+	sbindir:         /usr/bin
+	libdir:          /usr/lib/httpd
+	libexecdir:      /usr/lib/httpd/modules
+	mandir:          /usr/share/man
+	sysconfdir:      /etc/httpd/conf
+	datadir:         /usr/share/httpd
+	installbuilddir: /usr/lib/httpd/build
+	errordir:        /usr/share/httpd/error
+	iconsdir:        /usr/share/httpd/icons
+	htdocsdir:       /srv/http
+	manualdir:       /usr/share/httpd/manual
+	cgidir:          /srv/http/cgi-bin
+	includedir:      /usr/include/httpd
+	localstatedir:   /var
+	runtimedir:      /run/httpd
+	logfiledir:      /var/log/httpd
+	proxycachedir:   /var/cache/httpd
+</Layout>
\ No newline at end of file

Copied: apache/repos/testing-x86_64/httpd.logrotate (from rev 299699, apache/trunk/httpd.logrotate)
===================================================================
--- testing-x86_64/httpd.logrotate	                        (rev 0)
+++ testing-x86_64/httpd.logrotate	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,7 @@
+/var/log/httpd/*log {
+   missingok
+   sharedscripts
+   postrotate
+      /usr/bin/systemctl reload httpd.service 2>/dev/null || true
+   endscript
+}

Copied: apache/repos/testing-x86_64/httpd.service (from rev 299699, apache/trunk/httpd.service)
===================================================================
--- testing-x86_64/httpd.service	                        (rev 0)
+++ testing-x86_64/httpd.service	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,15 @@
+[Unit]
+Description=Apache Web Server
+After=network.target remote-fs.target nss-lookup.target
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/httpd -k start -DFOREGROUND
+ExecStop=/usr/bin/httpd -k graceful-stop
+ExecReload=/usr/bin/httpd -k graceful
+PrivateTmp=true
+LimitNOFILE=infinity
+KillMode=mixed
+
+[Install]
+WantedBy=multi-user.target

Copied: apache/repos/testing-x86_64/nohttp2forprefork.patch (from rev 299699, apache/trunk/nohttp2forprefork.patch)
===================================================================
--- testing-x86_64/nohttp2forprefork.patch	                        (rev 0)
+++ testing-x86_64/nohttp2forprefork.patch	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,506 @@
+From ab03196a879f4064f618a9a45d63c67a67f4b901 Mon Sep 17 00:00:00 2001
+From: Jim Jagielski <jim at apache.org>
+Date: Tue, 4 Jul 2017 12:34:15 +0000
+Subject: [PATCH] Merge r1800689 from trunk:
+
+On the trunk:
+
+mod_http2: disable and give warning when mpm_prefork is encountered.
+     The server will continue to work, but HTTP/2 will no longer be negotiated.
+
+
+Submitted by: icing
+Reviewed by: icing, ylavic, jim
+
+
+git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1800774 13f79535-47bb-0310-9956-ffa450edef68
+---
+ modules/http2/h2_conn.c    |  21 +++++++-
+ modules/http2/h2_conn.h    |   3 +-
+ modules/http2/h2_mplx.c    |  37 +++++++-------
+ modules/http2/h2_mplx.h    |   2 +-
+ modules/http2/h2_session.c |   7 +--
+ modules/http2/h2_stream.c  |  14 +++++-
+ modules/http2/h2_switch.c  |   8 +++
+ modules/http2/h2_util.c    | 118 +++++++++++++++++++++------------------------
+ modules/http2/h2_workers.c |   7 +--
+ modules/http2/mod_http2.c  |  12 +++++
+ 12 files changed, 139 insertions(+), 99 deletions(-)
+
+diff --git a/modules/http2/h2_conn.c b/modules/http2/h2_conn.c
+index fcf6bad4d41..e2502c2f167 100644
+--- a/modules/http2/h2_conn.c
++++ b/modules/http2/h2_conn.c
+@@ -47,6 +47,7 @@ static struct h2_workers *workers;
+ static h2_mpm_type_t mpm_type = H2_MPM_UNKNOWN;
+ static module *mpm_module;
+ static int async_mpm;
++static int mpm_supported = 1;
+ static apr_socket_t *dummy_socket;
+ 
+ static void check_modules(int force) 
+@@ -76,11 +77,18 @@ static void check_modules(int force)
+             else if (!strcmp("prefork.c", m->name)) {
+                 mpm_type = H2_MPM_PREFORK;
+                 mpm_module = m;
++                /* While http2 can work really well on prefork, it collides
++                 * today's use case for prefork: runnning single-thread app engines
++                 * like php. If we restrict h2_workers to 1 per process, php will
++                 * work fine, but browser will be limited to 1 active request at a
++                 * time. */
++                mpm_supported = 0;
+                 break;
+             }
+             else if (!strcmp("simple_api.c", m->name)) {
+                 mpm_type = H2_MPM_SIMPLE;
+                 mpm_module = m;
++                mpm_supported = 0;
+                 break;
+             }
+             else if (!strcmp("mpm_winnt.c", m->name)) {
+@@ -107,7 +115,6 @@ apr_status_t h2_conn_child_init(apr_pool_t *pool, server_rec *s)
+     int idle_secs = 0;
+ 
+     check_modules(1);
+-    
+     ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads_per_child);
+     
+     status = ap_mpm_query(AP_MPMQ_IS_ASYNC, &async_mpm);
+@@ -157,6 +164,18 @@ h2_mpm_type_t h2_conn_mpm_type(void)
+     return mpm_type;
+ }
+ 
++const char *h2_conn_mpm_name(void)
++{
++    check_modules(0);
++    return mpm_module? mpm_module->name : "unknown";
++}
++
++int h2_mpm_supported(void)
++{
++    check_modules(0);
++    return mpm_supported;
++}
++
+ static module *h2_conn_mpm_module(void)
+ {
+     check_modules(0);
+diff --git a/modules/http2/h2_conn.h b/modules/http2/h2_conn.h
+index 79948644ae8..7111a6cd69c 100644
+--- a/modules/http2/h2_conn.h
++++ b/modules/http2/h2_conn.h
+@@ -64,7 +64,8 @@ typedef enum {
+ 
+ /* Returns the type of MPM module detected */
+ h2_mpm_type_t h2_conn_mpm_type(void);
+-
++const char *h2_conn_mpm_name(void);
++int h2_mpm_supported(void);
+ 
+ conn_rec *h2_slave_create(conn_rec *master, int slave_id, apr_pool_t *parent);
+ void h2_slave_destroy(conn_rec *slave);
+diff --git a/modules/http2/h2_mplx.c b/modules/http2/h2_mplx.c
+index b73bd0d5bfd..214d84ed1f9 100644
+--- a/modules/http2/h2_mplx.c
++++ b/modules/http2/h2_mplx.c
+@@ -481,9 +481,6 @@ void h2_mplx_release_and_join(h2_mplx *m, apr_thread_cond_t *wait)
+     
+     H2_MPLX_LEAVE(m);
+ 
+-    /* 5. unregister again, now that our workers are done */
+-    h2_workers_unregister(m->workers, m);
+-
+     ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,
+                   "h2_mplx(%ld): released", m->id);
+ }
+@@ -662,7 +659,7 @@ apr_status_t h2_mplx_reprioritize(h2_mplx *m, h2_stream_pri_cmp *cmp, void *ctx)
+ 
+ static void register_if_needed(h2_mplx *m) 
+ {
+-    if (!m->is_registered && !h2_iq_empty(m->q)) {
++    if (!m->aborted && !m->is_registered && !h2_iq_empty(m->q)) {
+         apr_status_t status = h2_workers_register(m->workers, m); 
+         if (status == APR_SUCCESS) {
+             m->is_registered = 1;
+@@ -755,25 +752,27 @@ static h2_task *next_stream_task(h2_mplx *m)
+     return NULL;
+ }
+ 
+-h2_task *h2_mplx_pop_task(h2_mplx *m, int *has_more)
++apr_status_t h2_mplx_pop_task(h2_mplx *m, h2_task **ptask)
+ {
+-    h2_task *task = NULL;
++    apr_status_t rv = APR_EOF;
+     
+-    H2_MPLX_ENTER_ALWAYS(m);
+-
+-    *has_more = 0;
+-    if (!m->aborted) {
+-        task = next_stream_task(m);
+-        if (task != NULL && !h2_iq_empty(m->q)) {
+-            *has_more = 1;
+-        }
+-        else {
+-            m->is_registered = 0; /* h2_workers will discard this mplx */
+-        }
++    *ptask = NULL;
++    if (APR_SUCCESS != (rv = apr_thread_mutex_lock(m->lock))) {
++        return rv;
++    }
++    
++    if (m->aborted) {
++        rv = APR_EOF;
++    }
++    else {
++        *ptask = next_stream_task(m);
++        rv = (*ptask != NULL && !h2_iq_empty(m->q))? APR_EAGAIN : APR_SUCCESS;
++    }
++    if (APR_EAGAIN != rv) {
++        m->is_registered = 0; /* h2_workers will discard this mplx */
+     }
+-
+     H2_MPLX_LEAVE(m);
+-    return task;
++    return rv;
+ }
+ 
+ static void task_done(h2_mplx *m, h2_task *task, h2_req_engine *ngn)
+diff --git a/modules/http2/h2_mplx.h b/modules/http2/h2_mplx.h
+index 61b1b99aba7..d56c65289c2 100644
+--- a/modules/http2/h2_mplx.h
++++ b/modules/http2/h2_mplx.h
+@@ -124,7 +124,7 @@ h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *master,
+  */ 
+ void h2_mplx_release_and_join(h2_mplx *m, struct apr_thread_cond_t *wait);
+ 
+-struct h2_task *h2_mplx_pop_task(h2_mplx *mplx, int *has_more);
++apr_status_t h2_mplx_pop_task(h2_mplx *m, struct h2_task **ptask);
+ 
+ void h2_mplx_task_done(h2_mplx *m, struct h2_task *task, struct h2_task **ptask);
+ 
+diff --git a/modules/http2/h2_session.c b/modules/http2/h2_session.c
+index bc24bb41cdb..da85d7053fd 100644
+--- a/modules/http2/h2_session.c
++++ b/modules/http2/h2_session.c
+@@ -326,6 +326,7 @@ static int on_frame_recv_cb(nghttp2_session *ng2s,
+ {
+     h2_session *session = (h2_session *)userp;
+     h2_stream *stream;
++    apr_status_t rv = APR_SUCCESS;
+     
+     if (APLOGcdebug(session->c)) {
+         char buffer[256];
+@@ -346,7 +347,7 @@ static int on_frame_recv_cb(nghttp2_session *ng2s,
+              * trailers */
+             stream = h2_session_stream_get(session, frame->hd.stream_id);
+             if (stream) {
+-                h2_stream_recv_frame(stream, NGHTTP2_HEADERS, frame->hd.flags);
++                rv = h2_stream_recv_frame(stream, NGHTTP2_HEADERS, frame->hd.flags);
+             }
+             break;
+         case NGHTTP2_DATA:
+@@ -356,7 +357,7 @@ static int on_frame_recv_cb(nghttp2_session *ng2s,
+                               H2_STRM_LOG(APLOGNO(02923), stream, 
+                               "DATA, len=%ld, flags=%d"), 
+                               (long)frame->hd.length, frame->hd.flags);
+-                h2_stream_recv_frame(stream, NGHTTP2_DATA, frame->hd.flags);
++                rv = h2_stream_recv_frame(stream, NGHTTP2_DATA, frame->hd.flags);
+             }
+             break;
+         case NGHTTP2_PRIORITY:
+@@ -411,7 +412,7 @@ static int on_frame_recv_cb(nghttp2_session *ng2s,
+             }
+             break;
+     }
+-    return 0;
++    return (APR_SUCCESS == rv)? 0 : NGHTTP2_ERR_PROTO;
+ }
+ 
+ static int h2_session_continue_data(h2_session *session) {
+diff --git a/modules/http2/h2_stream.c b/modules/http2/h2_stream.c
+index 4cd2132207e..925f3d6d81d 100644
+--- a/modules/http2/h2_stream.c
++++ b/modules/http2/h2_stream.c
+@@ -444,7 +444,13 @@ apr_status_t h2_stream_recv_frame(h2_stream *stream, int ftype, int flags)
+             else {
+                 /* request HEADER */
+                 ap_assert(stream->request == NULL);
+-                ap_assert(stream->rtmp != NULL);
++                if (stream->rtmp == NULL) {
++                    /* This can only happen, if the stream has received no header
++                     * name/value pairs at all. The lastest nghttp2 version have become
++                     * pretty good at detecting this early. In any case, we have
++                     * to abort the connection here, since this is clearly a protocol error */
++                    return APR_EINVAL;
++                }
+                 status = h2_request_end_headers(stream->rtmp, stream->pool, eos);
+                 if (status != APR_SUCCESS) {
+                     return status;
+@@ -739,9 +745,13 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
+         status = h2_request_add_header(stream->rtmp, stream->pool,
+                                        name, nlen, value, vlen);
+     }
+-    else  {
++    else if (H2_SS_OPEN == stream->state) {
+         status = add_trailer(stream, name, nlen, value, vlen);
+     }
++    else {
++        status = APR_EINVAL;
++    }
++    
+     if (status != APR_SUCCESS) {
+         ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c,
+                       H2_STRM_MSG(stream, "header %s not accepted"), name);
+diff --git a/modules/http2/h2_switch.c b/modules/http2/h2_switch.c
+index 8a8d56e59ef..5b1247ec700 100644
+--- a/modules/http2/h2_switch.c
++++ b/modules/http2/h2_switch.c
+@@ -55,6 +55,10 @@ static int h2_protocol_propose(conn_rec *c, request_rec *r,
+     const char **protos = is_tls? h2_tls_protos : h2_clear_protos;
+     
+     (void)s;
++    if (!h2_mpm_supported()) {
++        return DECLINED;
++    }
++    
+     if (strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))) {
+         /* We do not know how to switch from anything else but http/1.1.
+          */
+@@ -127,6 +131,10 @@ static int h2_protocol_switch(conn_rec *c, request_rec *r, server_rec *s,
+     const char **p = protos;
+     
+     (void)s;
++    if (!h2_mpm_supported()) {
++        return DECLINED;
++    }
++
+     while (*p) {
+         if (!strcmp(*p, protocol)) {
+             found = 1;
+diff --git a/modules/http2/h2_util.c b/modules/http2/h2_util.c
+index 01b506ac854..04a9311424e 100644
+--- a/modules/http2/h2_util.c
++++ b/modules/http2/h2_util.c
+@@ -695,16 +695,47 @@ int h2_fifo_count(h2_fifo *fifo)
+ 
+ static apr_status_t check_not_empty(h2_fifo *fifo, int block)
+ {
+-    if (fifo->count == 0) {
++    while (fifo->count == 0) {
+         if (!block) {
+             return APR_EAGAIN;
+         }
+-        while (fifo->count == 0) {
+-            if (fifo->aborted) {
+-                return APR_EOF;
++        if (fifo->aborted) {
++            return APR_EOF;
++        }
++        apr_thread_cond_wait(fifo->not_empty, fifo->lock);
++    }
++    return APR_SUCCESS;
++}
++
++static apr_status_t fifo_push_int(h2_fifo *fifo, void *elem, int block)
++{
++    if (fifo->aborted) {
++        return APR_EOF;
++    }
++
++    if (fifo->set && index_of(fifo, elem) >= 0) {
++        /* set mode, elem already member */
++        return APR_EEXIST;
++    }
++    else if (fifo->count == fifo->nelems) {
++        if (block) {
++            while (fifo->count == fifo->nelems) {
++                if (fifo->aborted) {
++                    return APR_EOF;
++                }
++                apr_thread_cond_wait(fifo->not_full, fifo->lock);
+             }
+-            apr_thread_cond_wait(fifo->not_empty, fifo->lock);
+         }
++        else {
++            return APR_EAGAIN;
++        }
++    }
++    
++    ap_assert(fifo->count < fifo->nelems);
++    fifo->elems[nth_index(fifo, fifo->count)] = elem;
++    ++fifo->count;
++    if (fifo->count == 1) {
++        apr_thread_cond_broadcast(fifo->not_empty);
+     }
+     return APR_SUCCESS;
+ }
+@@ -718,33 +749,7 @@ static apr_status_t fifo_push(h2_fifo *fifo, void *elem, int block)
+     }
+ 
+     if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
+-        if (fifo->set && index_of(fifo, elem) >= 0) {
+-            /* set mode, elem already member */
+-            apr_thread_mutex_unlock(fifo->lock);
+-            return APR_EEXIST;
+-        }
+-        else if (fifo->count == fifo->nelems) {
+-            if (block) {
+-                while (fifo->count == fifo->nelems) {
+-                    if (fifo->aborted) {
+-                        apr_thread_mutex_unlock(fifo->lock);
+-                        return APR_EOF;
+-                    }
+-                    apr_thread_cond_wait(fifo->not_full, fifo->lock);
+-                }
+-            }
+-            else {
+-                apr_thread_mutex_unlock(fifo->lock);
+-                return APR_EAGAIN;
+-            }
+-        }
+-        
+-        ap_assert(fifo->count < fifo->nelems);
+-        fifo->elems[nth_index(fifo, fifo->count)] = elem;
+-        ++fifo->count;
+-        if (fifo->count == 1) {
+-            apr_thread_cond_broadcast(fifo->not_empty);
+-        }
++        rv = fifo_push_int(fifo, elem, block);
+         apr_thread_mutex_unlock(fifo->lock);
+     }
+     return rv;
+@@ -760,12 +765,15 @@ apr_status_t h2_fifo_try_push(h2_fifo *fifo, void *elem)
+     return fifo_push(fifo, elem, 0);
+ }
+ 
+-static void *pull_head(h2_fifo *fifo)
++static apr_status_t pull_head(h2_fifo *fifo, void **pelem, int block)
+ {
+-    void *elem;
++    apr_status_t rv;
+     
+-    ap_assert(fifo->count > 0);
+-    elem = fifo->elems[fifo->head];
++    if ((rv = check_not_empty(fifo, block)) != APR_SUCCESS) {
++        *pelem = NULL;
++        return rv;
++    }
++    *pelem = fifo->elems[fifo->head];
+     --fifo->count;
+     if (fifo->count > 0) {
+         fifo->head = nth_index(fifo, 1);
+@@ -773,7 +781,7 @@ static void *pull_head(h2_fifo *fifo)
+             apr_thread_cond_broadcast(fifo->not_full);
+         }
+     }
+-    return elem;
++    return APR_SUCCESS;
+ }
+ 
+ static apr_status_t fifo_pull(h2_fifo *fifo, void **pelem, int block)
+@@ -785,15 +793,7 @@ static apr_status_t fifo_pull(h2_fifo *fifo, void **pelem, int block)
+     }
+     
+     if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
+-        if ((rv = check_not_empty(fifo, block)) != APR_SUCCESS) {
+-            apr_thread_mutex_unlock(fifo->lock);
+-            *pelem = NULL;
+-            return rv;
+-        }
+-
+-        ap_assert(fifo->count > 0);
+-        *pelem = pull_head(fifo);
+-
++        rv = pull_head(fifo, pelem, block);
+         apr_thread_mutex_unlock(fifo->lock);
+     }
+     return rv;
+@@ -818,25 +818,17 @@ static apr_status_t fifo_peek(h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx, int
+         return APR_EOF;
+     }
+     
+-    if ((rv = apr_thread_mutex_lock(fifo->lock)) == APR_SUCCESS) {
+-        if ((rv = check_not_empty(fifo, block)) != APR_SUCCESS) {
+-            apr_thread_mutex_unlock(fifo->lock);
+-            return rv;
++    if (APR_SUCCESS == (rv = apr_thread_mutex_lock(fifo->lock))) {
++        if (APR_SUCCESS == (rv = pull_head(fifo, &elem, block))) {
++            switch (fn(elem, ctx)) {
++                case H2_FIFO_OP_PULL:
++                    break;
++                case H2_FIFO_OP_REPUSH:
++                    rv = fifo_push_int(fifo, elem, block);
++                    break;
++            }
+         }
+-
+-        ap_assert(fifo->count > 0);
+-        elem = pull_head(fifo);
+-        
+         apr_thread_mutex_unlock(fifo->lock);
+-
+-        switch (fn(elem, ctx)) {
+-            case H2_FIFO_OP_PULL:
+-                break;
+-            case H2_FIFO_OP_REPUSH:
+-                return h2_fifo_push(fifo, elem);
+-                break;
+-        }
+-        
+     }
+     return rv;
+ }
+diff --git a/modules/http2/h2_workers.c b/modules/http2/h2_workers.c
+index 0bbb65223f7..5abddd4a1d5 100644
+--- a/modules/http2/h2_workers.c
++++ b/modules/http2/h2_workers.c
+@@ -150,15 +150,16 @@ static void cleanup_zombies(h2_workers *workers)
+ 
+ static apr_status_t slot_pull_task(h2_slot *slot, h2_mplx *m)
+ {
+-    int has_more;
+-    slot->task = h2_mplx_pop_task(m, &has_more);
++    apr_status_t rv;
++    
++    rv = h2_mplx_pop_task(m, &slot->task);
+     if (slot->task) {
+         /* Ok, we got something to give back to the worker for execution. 
+          * If we still have idle workers, we let the worker be sticky, 
+          * e.g. making it poll the task's h2_mplx instance for more work 
+          * before asking back here. */
+         slot->sticks = slot->workers->max_workers;
+-        return has_more? APR_EAGAIN : APR_SUCCESS;            
++        return rv;            
+     }
+     slot->sticks = 0;
+     return APR_EOF;
+diff --git a/modules/http2/mod_http2.c b/modules/http2/mod_http2.c
+index ea399c91a28..420e74c3363 100644
+--- a/modules/http2/mod_http2.c
++++ b/modules/http2/mod_http2.c
+@@ -65,6 +65,7 @@ typedef struct {
+ } features;
+ 
+ static features myfeats;
++static int mpm_warned;
+ 
+ /* The module initialization. Called once as apache hook, before any multi
+  * processing (threaded or not) happens. It is typically at least called twice, 
+@@ -141,6 +142,17 @@ static int h2_post_config(apr_pool_t *p, apr_pool_t *plog,
+             break;
+     }
+     
++    if (!h2_mpm_supported() && !mpm_warned) {
++        mpm_warned = 1;
++        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10034)
++                     "The mpm module (%s) is not supported by mod_http2. The mpm determines "
++                     "how things are processed in your server. HTTP/2 has more demands in "
++                     "this regard and the currently selected mpm will just not do. "
++                     "This is an advisory warning. Your server will continue to work, but "
++                     "the HTTP/2 protocol will be inactive.", 
++                     h2_conn_mpm_name());
++    }
++    
+     status = h2_h2_init(p, s);
+     if (status == APR_SUCCESS) {
+         status = h2_switch_init(p, s);

Copied: apache/repos/testing-x86_64/openssl-malloc-init.patch (from rev 299699, apache/trunk/openssl-malloc-init.patch)
===================================================================
--- testing-x86_64/openssl-malloc-init.patch	                        (rev 0)
+++ testing-x86_64/openssl-malloc-init.patch	2017-07-05 17:14:16 UTC (rev 299700)
@@ -0,0 +1,20 @@
+--- httpd-2.4.25/support/ab.c.orig	2017-05-21 21:59:17.131193359 +0000
++++ httpd-2.4.25/support/ab.c	2017-05-21 22:01:34.704322361 +0000
+@@ -2496,6 +2496,8 @@
+         heartbeatres = 0;
+ 
+ #ifdef USE_SSL
++    SSL_load_error_strings();
++    SSL_library_init();
+ #ifdef RSAREF
+     R_malloc_init();
+ #else
+@@ -2505,8 +2507,6 @@
+     OPENSSL_malloc_init();
+ #endif
+ #endif
+-    SSL_load_error_strings();
+-    SSL_library_init();
+     bio_out=BIO_new_fp(stdout,BIO_NOCLOSE);
+     bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+ 



More information about the arch-commits mailing list