summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-02-02 12:03:31 +0000
committerCoprDistGit <infra@openeuler.org>2024-02-02 12:03:31 +0000
commita12b5db2a95667c9a8affb404d5b5684cad488e4 (patch)
tree1114887c887a02562e246afc80785b03779f5ce3
parent234812b47987978dfc84e99bfdca4f5f4d6fbfa9 (diff)
automatic import of httpd
-rw-r--r--.gitignore1
-rw-r--r--00-base.conf69
-rw-r--r--00-dav.conf3
-rw-r--r--00-lua.conf1
-rw-r--r--00-mpm.conf23
-rw-r--r--00-optional.conf18
-rw-r--r--00-proxy.conf18
-rw-r--r--00-proxyhtml.conf3
-rw-r--r--00-ssl.conf1
-rw-r--r--00-systemd.conf2
-rw-r--r--01-cgi.conf14
-rw-r--r--01-ldap.conf3
-rw-r--r--01-md.conf1
-rw-r--r--01-session.conf6
-rw-r--r--10-listen443.conf5
-rw-r--r--README.confd9
-rw-r--r--README.confmod9
-rw-r--r--action-configtest.sh2
-rw-r--r--action-graceful.sh2
-rw-r--r--backport-httpd-2.4.1-apctl.patch94
-rw-r--r--backport-httpd-2.4.1-deplibs.patch19
-rw-r--r--backport-httpd-2.4.25-selinux.patch63
-rw-r--r--backport-httpd-2.4.3-apctl-systemd.patch51
-rw-r--r--backport-httpd-2.4.43-cachehardmax.patch82
-rw-r--r--backport-httpd-2.4.43-corelimit.patch29
-rw-r--r--backport-httpd-2.4.43-enable-sslv3.patch62
-rw-r--r--backport-httpd-2.4.43-gettid.patch93
-rw-r--r--backport-httpd-2.4.43-r1861793+.patch271
-rw-r--r--backport-httpd-2.4.43-socket-activation.patch299
-rw-r--r--backport-httpd-2.4.43-sslciphdefault.patch31
-rw-r--r--backport-httpd-2.4.43-sslprotdefault.patch99
-rw-r--r--backport-httpd-2.4.46-htcacheclean-dont-break.patch13
-rw-r--r--backport-httpd-2.4.48-r1828172+.patch2371
-rw-r--r--backport-httpd-2.4.53-detect-systemd.patch45
-rw-r--r--backport-httpd-2.4.53-export.patch56
-rw-r--r--backport-httpd-2.4.54-icons.patch49
-rw-r--r--backport-httpd-2.4.9-apxs.patch58
-rw-r--r--backport-layout_add_openEuler.patch34
-rw-r--r--htcacheclean.service10
-rw-r--r--htcacheclean.sysconf16
-rw-r--r--httpd-init.service12
-rw-r--r--httpd-ssl-gencerts39
-rw-r--r--httpd-ssl-pass-dialog3
-rw-r--r--httpd.conf355
-rw-r--r--httpd.logrotate9
-rw-r--r--httpd.service32
-rw-r--r--httpd.service.xml338
-rw-r--r--httpd.socket13
-rw-r--r--httpd.spec733
-rw-r--r--httpd.tmpfiles2
-rw-r--r--httpd@.service23
-rw-r--r--index.html123
-rw-r--r--instance.conf23
-rw-r--r--manual.conf13
-rw-r--r--server-status.conf10
-rw-r--r--sources1
-rw-r--r--ssl.conf219
-rw-r--r--userdir.conf36
-rw-r--r--welcome.conf18
59 files changed, 6037 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..f6c4266 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/httpd-2.4.58.tar.bz2
diff --git a/00-base.conf b/00-base.conf
new file mode 100644
index 0000000..7cabce0
--- /dev/null
+++ b/00-base.conf
@@ -0,0 +1,69 @@
+#
+# This file loads most of the modules included with the Apache HTTP
+# Server itself.
+#
+
+LoadModule access_compat_module modules/mod_access_compat.so
+LoadModule actions_module modules/mod_actions.so
+LoadModule alias_module modules/mod_alias.so
+LoadModule allowmethods_module modules/mod_allowmethods.so
+LoadModule auth_basic_module modules/mod_auth_basic.so
+LoadModule auth_digest_module modules/mod_auth_digest.so
+LoadModule authn_anon_module modules/mod_authn_anon.so
+LoadModule authn_core_module modules/mod_authn_core.so
+LoadModule authn_dbd_module modules/mod_authn_dbd.so
+LoadModule authn_dbm_module modules/mod_authn_dbm.so
+LoadModule authn_file_module modules/mod_authn_file.so
+LoadModule authn_socache_module modules/mod_authn_socache.so
+LoadModule authz_core_module modules/mod_authz_core.so
+LoadModule authz_dbd_module modules/mod_authz_dbd.so
+LoadModule authz_dbm_module modules/mod_authz_dbm.so
+LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
+LoadModule authz_host_module modules/mod_authz_host.so
+LoadModule authz_owner_module modules/mod_authz_owner.so
+LoadModule authz_user_module modules/mod_authz_user.so
+LoadModule autoindex_module modules/mod_autoindex.so
+LoadModule brotli_module modules/mod_brotli.so
+LoadModule cache_module modules/mod_cache.so
+LoadModule cache_disk_module modules/mod_cache_disk.so
+LoadModule cache_socache_module modules/mod_cache_socache.so
+LoadModule data_module modules/mod_data.so
+LoadModule dbd_module modules/mod_dbd.so
+LoadModule deflate_module modules/mod_deflate.so
+LoadModule dir_module modules/mod_dir.so
+LoadModule dumpio_module modules/mod_dumpio.so
+LoadModule echo_module modules/mod_echo.so
+LoadModule env_module modules/mod_env.so
+LoadModule expires_module modules/mod_expires.so
+LoadModule ext_filter_module modules/mod_ext_filter.so
+LoadModule filter_module modules/mod_filter.so
+LoadModule headers_module modules/mod_headers.so
+LoadModule include_module modules/mod_include.so
+LoadModule info_module modules/mod_info.so
+LoadModule log_config_module modules/mod_log_config.so
+LoadModule logio_module modules/mod_logio.so
+LoadModule macro_module modules/mod_macro.so
+LoadModule mime_magic_module modules/mod_mime_magic.so
+LoadModule mime_module modules/mod_mime.so
+LoadModule negotiation_module modules/mod_negotiation.so
+LoadModule remoteip_module modules/mod_remoteip.so
+LoadModule reqtimeout_module modules/mod_reqtimeout.so
+LoadModule request_module modules/mod_request.so
+LoadModule rewrite_module modules/mod_rewrite.so
+LoadModule setenvif_module modules/mod_setenvif.so
+LoadModule slotmem_plain_module modules/mod_slotmem_plain.so
+LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
+LoadModule socache_dbm_module modules/mod_socache_dbm.so
+LoadModule socache_memcache_module modules/mod_socache_memcache.so
+LoadModule socache_redis_module modules/mod_socache_redis.so
+LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
+LoadModule status_module modules/mod_status.so
+LoadModule substitute_module modules/mod_substitute.so
+LoadModule suexec_module modules/mod_suexec.so
+LoadModule unique_id_module modules/mod_unique_id.so
+LoadModule unixd_module modules/mod_unixd.so
+LoadModule userdir_module modules/mod_userdir.so
+LoadModule version_module modules/mod_version.so
+LoadModule vhost_alias_module modules/mod_vhost_alias.so
+LoadModule watchdog_module modules/mod_watchdog.so
+
diff --git a/00-dav.conf b/00-dav.conf
new file mode 100644
index 0000000..e6af8de
--- /dev/null
+++ b/00-dav.conf
@@ -0,0 +1,3 @@
+LoadModule dav_module modules/mod_dav.so
+LoadModule dav_fs_module modules/mod_dav_fs.so
+LoadModule dav_lock_module modules/mod_dav_lock.so
diff --git a/00-lua.conf b/00-lua.conf
new file mode 100644
index 0000000..9e0d0db
--- /dev/null
+++ b/00-lua.conf
@@ -0,0 +1 @@
+LoadModule lua_module modules/mod_lua.so
diff --git a/00-mpm.conf b/00-mpm.conf
new file mode 100644
index 0000000..b15f913
--- /dev/null
+++ b/00-mpm.conf
@@ -0,0 +1,23 @@
+# Select the MPM module which should be used by uncommenting exactly
+# one of the following LoadModule lines. See the httpd.service(8) man
+# page for more information on changing the MPM.
+
+# prefork MPM: Implements a non-threaded, pre-forking web server
+# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
+#
+# NOTE: If enabling prefork, the httpd_graceful_shutdown SELinux
+# boolean should be enabled, to allow graceful stop/shutdown.
+#
+#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
+
+# worker MPM: Multi-Processing Module implementing a hybrid
+# multi-threaded multi-process web server
+# See: http://httpd.apache.org/docs/2.4/mod/worker.html
+#
+#LoadModule mpm_worker_module modules/mod_mpm_worker.so
+
+# event MPM: A variant of the worker MPM with the goal of consuming
+# threads only for connections with active processing
+# See: http://httpd.apache.org/docs/2.4/mod/event.html
+#
+#LoadModule mpm_event_module modules/mod_mpm_event.so
diff --git a/00-optional.conf b/00-optional.conf
new file mode 100644
index 0000000..ef584ec
--- /dev/null
+++ b/00-optional.conf
@@ -0,0 +1,18 @@
+#
+# This file lists modules included with the Apache HTTP Server
+# which are not enabled by default.
+#
+
+#LoadModule asis_module modules/mod_asis.so
+#LoadModule buffer_module modules/mod_buffer.so
+#LoadModule heartbeat_module modules/mod_heartbeat.so
+#LoadModule heartmonitor_module modules/mod_heartmonitor.so
+#LoadModule usertrack_module modules/mod_usertrack.so
+#LoadModule dialup_module modules/mod_dialup.so
+#LoadModule charset_lite_module modules/mod_charset_lite.so
+#LoadModule log_debug_module modules/mod_log_debug.so
+#LoadModule log_forensic_module modules/mod_log_forensic.so
+#LoadModule ratelimit_module modules/mod_ratelimit.so
+#LoadModule reflector_module modules/mod_reflector.so
+#LoadModule sed_module modules/mod_sed.so
+#LoadModule speling_module modules/mod_speling.so
diff --git a/00-proxy.conf b/00-proxy.conf
new file mode 100644
index 0000000..f0f84c2
--- /dev/null
+++ b/00-proxy.conf
@@ -0,0 +1,18 @@
+# This file configures all the proxy modules:
+LoadModule proxy_module modules/mod_proxy.so
+LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
+LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
+LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
+LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
+LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
+LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
+LoadModule proxy_connect_module modules/mod_proxy_connect.so
+LoadModule proxy_express_module modules/mod_proxy_express.so
+LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
+LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so
+LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
+LoadModule proxy_http_module modules/mod_proxy_http.so
+LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so
+LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
+LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so
+LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
diff --git a/00-proxyhtml.conf b/00-proxyhtml.conf
new file mode 100644
index 0000000..9a9b107
--- /dev/null
+++ b/00-proxyhtml.conf
@@ -0,0 +1,3 @@
+# This file configures mod_proxy_html and mod_xml2enc:
+LoadModule xml2enc_module modules/mod_xml2enc.so
+LoadModule proxy_html_module modules/mod_proxy_html.so
diff --git a/00-ssl.conf b/00-ssl.conf
new file mode 100644
index 0000000..53235cd
--- /dev/null
+++ b/00-ssl.conf
@@ -0,0 +1 @@
+LoadModule ssl_module modules/mod_ssl.so
diff --git a/00-systemd.conf b/00-systemd.conf
new file mode 100644
index 0000000..b208c97
--- /dev/null
+++ b/00-systemd.conf
@@ -0,0 +1,2 @@
+# This file configures systemd module:
+LoadModule systemd_module modules/mod_systemd.so
diff --git a/01-cgi.conf b/01-cgi.conf
new file mode 100644
index 0000000..5b8b936
--- /dev/null
+++ b/01-cgi.conf
@@ -0,0 +1,14 @@
+# This configuration file loads a CGI module appropriate to the MPM
+# which has been configured in 00-mpm.conf. mod_cgid should be used
+# with a threaded MPM; mod_cgi with the prefork MPM.
+
+<IfModule mpm_worker_module>
+ LoadModule cgid_module modules/mod_cgid.so
+</IfModule>
+<IfModule mpm_event_module>
+ LoadModule cgid_module modules/mod_cgid.so
+</IfModule>
+<IfModule mpm_prefork_module>
+ LoadModule cgi_module modules/mod_cgi.so
+</IfModule>
+
diff --git a/01-ldap.conf b/01-ldap.conf
new file mode 100644
index 0000000..f2ac2a2
--- /dev/null
+++ b/01-ldap.conf
@@ -0,0 +1,3 @@
+# This file configures the LDAP modules:
+LoadModule ldap_module modules/mod_ldap.so
+LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
diff --git a/01-md.conf b/01-md.conf
new file mode 100644
index 0000000..2739202
--- /dev/null
+++ b/01-md.conf
@@ -0,0 +1 @@
+LoadModule md_module modules/mod_md.so
diff --git a/01-session.conf b/01-session.conf
new file mode 100644
index 0000000..f8d4d92
--- /dev/null
+++ b/01-session.conf
@@ -0,0 +1,6 @@
+LoadModule session_module modules/mod_session.so
+LoadModule session_cookie_module modules/mod_session_cookie.so
+LoadModule session_dbd_module modules/mod_session_dbd.so
+LoadModule auth_form_module modules/mod_auth_form.so
+
+#LoadModule session_crypto_module modules/mod_session_crypto.so
diff --git a/10-listen443.conf b/10-listen443.conf
new file mode 100644
index 0000000..7e2df97
--- /dev/null
+++ b/10-listen443.conf
@@ -0,0 +1,5 @@
+# This file is part of mod_ssl. It enables listening on port 443 when
+# socket activation is used.
+
+[Socket]
+ListenStream=443
diff --git a/README.confd b/README.confd
new file mode 100644
index 0000000..f5e9661
--- /dev/null
+++ b/README.confd
@@ -0,0 +1,9 @@
+
+This directory holds configuration files for the Apache HTTP Server;
+any files in this directory which have the ".conf" extension will be
+processed as httpd configuration files. The directory is used in
+addition to the directory /etc/httpd/conf.modules.d/, which contains
+configuration files necessary to load modules.
+
+Files are processed in alphabetical order.
+
diff --git a/README.confmod b/README.confmod
new file mode 100644
index 0000000..d33d1d4
--- /dev/null
+++ b/README.confmod
@@ -0,0 +1,9 @@
+
+This directory holds configuration files for the Apache HTTP Server;
+any files in this directory which have the ".conf" extension will be
+processed as httpd configuration files. This directory contains
+configuration fragments necessary only to load modules.
+Administrators should use the directory "/etc/httpd/conf.d" to modify
+the configuration of httpd, or any modules.
+
+Files are processed in alphanumeric order.
diff --git a/action-configtest.sh b/action-configtest.sh
new file mode 100644
index 0000000..6685b0a
--- /dev/null
+++ b/action-configtest.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /sbin/apachectl configtest "$@"
diff --git a/action-graceful.sh b/action-graceful.sh
new file mode 100644
index 0000000..dc68b2e
--- /dev/null
+++ b/action-graceful.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /sbin/apachectl graceful "$@"
diff --git a/backport-httpd-2.4.1-apctl.patch b/backport-httpd-2.4.1-apctl.patch
new file mode 100644
index 0000000..b31c3c5
--- /dev/null
+++ b/backport-httpd-2.4.1-apctl.patch
@@ -0,0 +1,94 @@
+
+- fail gracefully if links is not installed on target system
+- source sysconfig/httpd for custom env. vars etc.
+- make httpd -t work even in SELinux
+- pass $OPTIONS to all $HTTPD invocation
+
+Upstream-HEAD: vendor
+Upstream-2.0: vendor
+Upstream-Status: Vendor-specific changes for better initscript integration
+
+--- httpd-2.4.1/support/apachectl.in.apctl
++++ httpd-2.4.1/support/apachectl.in
+@@ -44,19 +44,25 @@ ARGV="$@"
+ # the path to your httpd binary, including options if necessary
+ HTTPD='@exp_sbindir@/@progname@'
+ #
+-# pick up any necessary environment variables
+-if test -f @exp_sbindir@/envvars; then
+- . @exp_sbindir@/envvars
+-fi
+ #
+ # a command that outputs a formatted text version of the HTML at the
+ # url given on the command line. Designed for lynx, however other
+ # programs may work.
+-LYNX="@LYNX_PATH@ -dump"
++if [ -x "@LYNX_PATH@" ]; then
++ LYNX="@LYNX_PATH@ -dump"
++else
++ LYNX=none
++fi
+ #
+ # the URL to your server's mod_status status page. If you do not
+ # have one, then status and fullstatus will not work.
+ STATUSURL="http://localhost:@PORT@/server-status"
++
++# Source /etc/sysconfig/httpd for $HTTPD setting, etc.
++if [ -r /etc/sysconfig/httpd ]; then
++ . /etc/sysconfig/httpd
++fi
++
+ #
+ # Set this variable to a command that increases the maximum
+ # number of file descriptors allowed per child process. This is
+@@ -76,9 +82,27 @@ if [ "x$ARGV" = "x" ] ; then
+ ARGV="-h"
+ fi
+
++function checklynx() {
++if [ "$LYNX" = "none" ]; then
++ echo "The 'links' package is required for this functionality."
++ exit 8
++fi
++}
++
++function testconfig() {
++# httpd is denied terminal access in SELinux, so run in the
++# current context to get stdout from $HTTPD -t.
++if test -x /usr/sbin/selinuxenabled && /usr/sbin/selinuxenabled; then
++ runcon -- `id -Z` $HTTPD $OPTIONS -t
++else
++ $HTTPD $OPTIONS -t
++fi
++ERROR=$?
++}
++
+ case $ACMD in
+ start|stop|restart|graceful|graceful-stop)
+- $HTTPD -k $ARGV
++ $HTTPD $OPTIONS -k $ARGV
+ ERROR=$?
+ ;;
+ startssl|sslstart|start-SSL)
+@@ -88,17 +112,18 @@ startssl|sslstart|start-SSL)
+ ERROR=2
+ ;;
+ configtest)
+- $HTTPD -t
+- ERROR=$?
++ testconfig
+ ;;
+ status)
++ checklynx
+ $LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } '
+ ;;
+ fullstatus)
++ checklynx
+ $LYNX $STATUSURL
+ ;;
+ *)
+- $HTTPD "$@"
++ $HTTPD $OPTIONS "$@"
+ ERROR=$?
+ esac
+
diff --git a/backport-httpd-2.4.1-deplibs.patch b/backport-httpd-2.4.1-deplibs.patch
new file mode 100644
index 0000000..b73c21d
--- /dev/null
+++ b/backport-httpd-2.4.1-deplibs.patch
@@ -0,0 +1,19 @@
+
+Link straight against .la files.
+
+Upstream-Status: vendor specific
+
+--- httpd-2.4.1/configure.in.deplibs
++++ httpd-2.4.1/configure.in
+@@ -707,9 +707,9 @@ APACHE_HELP_STRING(--with-suexec-umask,u
+
+ dnl APR should go after the other libs, so the right symbols can be picked up
+ if test x${apu_found} != xobsolete; then
+- AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool --libs`"
++ AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool`"
+ fi
+-AP_LIBS="$AP_LIBS `$apr_config --link-libtool --libs`"
++AP_LIBS="$AP_LIBS `$apr_config --link-libtool`"
+ APACHE_SUBST(AP_LIBS)
+ APACHE_SUBST(AP_BUILD_SRCLIB_DIRS)
+ APACHE_SUBST(AP_CLEAN_SRCLIB_DIRS)
diff --git a/backport-httpd-2.4.25-selinux.patch b/backport-httpd-2.4.25-selinux.patch
new file mode 100644
index 0000000..0db1e45
--- /dev/null
+++ b/backport-httpd-2.4.25-selinux.patch
@@ -0,0 +1,63 @@
+diff --git a/configure.in b/configure.in
+index c5896c1..96cd4a6 100644
+--- a/configure.in
++++ b/configure.in
+@@ -508,6 +508,11 @@ getloadavg
+ dnl confirm that a void pointer is large enough to store a long integer
+ APACHE_CHECK_VOID_PTR_LEN
+
++AC_CHECK_LIB(selinux, is_selinux_enabled, [
++ AC_DEFINE(HAVE_SELINUX, 1, [Defined if SELinux is supported])
++ APR_ADDTO(HTTPD_LIBS, [-lselinux])
++])
++
+ AC_CACHE_CHECK([for gettid()], ac_cv_gettid,
+ [AC_TRY_RUN(#define _GNU_SOURCE
+ #include <unistd.h>
+diff --git a/server/core.c b/server/core.c
+index 4da7209..515047b 100644
+--- a/server/core.c
++++ b/server/core.c
+@@ -65,6 +65,10 @@
+ #include <unistd.h>
+ #endif
+
++#ifdef HAVE_SELINUX
++#include <selinux/selinux.h>
++#endif
++
+ /* LimitRequestBody handling */
+ #define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1)
+ #define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 1<<30) /* 1GB */
+@@ -5126,6 +5130,28 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
+ }
+ #endif
+
++#ifdef HAVE_SELINUX
++ {
++ static int already_warned = 0;
++ int is_enabled = is_selinux_enabled() > 0;
++
++ if (is_enabled && !already_warned) {
++ security_context_t con;
++
++ if (getcon(&con) == 0) {
++
++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
++ "SELinux policy enabled; "
++ "httpd running as context %s", con);
++
++ already_warned = 1;
++
++ freecon(con);
++ }
++ }
++ }
++#endif
++
+ return OK;
+ }
+
+--
+2.27.0
+
diff --git a/backport-httpd-2.4.3-apctl-systemd.patch b/backport-httpd-2.4.3-apctl-systemd.patch
new file mode 100644
index 0000000..c6bf5da
--- /dev/null
+++ b/backport-httpd-2.4.3-apctl-systemd.patch
@@ -0,0 +1,51 @@
+
+Make apachectl run via systemctl.
+
+Note: "apachectl graceful" is documented to start httpd if not running.
+
+Upstream-Status: vendor specific patch
+
+--- httpd-2.4.18/support/apachectl.in.apctlsystemd
++++ httpd-2.4.18/support/apachectl.in
+@@ -100,9 +100,28 @@ fi
+ ERROR=$?
+ }
+
++if [ "x$2" != "x" ] ; then
++ echo Passing arguments to httpd using apachectl is no longer supported.
++ echo You can only start/stop/restart httpd using this script.
++ echo If you want to pass extra arguments to httpd, edit the
++ echo /etc/sysconfig/httpd config file.
++fi
++
+ case $ACMD in
+-start|stop|restart|graceful|graceful-stop)
+- $HTTPD $OPTIONS -k $ARGV
++start|stop|restart|status)
++ /usr/bin/systemctl $ACMD httpd.service
++ ERROR=$?
++ ;;
++graceful)
++ if /usr/bin/systemctl -q is-active httpd.service; then
++ /usr/bin/systemctl reload httpd.service
++ else
++ /usr/bin/systemctl start httpd.service
++ fi
++ ERROR=$?
++ ;;
++graceful-stop)
++ /usr/bin/systemctl stop httpd.service
+ ERROR=$?
+ ;;
+ startssl|sslstart|start-SSL)
+@@ -114,10 +133,6 @@ startssl|sslstart|start-SSL)
+ configtest)
+ testconfig
+ ;;
+-status)
+- checklynx
+- $LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } '
+- ;;
+ fullstatus)
+ checklynx
+ $LYNX $STATUSURL
diff --git a/backport-httpd-2.4.43-cachehardmax.patch b/backport-httpd-2.4.43-cachehardmax.patch
new file mode 100644
index 0000000..755f822
--- /dev/null
+++ b/backport-httpd-2.4.43-cachehardmax.patch
@@ -0,0 +1,82 @@
+diff --git a/modules/cache/cache_util.h b/modules/cache/cache_util.h
+index 6b92151..4c42a8e 100644
+--- a/modules/cache/cache_util.h
++++ b/modules/cache/cache_util.h
+@@ -195,6 +195,9 @@ typedef struct {
+ unsigned int store_nostore_set:1;
+ unsigned int enable_set:1;
+ unsigned int disable_set:1;
++ /* treat maxex as hard limit */
++ unsigned int hardmaxex:1;
++ unsigned int hardmaxex_set:1;
+ } cache_dir_conf;
+
+ /* A linked-list of authn providers. */
+diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c
+index 3b9aa4f..8268503 100644
+--- a/modules/cache/mod_cache.c
++++ b/modules/cache/mod_cache.c
+@@ -1455,6 +1455,11 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
+ exp = date + dconf->defex;
+ }
+ }
++ /* else, forcibly cap the expiry date if required */
++ else if (dconf->hardmaxex && (date + dconf->maxex) < exp) {
++ exp = date + dconf->maxex;
++ }
++
+ info->expire = exp;
+
+ /* We found a stale entry which wasn't really stale. */
+@@ -1954,7 +1959,9 @@ static void *create_dir_config(apr_pool_t *p, char *dummy)
+
+ /* array of providers for this URL space */
+ dconf->cacheenable = apr_array_make(p, 10, sizeof(struct cache_enable));
+-
++ /* flag; treat maxex as hard limit */
++ dconf->hardmaxex = 0;
++ dconf->hardmaxex_set = 0;
+ return dconf;
+ }
+
+@@ -2004,7 +2011,10 @@ static void *merge_dir_config(apr_pool_t *p, void *basev, void *addv) {
+ new->enable_set = add->enable_set || base->enable_set;
+ new->disable = (add->disable_set == 0) ? base->disable : add->disable;
+ new->disable_set = add->disable_set || base->disable_set;
+-
++ new->hardmaxex =
++ (add->hardmaxex_set == 0)
++ ? base->hardmaxex
++ : add->hardmaxex;
+ return new;
+ }
+
+@@ -2332,12 +2342,18 @@ static const char *add_cache_disable(cmd_parms *parms, void *dummy,
+ }
+
+ static const char *set_cache_maxex(cmd_parms *parms, void *dummy,
+- const char *arg)
++ const char *arg, const char *hard)
+ {
+ cache_dir_conf *dconf = (cache_dir_conf *)dummy;
+
+ dconf->maxex = (apr_time_t) (atol(arg) * MSEC_ONE_SEC);
+ dconf->maxex_set = 1;
++
++ if (hard && strcasecmp(hard, "hard") == 0) {
++ dconf->hardmaxex = 1;
++ dconf->hardmaxex_set = 1;
++ }
++
+ return NULL;
+ }
+
+@@ -2545,7 +2561,7 @@ static const command_rec cache_cmds[] =
+ "caching is enabled"),
+ AP_INIT_TAKE1("CacheDisable", add_cache_disable, NULL, RSRC_CONF|ACCESS_CONF,
+ "A partial URL prefix below which caching is disabled"),
+- AP_INIT_TAKE1("CacheMaxExpire", set_cache_maxex, NULL, RSRC_CONF|ACCESS_CONF,
++ AP_INIT_TAKE12("CacheMaxExpire", set_cache_maxex, NULL, RSRC_CONF|ACCESS_CONF,
+ "The maximum time in seconds to cache a document"),
+ AP_INIT_TAKE1("CacheMinExpire", set_cache_minex, NULL, RSRC_CONF|ACCESS_CONF,
+ "The minimum time in seconds to cache a document"),
diff --git a/backport-httpd-2.4.43-corelimit.patch b/backport-httpd-2.4.43-corelimit.patch
new file mode 100644
index 0000000..48267a9
--- /dev/null
+++ b/backport-httpd-2.4.43-corelimit.patch
@@ -0,0 +1,29 @@
+diff --git a/server/core.c b/server/core.c
+index 79b2a82..dc0f17a 100644
+--- a/server/core.c
++++ b/server/core.c
+@@ -4996,6 +4996,25 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
+ }
+ apr_pool_cleanup_register(pconf, NULL, ap_mpm_end_gen_helper,
+ apr_pool_cleanup_null);
++
++#ifdef RLIMIT_CORE
++ if (ap_coredumpdir_configured) {
++ struct rlimit lim;
++
++ if (getrlimit(RLIMIT_CORE, &lim) == 0 && lim.rlim_cur == 0) {
++ lim.rlim_cur = lim.rlim_max;
++ if (setrlimit(RLIMIT_CORE, &lim) == 0) {
++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
++ "core dump file size limit raised to %lu bytes",
++ lim.rlim_cur);
++ } else {
++ ap_log_error(APLOG_MARK, APLOG_NOTICE, errno, NULL,
++ "core dump file size is zero, setrlimit failed");
++ }
++ }
++ }
++#endif
++
+ return OK;
+ }
diff --git a/backport-httpd-2.4.43-enable-sslv3.patch b/backport-httpd-2.4.43-enable-sslv3.patch
new file mode 100644
index 0000000..2861605
--- /dev/null
+++ b/backport-httpd-2.4.43-enable-sslv3.patch
@@ -0,0 +1,62 @@
+diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
+index 979489c..3d6443b 100644
+--- a/modules/ssl/ssl_engine_config.c
++++ b/modules/ssl/ssl_engine_config.c
+@@ -1485,6 +1485,10 @@ static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
+ #endif
+ else if (strcEQ(w, "all")) {
+ thisopt = SSL_PROTOCOL_ALL;
++#ifndef OPENSSL_NO_SSL3
++ /* by default, ALL kw doesn't turn on SSLv3 */
++ thisopt &= ~SSL_PROTOCOL_SSLV3;
++#endif
+ }
+ else {
+ return apr_pstrcat(parms->temp_pool,
+diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
+index b0fcf81..ab6f263 100644
+--- a/modules/ssl/ssl_engine_init.c
++++ b/modules/ssl/ssl_engine_init.c
+@@ -568,6 +568,28 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
+ }
+ #endif
+
++/*
++ * Enable/disable SSLProtocol. If the mod_ssl enables protocol
++ * which is disabled by default by OpenSSL, show a warning.
++ * "option" is for example SSL_OP_NO_SSLv3.
++ */
++static void ssl_set_ctx_protocol_option(server_rec *s,
++ SSL_CTX *ctx,
++ long option,
++ int enabled,
++ const char *name)
++{
++ if (!enabled) {
++ SSL_CTX_set_options(ctx, option);
++ }
++ else if (SSL_CTX_get_options(ctx) & option) {
++ SSL_CTX_clear_options(ctx, option);
++ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02904)
++ "Allowing SSLProtocol %s even though it is disabled "
++ "by OpenSSL by default on this system", name);
++ }
++}
++
+ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
+ apr_pool_t *p,
+ apr_pool_t *ptemp,
+@@ -735,9 +757,13 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
+ }
+ if (prot == TLS1_1_VERSION && protocol & SSL_PROTOCOL_TLSV1) {
+ prot = TLS1_VERSION;
++ ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_TLSv1,
++ protocol & SSL_PROTOCOL_TLSV1, "TLSv1");
+ }
+ #ifndef OPENSSL_NO_SSL3
+ if (prot == TLS1_VERSION && protocol & SSL_PROTOCOL_SSLV3) {
++ ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_SSLv3,
++ protocol & SSL_PROTOCOL_SSLV3, "SSLv3");
+ prot = SSL3_VERSION;
+ }
+ #endif
diff --git a/backport-httpd-2.4.43-gettid.patch b/backport-httpd-2.4.43-gettid.patch
new file mode 100644
index 0000000..f80b3a7
--- /dev/null
+++ b/backport-httpd-2.4.43-gettid.patch
@@ -0,0 +1,93 @@
+From d4e5b6e1e5585d341d1e51f1ddc637c099111076 Mon Sep 17 00:00:00 2001
+From: Joe Orton <jorton@redhat.com>
+Date: Tue, 7 Jul 2020 09:48:01 +0100
+Subject: [PATCH] Check and use gettid() directly with glibc 2.30+.
+
+* configure.in: Check for gettid() and define HAVE_SYS_GETTID if
+ gettid() is only usable via syscall().
+
+* server/log.c (log_tid): Use gettid() directly if available.
+---
+ configure.in | 14 +++++++++-----
+ server/log.c | 8 ++++++--
+ 2 files changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/configure.in b/configure.in
+index 423d58d4b9a..60cbf7b7f81 100644
+--- httpd-2.4.43/configure.in.gettid
++++ httpd-2.4.43/configure.in
+@@ -478,7 +500,8 @@
+ timegm \
+ getpgid \
+ fopen64 \
+-getloadavg
++getloadavg \
++gettid
+ )
+
+ dnl confirm that a void pointer is large enough to store a long integer
+@@ -489,16 +512,19 @@
+ APR_ADDTO(HTTPD_LIBS, [-lselinux])
+ ])
+
+-AC_CACHE_CHECK([for gettid()], ac_cv_gettid,
++if test $ac_cv_func_gettid = no; then
++ # On Linux before glibc 2.30, gettid() is only usable via syscall()
++ AC_CACHE_CHECK([for gettid() via syscall], ap_cv_gettid,
+ [AC_TRY_RUN(#define _GNU_SOURCE
+ #include <unistd.h>
+ #include <sys/syscall.h>
+ #include <sys/types.h>
+ int main(int argc, char **argv) {
+ pid_t t = syscall(SYS_gettid); return t == -1 ? 1 : 0; },
+-[ac_cv_gettid=yes], [ac_cv_gettid=no], [ac_cv_gettid=no])])
+-if test "$ac_cv_gettid" = "yes"; then
+- AC_DEFINE(HAVE_GETTID, 1, [Define if you have gettid()])
++ [ap_cv_gettid=yes], [ap_cv_gettid=no], [ap_cv_gettid=no])])
++ if test "$ap_cv_gettid" = "yes"; then
++ AC_DEFINE(HAVE_SYS_GETTID, 1, [Define if you have gettid() via syscall()])
++ fi
+ fi
+
+ dnl ## Check for the tm_gmtoff field in struct tm to get the timezone diffs
+--- httpd-2.4.43/server/log.c.gettid
++++ httpd-2.4.43/server/log.c
+@@ -55,7 +55,7 @@
+ #include "ap_mpm.h"
+ #include "ap_listen.h"
+
+-#if HAVE_GETTID
++#if HAVE_SYS_GETTID
+ #include <sys/syscall.h>
+ #include <sys/types.h>
+ #endif
+@@ -625,14 +625,18 @@
+ #if APR_HAS_THREADS
+ int result;
+ #endif
+-#if HAVE_GETTID
++#if defined(HAVE_GETTID) || defined(HAVE_SYS_GETTID)
+ if (arg && *arg == 'g') {
++#ifdef HAVE_GETTID
++ pid_t tid = gettid();
++#else
+ pid_t tid = syscall(SYS_gettid);
++#endif
+ if (tid == -1)
+ return 0;
+ return apr_snprintf(buf, buflen, "%"APR_PID_T_FMT, tid);
+ }
+-#endif
++#endif /* HAVE_GETTID || HAVE_SYS_GETTID */
+ #if APR_HAS_THREADS
+ if (ap_mpm_query(AP_MPMQ_IS_THREADED, &result) == APR_SUCCESS
+ && result != AP_MPMQ_NOT_SUPPORTED)
+@@ -966,7 +970,7 @@
+ #if APR_HAS_THREADS
+ field_start = len;
+ len += cpystrn(buf + len, ":tid ", buflen - len);
+- item_len = log_tid(info, NULL, buf + len, buflen - len);
++ item_len = log_tid(info, "g", buf + len, buflen - len);
+ if (!item_len)
+ len = field_start;
+ else
diff --git a/backport-httpd-2.4.43-r1861793+.patch b/backport-httpd-2.4.43-r1861793+.patch
new file mode 100644
index 0000000..08e96cb
--- /dev/null
+++ b/backport-httpd-2.4.43-r1861793+.patch
@@ -0,0 +1,271 @@
+diff --git a/configure.in b/configure.in
+index cb43246..0bb6b0d 100644
+--- httpd-2.4.43/configure.in.r1861793+
++++ httpd-2.4.43/configure.in
+@@ -465,6 +465,28 @@
+ AC_SEARCH_LIBS(crypt, crypt)
+ CRYPT_LIBS="$LIBS"
+ APACHE_SUBST(CRYPT_LIBS)
++
++if test "$ac_cv_search_crypt" != "no"; then
++ # Test crypt() with the SHA-512 test vector from https://akkadia.org/drepper/SHA-crypt.txt
++ AC_CACHE_CHECK([whether crypt() supports SHA-2], [ap_cv_crypt_sha2], [
++ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
++#include <crypt.h>
++#include <stdlib.h>
++#include <string.h>
++
++#define PASSWD_0 "Hello world!"
++#define SALT_0 "\$6\$saltstring"
++#define EXPECT_0 "\$6\$saltstring\$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu" \
++ "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1"
++]], [char *result = crypt(PASSWD_0, SALT_0);
++ if (!result) return 1;
++ if (strcmp(result, EXPECT_0)) return 2;
++])], [ap_cv_crypt_sha2=yes], [ap_cv_crypt_sha2=no])])
++ if test "$ap_cv_crypt_sha2" = yes; then
++ AC_DEFINE([HAVE_CRYPT_SHA2], 1, [Define if crypt() supports SHA-2 hashes])
++ fi
++fi
++
+ LIBS="$saved_LIBS"
+
+ dnl See Comment #Spoon
+--- httpd-2.4.43/docs/man/htpasswd.1.r1861793+
++++ httpd-2.4.43/docs/man/htpasswd.1
+@@ -27,16 +27,16 @@
+ .SH "SYNOPSIS"
+
+ .PP
+-\fB\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR\fR
++\fB\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR\fR
+
+ .PP
+-\fB\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR\fR
++\fB\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR\fR
+
+ .PP
+-\fB\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR\fR
++\fB\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR\fR
+
+ .PP
+-\fB\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR\fR
++\fB\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR\fR
+
+
+ .SH "SUMMARY"
+@@ -48,7 +48,7 @@
+ Resources available from the Apache HTTP server can be restricted to just the users listed in the files created by \fBhtpasswd\fR\&. This program can only manage usernames and passwords stored in a flat-file\&. It can encrypt and display password information for use in other types of data stores, though\&. To use a DBM database see dbmmanage or htdbm\&.
+
+ .PP
+-\fBhtpasswd\fR encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA1, or the system's \fBcrypt()\fR routine\&. Files managed by \fBhtpasswd\fR may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with \fBcrypt()\fR\&.
++\fBhtpasswd\fR encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA-1, or the system's \fBcrypt()\fR routine\&. SHA-2-based hashes (SHA-256 and SHA-512) are supported for \fBcrypt()\fR\&. Files managed by \fBhtpasswd\fR may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with \fBcrypt()\fR\&.
+
+ .PP
+ This manual page only lists the command line arguments\&. For details of the directives necessary to configure user authentication in httpd see the Apache manual, which is part of the Apache distribution or can be found at http://httpd\&.apache\&.org/\&.
+@@ -73,17 +73,26 @@
+ \fB-m\fR
+ Use MD5 encryption for passwords\&. This is the default (since version 2\&.2\&.18)\&.
+ .TP
++\fB-2\fR
++Use SHA-256 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&.
++.TP
++\fB-5\fR
++Use SHA-512 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&.
++.TP
+ \fB-B\fR
+ Use bcrypt encryption for passwords\&. This is currently considered to be very secure\&.
+ .TP
+ \fB-C\fR
+ This flag is only allowed in combination with \fB-B\fR (bcrypt encryption)\&. It sets the computing time used for the bcrypt algorithm (higher is more secure but slower, default: 5, valid: 4 to 17)\&.
+ .TP
++\fB-r\fR
++This flag is only allowed in combination with \fB-2\fR or \fB-5\fR\&. It sets the number of hash rounds used for the SHA-2 algorithms (higher is more secure but slower; the default is 5,000)\&.
++.TP
+ \fB-d\fR
+ Use \fBcrypt()\fR encryption for passwords\&. This is not supported by the httpd server on Windows and Netware\&. This algorithm limits the password length to 8 characters\&. This algorithm is \fBinsecure\fR by today's standards\&. It used to be the default algorithm until version 2\&.2\&.17\&.
+ .TP
+ \fB-s\fR
+-Use SHA encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&.
++Use SHA-1 (160-bit) encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&.
+ .TP
+ \fB-p\fR
+ Use plaintext passwords\&. Though \fBhtpasswd\fR will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows and Netware\&.
+@@ -152,10 +161,13 @@
+ When using the \fBcrypt()\fR algorithm, note that only the first 8 characters of the password are used to form the password\&. If the supplied password is longer, the extra characters will be silently discarded\&.
+
+ .PP
+-The SHA encryption format does not use salting: for a given password, there is only one encrypted representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&.
++The SHA-1 encryption format does not use salting: for a given password, there is only one encrypted representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&.
++
++.PP
++The SHA-1 and \fBcrypt()\fR formats are insecure by today's standards\&.
+
+ .PP
+-The SHA and \fBcrypt()\fR formats are insecure by today's standards\&.
++The SHA-2-based \fBcrypt()\fR formats (SHA-256 and SHA-512) are supported on most modern Unix systems, and follow the specification at https://www\&.akkadia\&.org/drepper/SHA-crypt\&.txt\&.
+
+ .SH "RESTRICTIONS"
+
+--- httpd-2.4.43/support/htpasswd.c.r1861793+
++++ httpd-2.4.43/support/htpasswd.c
+@@ -109,17 +109,21 @@
+ "for it." NL
+ " -i Read password from stdin without verification (for script usage)." NL
+ " -m Force MD5 encryption of the password (default)." NL
+- " -B Force bcrypt encryption of the password (very secure)." NL
++ " -2 Force SHA-256 crypt() hash of the password (very secure)." NL
++ " -5 Force SHA-512 crypt() hash of the password (very secure)." NL
++ " -B Force bcrypt encryption of the password (very secure)." NL
+ " -C Set the computing time used for the bcrypt algorithm" NL
+ " (higher is more secure but slower, default: %d, valid: 4 to 17)." NL
++ " -r Set the number of rounds used for the SHA-256, SHA-512 algorithms" NL
++ " (higher is more secure but slower, default: 5000)." NL
+ " -d Force CRYPT encryption of the password (8 chars max, insecure)." NL
+- " -s Force SHA encryption of the password (insecure)." NL
++ " -s Force SHA-1 encryption of the password (insecure)." NL
+ " -p Do not encrypt the password (plaintext, insecure)." NL
+ " -D Delete the specified user." NL
+ " -v Verify password for the specified user." NL
+ "On other systems than Windows and NetWare the '-p' flag will "
+ "probably not work." NL
+- "The SHA algorithm does not use a salt and is less secure than the "
++ "The SHA-1 algorithm does not use a salt and is less secure than the "
+ "MD5 algorithm." NL,
+ BCRYPT_DEFAULT_COST
+ );
+@@ -178,7 +182,7 @@
+ if (rv != APR_SUCCESS)
+ exit(ERR_SYNTAX);
+
+- while ((rv = apr_getopt(state, "cnmspdBbDiC:v", &opt, &opt_arg)) == APR_SUCCESS) {
++ while ((rv = apr_getopt(state, "cnmspdBbDi25C:r:v", &opt, &opt_arg)) == APR_SUCCESS) {
+ switch (opt) {
+ case 'c':
+ *mask |= APHTP_NEWFILE;
+--- httpd-2.4.43/support/passwd_common.c.r1861793+
++++ httpd-2.4.43/support/passwd_common.c
+@@ -179,16 +179,21 @@
+ int mkhash(struct passwd_ctx *ctx)
+ {
+ char *pw;
+- char salt[16];
++ char salt[17];
+ apr_status_t rv;
+ int ret = 0;
+ #if CRYPT_ALGO_SUPPORTED
+ char *cbuf;
+ #endif
++#ifdef HAVE_CRYPT_SHA2
++ const char *setting;
++ char method;
++#endif
+
+- if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT) {
++ if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT
++ && ctx->alg != ALG_CRYPT_SHA256 && ctx->alg != ALG_CRYPT_SHA512 ) {
+ apr_file_printf(errfile,
+- "Warning: Ignoring -C argument for this algorithm." NL);
++ "Warning: Ignoring -C/-r argument for this algorithm." NL);
+ }
+
+ if (ctx->passwd == NULL) {
+@@ -246,6 +251,34 @@
+ break;
+ #endif /* CRYPT_ALGO_SUPPORTED */
+
++#ifdef HAVE_CRYPT_SHA2
++ case ALG_CRYPT_SHA256:
++ case ALG_CRYPT_SHA512:
++ ret = generate_salt(salt, 16, &ctx->errstr, ctx->pool);
++ if (ret != 0)
++ break;
++
++ method = ctx->alg == ALG_CRYPT_SHA256 ? '5': '6';
++
++ if (ctx->cost)
++ setting = apr_psprintf(ctx->pool, "$%c$rounds=%d$%s",
++ method, ctx->cost, salt);
++ else
++ setting = apr_psprintf(ctx->pool, "$%c$%s",
++ method, salt);
++
++ cbuf = crypt(pw, setting);
++ if (cbuf == NULL) {
++ rv = APR_FROM_OS_ERROR(errno);
++ ctx->errstr = apr_psprintf(ctx->pool, "crypt() failed: %pm", &rv);
++ ret = ERR_PWMISMATCH;
++ break;
++ }
++
++ apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1);
++ break;
++#endif /* HAVE_CRYPT_SHA2 */
++
+ #if BCRYPT_ALGO_SUPPORTED
+ case ALG_BCRYPT:
+ rv = apr_generate_random_bytes((unsigned char*)salt, 16);
+@@ -294,6 +327,19 @@
+ case 's':
+ ctx->alg = ALG_APSHA;
+ break;
++#ifdef HAVE_CRYPT_SHA2
++ case '2':
++ ctx->alg = ALG_CRYPT_SHA256;
++ break;
++ case '5':
++ ctx->alg = ALG_CRYPT_SHA512;
++ break;
++#else
++ case '2':
++ case '5':
++ ctx->errstr = "SHA-2 crypt() algorithms are not supported on this platform.";
++ return ERR_ALG_NOT_SUPP;
++#endif
+ case 'p':
+ ctx->alg = ALG_PLAIN;
+ #if !PLAIN_ALGO_SUPPORTED
+@@ -324,11 +370,12 @@
+ return ERR_ALG_NOT_SUPP;
+ #endif
+ break;
+- case 'C': {
++ case 'C':
++ case 'r': {
+ char *endptr;
+ long num = strtol(opt_arg, &endptr, 10);
+ if (*endptr != '\0' || num <= 0) {
+- ctx->errstr = "argument to -C must be a positive integer";
++ ctx->errstr = "argument to -C/-r must be a positive integer";
+ return ERR_SYNTAX;
+ }
+ ctx->cost = num;
+--- httpd-2.4.43/support/passwd_common.h.r1861793+
++++ httpd-2.4.43/support/passwd_common.h
+@@ -28,6 +28,8 @@
+ #include "apu_version.h"
+ #endif
+
++#include "ap_config_auto.h"
++
+ #define MAX_STRING_LEN 256
+
+ #define ALG_PLAIN 0
+@@ -35,6 +37,8 @@
+ #define ALG_APMD5 2
+ #define ALG_APSHA 3
+ #define ALG_BCRYPT 4
++#define ALG_CRYPT_SHA256 5
++#define ALG_CRYPT_SHA512 6
+
+ #define BCRYPT_DEFAULT_COST 5
+
+@@ -84,7 +88,7 @@
+ apr_size_t out_len;
+ char *passwd;
+ int alg;
+- int cost;
++ int cost; /* cost for bcrypt, rounds for SHA-2 */
+ enum {
+ PW_PROMPT = 0,
+ PW_ARG,
diff --git a/backport-httpd-2.4.43-socket-activation.patch b/backport-httpd-2.4.43-socket-activation.patch
new file mode 100644
index 0000000..dd875c6
--- /dev/null
+++ b/backport-httpd-2.4.43-socket-activation.patch
@@ -0,0 +1,299 @@
+diff --git a/server/listen.c b/server/listen.c
+index 5242c2a..e2e028a 100644
+--- a/server/listen.c
++++ b/server/listen.c
+@@ -34,6 +34,10 @@
+ #include <unistd.h>
+ #endif
+
++#ifdef HAVE_SYSTEMD
++#include <systemd/sd-daemon.h>
++#endif
++
+ /* we know core's module_index is 0 */
+ #undef APLOG_MODULE_INDEX
+ #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
+@@ -59,9 +63,12 @@ static int ap_listenbacklog;
+ static int ap_listencbratio;
+ static int send_buffer_size;
+ static int receive_buffer_size;
++#ifdef HAVE_SYSTEMD
++static int use_systemd = -1;
++#endif
+
+ /* TODO: make_sock is just begging and screaming for APR abstraction */
+-static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
++static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_listen)
+ {
+ apr_socket_t *s = server->sd;
+ int one = 1;
+@@ -94,20 +101,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
+ return stat;
+ }
+
+-#if APR_HAVE_IPV6
+- if (server->bind_addr->family == APR_INET6) {
+- stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting);
+- if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
+- ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069)
+- "make_sock: for address %pI, apr_socket_opt_set: "
+- "(IPV6_V6ONLY)",
+- server->bind_addr);
+- apr_socket_close(s);
+- return stat;
+- }
+- }
+-#endif
+-
+ /*
+ * To send data over high bandwidth-delay connections at full
+ * speed we must force the TCP window to open wide enough to keep the
+@@ -169,21 +162,37 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
+ }
+ #endif
+
+- if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
+- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072)
+- "make_sock: could not bind to address %pI",
+- server->bind_addr);
+- apr_socket_close(s);
+- return stat;
+- }
++ if (do_bind_listen) {
++#if APR_HAVE_IPV6
++ if (server->bind_addr->family == APR_INET6) {
++ stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting);
++ if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
++ ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069)
++ "make_sock: for address %pI, apr_socket_opt_set: "
++ "(IPV6_V6ONLY)",
++ server->bind_addr);
++ apr_socket_close(s);
++ return stat;
++ }
++ }
++#endif
+
+- if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
+- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073)
+- "make_sock: unable to listen for connections "
+- "on address %pI",
+- server->bind_addr);
+- apr_socket_close(s);
+- return stat;
++ if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
++ ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072)
++ "make_sock: could not bind to address %pI",
++ server->bind_addr);
++ apr_socket_close(s);
++ return stat;
++ }
++
++ if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
++ ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073)
++ "make_sock: unable to listen for connections "
++ "on address %pI",
++ server->bind_addr);
++ apr_socket_close(s);
++ return stat;
++ }
+ }
+
+ #ifdef WIN32
+@@ -315,6 +324,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
+ return found;
+ }
+
++#ifdef HAVE_SYSTEMD
++
++static int find_systemd_socket(process_rec * process, apr_port_t port) {
++ int fdcount, fd;
++ int sdc = sd_listen_fds(0);
++
++ if (sdc < 0) {
++ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486)
++ "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d",
++ sdc);
++ return -1;
++ }
++
++ if (sdc == 0) {
++ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487)
++ "find_systemd_socket: At least one socket must be set.");
++ return -1;
++ }
++
++ fdcount = atoi(getenv("LISTEN_FDS"));
++ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) {
++ if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) {
++ return fd;
++ }
++ }
++
++ return -1;
++}
++
++static apr_status_t alloc_systemd_listener(process_rec * process,
++ int fd, const char *proto,
++ ap_listen_rec **out_rec)
++{
++ apr_status_t rv;
++ struct sockaddr sa;
++ socklen_t len = sizeof(struct sockaddr);
++ apr_os_sock_info_t si;
++ ap_listen_rec *rec;
++ *out_rec = NULL;
++
++ memset(&si, 0, sizeof(si));
++
++ rv = getsockname(fd, &sa, &len);
++
++ if (rv != 0) {
++ rv = apr_get_netos_error();
++ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02489)
++ "getsockname on %d failed.", fd);
++ return rv;
++ }
++
++ si.os_sock = &fd;
++ si.family = sa.sa_family;
++ si.local = &sa;
++ si.type = SOCK_STREAM;
++ si.protocol = APR_PROTO_TCP;
++
++ rec = apr_palloc(process->pool, sizeof(ap_listen_rec));
++ rec->active = 0;
++ rec->next = 0;
++
++
++ rv = apr_os_sock_make(&rec->sd, &si, process->pool);
++ if (rv != APR_SUCCESS) {
++ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02490)
++ "apr_os_sock_make on %d failed.", fd);
++ return rv;
++ }
++
++ rv = apr_socket_addr_get(&rec->bind_addr, APR_LOCAL, rec->sd);
++ if (rv != APR_SUCCESS) {
++ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02491)
++ "apr_socket_addr_get on %d failed.", fd);
++ return rv;
++ }
++
++ rec->protocol = apr_pstrdup(process->pool, proto);
++
++ *out_rec = rec;
++
++ return make_sock(process->pool, rec, 0);
++}
++
++static const char *set_systemd_listener(process_rec *process, apr_port_t port,
++ const char *proto)
++{
++ ap_listen_rec *last, *new;
++ apr_status_t rv;
++ int fd = find_systemd_socket(process, port);
++ if (fd < 0) {
++ return "Systemd socket activation is used, but this port is not "
++ "configured in systemd";
++ }
++
++ last = ap_listeners;
++ while (last && last->next) {
++ last = last->next;
++ }
++
++ rv = alloc_systemd_listener(process, fd, proto, &new);
++ if (rv != APR_SUCCESS) {
++ return "Failed to setup socket passed by systemd using socket activation";
++ }
++
++ if (last == NULL) {
++ ap_listeners = last = new;
++ }
++ else {
++ last->next = new;
++ last = new;
++ }
++
++ return NULL;
++}
++
++#endif /* HAVE_SYSTEMD */
++
+ static const char *alloc_listener(process_rec *process, const char *addr,
+ apr_port_t port, const char* proto,
+ void *slave)
+@@ -495,7 +621,7 @@ static int open_listeners(apr_pool_t *pool)
+ }
+ }
+ #endif
+- if (make_sock(pool, lr) == APR_SUCCESS) {
++ if (make_sock(pool, lr, 1) == APR_SUCCESS) {
+ ++num_open;
+ }
+ else {
+@@ -607,8 +733,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
+ }
+ }
+
+- if (open_listeners(s->process->pool)) {
+- return 0;
++#ifdef HAVE_SYSTEMD
++ if (use_systemd) {
++ const char *userdata_key = "ap_open_systemd_listeners";
++ void *data;
++ /* clear the enviroment on our second run
++ * so that none of our future children get confused.
++ */
++ apr_pool_userdata_get(&data, userdata_key, s->process->pool);
++ if (!data) {
++ apr_pool_userdata_set((const void *)1, userdata_key,
++ apr_pool_cleanup_null, s->process->pool);
++ }
++ else {
++ sd_listen_fds(1);
++ }
++ }
++ else
++#endif
++ {
++ if (open_listeners(s->process->pool)) {
++ return 0;
++ }
+ }
+
+ for (lr = ap_listeners; lr; lr = lr->next) {
+@@ -698,7 +844,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
+ duplr->bind_addr);
+ return stat;
+ }
+- make_sock(p, duplr);
++ make_sock(p, duplr, 1);
+ #if AP_NONBLOCK_WHEN_MULTI_LISTEN
+ use_nonblock = (ap_listeners && ap_listeners->next);
+ stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock);
+@@ -825,6 +971,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
+ if (argc < 1 || argc > 2) {
+ return "Listen requires 1 or 2 arguments.";
+ }
++#ifdef HAVE_SYSTEMD
++ if (use_systemd == -1) {
++ use_systemd = sd_listen_fds(0) > 0;
++ }
++#endif
+
+ rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool);
+ if (rv != APR_SUCCESS) {
+@@ -856,6 +1007,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
+ ap_str_tolower(proto);
+ }
+
++#ifdef HAVE_SYSTEMD
++ if (use_systemd) {
++ return set_systemd_listener(cmd->server->process, port, proto);
++ }
++#endif
++
+ return alloc_listener(cmd->server->process, host, port, proto, NULL);
+ }
diff --git a/backport-httpd-2.4.43-sslciphdefault.patch b/backport-httpd-2.4.43-sslciphdefault.patch
new file mode 100644
index 0000000..85ae568
--- /dev/null
+++ b/backport-httpd-2.4.43-sslciphdefault.patch
@@ -0,0 +1,31 @@
+diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
+index 97778a8..27e7a53 100644
+--- a/modules/ssl/ssl_engine_config.c
++++ b/modules/ssl/ssl_engine_config.c
+@@ -778,9 +778,11 @@ const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
+ }
+
+ if (!strcmp("SSL", arg1)) {
+- /* always disable null and export ciphers */
+- arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
+ if (cmd->path) {
++ /* Disable null and export ciphers by default, except for PROFILE=
++ * configs where the parser doesn't cope. */
++ if (strncmp(arg2, "PROFILE=", 8) != 0)
++ arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
+ dc->szCipherSuite = arg2;
+ }
+ else {
+@@ -1544,8 +1546,10 @@ const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
+ }
+
+ if (!strcmp("SSL", arg1)) {
+- /* always disable null and export ciphers */
+- arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
++ /* Disable null and export ciphers by default, except for PROFILE=
++ * configs where the parser doesn't cope. */
++ if (strncmp(arg2, "PROFILE=", 8) != 0)
++ arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
+ dc->proxy->auth.cipher_suite = arg2;
+ return NULL;
+ }
diff --git a/backport-httpd-2.4.43-sslprotdefault.patch b/backport-httpd-2.4.43-sslprotdefault.patch
new file mode 100644
index 0000000..b9ca049
--- /dev/null
+++ b/backport-httpd-2.4.43-sslprotdefault.patch
@@ -0,0 +1,99 @@
+diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
+index 27e7a53..b53f3f8 100644
+--- a/modules/ssl/ssl_engine_config.c
++++ b/modules/ssl/ssl_engine_config.c
+@@ -119,7 +119,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p)
+ mctx->ticket_key = NULL;
+ #endif
+
+- mctx->protocol = SSL_PROTOCOL_DEFAULT;
++ mctx->protocol = SSL_PROTOCOL_NONE;
+ mctx->protocol_set = 0;
+
+ mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET;
+@@ -263,6 +263,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p,
+ if (add->protocol_set) {
+ mrg->protocol_set = 1;
+ mrg->protocol = add->protocol;
++ mrg->protocol_set = 1;
+ }
+ else {
+ mrg->protocol_set = base->protocol_set;
+
+diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
+index bfad47a..b0fcf81 100644
+--- a/modules/ssl/ssl_engine_init.c
++++ b/modules/ssl/ssl_engine_init.c
+@@ -577,6 +577,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
+ MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL;
+ char *cp;
+ int protocol = mctx->protocol;
++ int protocol_set = mctx->protocol_set;
+ SSLSrvConfigRec *sc = mySrvConfig(s);
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ int prot;
+@@ -586,12 +587,18 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
+ * Create the new per-server SSL context
+ */
+ if (protocol == SSL_PROTOCOL_NONE) {
+- ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231)
+- "No SSL protocols available [hint: SSLProtocol]");
+- return ssl_die(s);
+- }
++ if (protocol_set) {
++ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231)
++ "No SSL protocols available [hint: SSLProtocol]");
++ return ssl_die(s);
++ }
+
+- cp = apr_pstrcat(p,
++ ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
++ "Using OpenSSL/system default SSL/TLS protocols");
++ cp = "default";
++ }
++ else {
++ cp = apr_pstrcat(p,
+ #ifndef OPENSSL_NO_SSL3
+ (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
+ #endif
+@@ -604,7 +611,8 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
+ #endif
+ #endif
+ NULL);
+- cp[strlen(cp)-2] = NUL;
++ cp[strlen(cp)-2] = NUL;
++ }
+
+ ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
+ "Creating new SSL context (protocols: %s)", cp);
+@@ -705,13 +713,15 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
+ prot = SSL3_VERSION;
+ #endif
+ } else {
+- SSL_CTX_free(ctx);
+- mctx->ssl_ctx = NULL;
+- ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(03378)
+- "No SSL protocols available [hint: SSLProtocol]");
+- return ssl_die(s);
++ if (protocol_set) {
++ SSL_CTX_free(ctx);
++ mctx->ssl_ctx = NULL;
++ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(03378)
++ "No SSL protocols available [hint: SSLProtocol]");
++ return ssl_die(s);
++ }
+ }
+- SSL_CTX_set_max_proto_version(ctx, prot);
++ if (protocol != SSL_PROTOCOL_NONE) SSL_CTX_set_max_proto_version(ctx, prot);
+
+ /* Next we scan for the minimal protocol version we should provide,
+ * but we do not allow holes between max and min */
+@@ -731,7 +741,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
+ prot = SSL3_VERSION;
+ }
+ #endif
+- SSL_CTX_set_min_proto_version(ctx, prot);
++ if (protocol != SSL_PROTOCOL_NONE) SSL_CTX_set_min_proto_version(ctx, prot);
+ #endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L */
+
+ #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
diff --git a/backport-httpd-2.4.46-htcacheclean-dont-break.patch b/backport-httpd-2.4.46-htcacheclean-dont-break.patch
new file mode 100644
index 0000000..e52318a
--- /dev/null
+++ b/backport-httpd-2.4.46-htcacheclean-dont-break.patch
@@ -0,0 +1,13 @@
+diff --git a/support/htcacheclean.c b/support/htcacheclean.c
+index 958ba6d..0a7fe3c 100644
+--- a/support/htcacheclean.c
++++ b/support/htcacheclean.c
+@@ -557,8 +557,6 @@ static int list_urls(char *path, apr_pool_t *pool, apr_off_t round)
+ }
+ }
+ }
+-
+- break;
+ }
+ }
+ }
diff --git a/backport-httpd-2.4.48-r1828172+.patch b/backport-httpd-2.4.48-r1828172+.patch
new file mode 100644
index 0000000..37f1855
--- /dev/null
+++ b/backport-httpd-2.4.48-r1828172+.patch
@@ -0,0 +1,2371 @@
+
+https://github.com/apache/httpd/pull/209
+
+diff --git a/modules/generators/cgi_common.h b/modules/generators/cgi_common.h
+new file mode 100644
+index 0000000000..69df73ce68
+--- /dev/null
++++ b/modules/generators/cgi_common.h
+@@ -0,0 +1,629 @@
++/* Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
++#include "apr.h"
++#include "apr_strings.h"
++#include "apr_buckets.h"
++#include "apr_lib.h"
++#include "apr_poll.h"
++
++#define APR_WANT_STRFUNC
++#define APR_WANT_MEMFUNC
++#include "apr_want.h"
++
++#include "httpd.h"
++#include "util_filter.h"
++
++static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgi_pfn_gtv;
++static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgi_pfn_ps;
++
++/* These functions provided by mod_cgi.c/mod_cgid.c still. */
++static int log_script(request_rec *r, cgi_server_conf * conf, int ret,
++ char *dbuf, const char *sbuf, apr_bucket_brigade *bb,
++ apr_file_t *script_err);
++static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f,
++ apr_bucket_brigade *bb, char *s);
++static apr_status_t include_cmd(include_ctx_t *ctx, ap_filter_t *f,
++ apr_bucket_brigade *bb, const char *command);
++
++/* Read and discard all output from the brigade. Note that with the
++ * CGI bucket, the brigade will become empty once the script's stdout
++ * is closed (or on error/timeout), but the stderr output may not have
++ * been entirely captured at this point. */
++static void discard_script_output(apr_bucket_brigade *bb)
++{
++ apr_bucket *e;
++ const char *buf;
++ apr_size_t len;
++
++ for (e = APR_BRIGADE_FIRST(bb);
++ e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e);
++ e = APR_BRIGADE_FIRST(bb))
++ {
++ if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) {
++ break;
++ }
++ apr_bucket_delete(e);
++ }
++}
++
++static int log_scripterror(request_rec *r, cgi_server_conf *conf, int ret,
++ apr_status_t rv, const char *logno,
++ const char *error)
++{
++ apr_file_t *f = NULL;
++ apr_finfo_t finfo;
++ char time_str[APR_CTIME_LEN];
++
++ /* Intentional no APLOGNO */
++ /* Callee provides APLOGNO in error text */
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
++ "%sstderr from %s: %s", logno ? logno : "", r->filename, error);
++
++ /* XXX Very expensive mainline case! Open, then getfileinfo! */
++ if (!conf->logname ||
++ ((apr_stat(&finfo, conf->logname,
++ APR_FINFO_SIZE, r->pool) == APR_SUCCESS) &&
++ (finfo.size > conf->logbytes)) ||
++ (apr_file_open(&f, conf->logname,
++ APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT,
++ r->pool) != APR_SUCCESS)) {
++ return ret;
++ }
++
++ /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */
++ apr_ctime(time_str, apr_time_now());
++ apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri,
++ r->args ? "?" : "", r->args ? r->args : "", r->protocol);
++ /* "%% 500 /usr/local/apache/cgi-bin */
++ apr_file_printf(f, "%%%% %d %s\n", ret, r->filename);
++
++ apr_file_printf(f, "%%error\n%s\n", error);
++
++ apr_file_close(f);
++ return ret;
++}
++
++/* Soak up stderr from a script and redirect it to the error log.
++ */
++static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err)
++{
++ char argsbuffer[HUGE_STRING_LEN];
++ char *newline;
++ apr_status_t rv;
++ cgi_server_conf *conf = ap_get_module_config(r->server->module_config, &cgi_module);
++
++ while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN,
++ script_err)) == APR_SUCCESS) {
++
++ newline = strchr(argsbuffer, '\n');
++ if (newline) {
++ char *prev = newline - 1;
++ if (prev >= argsbuffer && *prev == '\r') {
++ newline = prev;
++ }
++
++ *newline = '\0';
++ }
++ log_scripterror(r, conf, r->status, 0, APLOGNO(01215), argsbuffer);
++ }
++
++ return rv;
++}
++
++static apr_status_t cgi_handle_exec(include_ctx_t *ctx, ap_filter_t *f,
++ apr_bucket_brigade *bb)
++{
++ char *tag = NULL;
++ char *tag_val = NULL;
++ request_rec *r = f->r;
++ char *file = r->filename;
++ char parsed_string[MAX_STRING_LEN];
++
++ if (!ctx->argc) {
++ ap_log_rerror(APLOG_MARK,
++ (ctx->flags & SSI_FLAG_PRINTING)
++ ? APLOG_ERR : APLOG_WARNING,
++ 0, r, APLOGNO(03195)
++ "missing argument for exec element in %s", r->filename);
++ }
++
++ if (!(ctx->flags & SSI_FLAG_PRINTING)) {
++ return APR_SUCCESS;
++ }
++
++ if (!ctx->argc) {
++ SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
++ return APR_SUCCESS;
++ }
++
++ if (ctx->flags & SSI_FLAG_NO_EXEC) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01228) "exec used but not allowed "
++ "in %s", r->filename);
++ SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
++ return APR_SUCCESS;
++ }
++
++ while (1) {
++ cgi_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED);
++ if (!tag || !tag_val) {
++ break;
++ }
++
++ if (!strcmp(tag, "cmd")) {
++ apr_status_t rv;
++
++ cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string),
++ SSI_EXPAND_LEAVE_NAME);
++
++ rv = include_cmd(ctx, f, bb, parsed_string);
++ if (rv != APR_SUCCESS) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01229) "execution failure "
++ "for parameter \"%s\" to tag exec in file %s",
++ tag, r->filename);
++ SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
++ break;
++ }
++ }
++ else if (!strcmp(tag, "cgi")) {
++ apr_status_t rv;
++
++ cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string),
++ SSI_EXPAND_DROP_NAME);
++
++ rv = include_cgi(ctx, f, bb, parsed_string);
++ if (rv != APR_SUCCESS) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01230) "invalid CGI ref "
++ "\"%s\" in %s", tag_val, file);
++ SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
++ break;
++ }
++ }
++ else {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01231) "unknown parameter "
++ "\"%s\" to tag exec in %s", tag, file);
++ SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
++ break;
++ }
++ }
++
++ return APR_SUCCESS;
++}
++
++/* Hook to register exec= handling with mod_include. */
++static void cgi_optfns_retrieve(void)
++{
++ APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgi_pfn_reg_with_ssi;
++
++ cgi_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler);
++ cgi_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value);
++ cgi_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string);
++
++ if (cgi_pfn_reg_with_ssi && cgi_pfn_gtv && cgi_pfn_ps) {
++ /* Required by mod_include filter. This is how mod_cgi registers
++ * with mod_include to provide processing of the exec directive.
++ */
++ cgi_pfn_reg_with_ssi("exec", cgi_handle_exec);
++ }
++}
++
++#ifdef WANT_CGI_BUCKET
++/* A CGI bucket type is needed to catch any output to stderr from the
++ * script; see PR 22030. */
++static const apr_bucket_type_t bucket_type_cgi;
++
++struct cgi_bucket_data {
++ apr_pollset_t *pollset;
++ request_rec *r;
++ apr_interval_time_t timeout;
++};
++
++/* Create a CGI bucket using pipes from script stdout 'out'
++ * and stderr 'err', for request 'r'. */
++static apr_bucket *cgi_bucket_create(request_rec *r,
++ apr_interval_time_t timeout,
++ apr_file_t *out, apr_file_t *err,
++ apr_bucket_alloc_t *list)
++{
++ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
++ apr_status_t rv;
++ apr_pollfd_t fd;
++ struct cgi_bucket_data *data = apr_palloc(r->pool, sizeof *data);
++
++ /* Disable APR timeout handling since we'll use poll() entirely. */
++ apr_file_pipe_timeout_set(out, 0);
++ apr_file_pipe_timeout_set(err, 0);
++
++ APR_BUCKET_INIT(b);
++ b->free = apr_bucket_free;
++ b->list = list;
++ b->type = &bucket_type_cgi;
++ b->length = (apr_size_t)(-1);
++ b->start = -1;
++
++ /* Create the pollset */
++ rv = apr_pollset_create(&data->pollset, 2, r->pool, 0);
++ if (rv != APR_SUCCESS) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01217)
++ "apr_pollset_create(); check system or user limits");
++ return NULL;
++ }
++
++ fd.desc_type = APR_POLL_FILE;
++ fd.reqevents = APR_POLLIN;
++ fd.p = r->pool;
++ fd.desc.f = out; /* script's stdout */
++ fd.client_data = (void *)1;
++ rv = apr_pollset_add(data->pollset, &fd);
++ if (rv != APR_SUCCESS) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01218)
++ "apr_pollset_add(); check system or user limits");
++ return NULL;
++ }
++
++ fd.desc.f = err; /* script's stderr */
++ fd.client_data = (void *)2;
++ rv = apr_pollset_add(data->pollset, &fd);
++ if (rv != APR_SUCCESS) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01219)
++ "apr_pollset_add(); check system or user limits");
++ return NULL;
++ }
++
++ data->r = r;
++ data->timeout = timeout;
++ b->data = data;
++ return b;
++}
++
++/* Create a duplicate CGI bucket using given bucket data */
++static apr_bucket *cgi_bucket_dup(struct cgi_bucket_data *data,
++ apr_bucket_alloc_t *list)
++{
++ apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
++ APR_BUCKET_INIT(b);
++ b->free = apr_bucket_free;
++ b->list = list;
++ b->type = &bucket_type_cgi;
++ b->length = (apr_size_t)(-1);
++ b->start = -1;
++ b->data = data;
++ return b;
++}
++
++/* Handle stdout from CGI child. Duplicate of logic from the _read
++ * method of the real APR pipe bucket implementation. */
++static apr_status_t cgi_read_stdout(apr_bucket *a, apr_file_t *out,
++ const char **str, apr_size_t *len)
++{
++ char *buf;
++ apr_status_t rv;
++
++ *str = NULL;
++ *len = APR_BUCKET_BUFF_SIZE;
++ buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */
++
++ rv = apr_file_read(out, buf, len);
++
++ if (rv != APR_SUCCESS && rv != APR_EOF) {
++ apr_bucket_free(buf);
++ return rv;
++ }
++
++ if (*len > 0) {
++ struct cgi_bucket_data *data = a->data;
++ apr_bucket_heap *h;
++
++ /* Change the current bucket to refer to what we read */
++ a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free);
++ h = a->data;
++ h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */
++ *str = buf;
++ APR_BUCKET_INSERT_AFTER(a, cgi_bucket_dup(data, a->list));
++ }
++ else {
++ apr_bucket_free(buf);
++ a = apr_bucket_immortal_make(a, "", 0);
++ *str = a->data;
++ }
++ return rv;
++}
++
++/* Read method of CGI bucket: polls on stderr and stdout of the child,
++ * sending any stderr output immediately away to the error log. */
++static apr_status_t cgi_bucket_read(apr_bucket *b, const char **str,
++ apr_size_t *len, apr_read_type_e block)
++{
++ struct cgi_bucket_data *data = b->data;
++ apr_interval_time_t timeout = 0;
++ apr_status_t rv;
++ int gotdata = 0;
++
++ if (block != APR_NONBLOCK_READ) {
++ timeout = data->timeout > 0 ? data->timeout : data->r->server->timeout;
++ }
++
++ do {
++ const apr_pollfd_t *results;
++ apr_int32_t num;
++
++ rv = apr_pollset_poll(data->pollset, timeout, &num, &results);
++ if (APR_STATUS_IS_TIMEUP(rv)) {
++ if (timeout) {
++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, data->r, APLOGNO(01220)
++ "Timeout waiting for output from CGI script %s",
++ data->r->filename);
++ return rv;
++ }
++ else {
++ return APR_EAGAIN;
++ }
++ }
++ else if (APR_STATUS_IS_EINTR(rv)) {
++ continue;
++ }
++ else if (rv != APR_SUCCESS) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, data->r, APLOGNO(01221)
++ "poll failed waiting for CGI child");
++ return rv;
++ }
++
++ for (; num; num--, results++) {
++ if (results[0].client_data == (void *)1) {
++ /* stdout */
++ rv = cgi_read_stdout(b, results[0].desc.f, str, len);
++ if (APR_STATUS_IS_EOF(rv)) {
++ rv = APR_SUCCESS;
++ }
++ gotdata = 1;
++ } else {
++ /* stderr */
++ apr_status_t rv2 = log_script_err(data->r, results[0].desc.f);
++ if (APR_STATUS_IS_EOF(rv2)) {
++ apr_pollset_remove(data->pollset, &results[0]);
++ }
++ }
++ }
++
++ } while (!gotdata);
++
++ return rv;
++}
++
++static const apr_bucket_type_t bucket_type_cgi = {
++ "CGI", 5, APR_BUCKET_DATA,
++ apr_bucket_destroy_noop,
++ cgi_bucket_read,
++ apr_bucket_setaside_notimpl,
++ apr_bucket_split_notimpl,
++ apr_bucket_copy_notimpl
++};
++
++#endif /* WANT_CGI_BUCKET */
++
++/* Handle the CGI response output, having set up the brigade with the
++ * CGI or PIPE bucket as appropriate. */
++static int cgi_handle_response(request_rec *r, int nph, apr_bucket_brigade *bb,
++ apr_interval_time_t timeout, cgi_server_conf *conf,
++ char *logdata, apr_file_t *script_err)
++{
++ apr_status_t rv;
++
++ /* Handle script return... */
++ if (!nph) {
++ const char *location;
++ char sbuf[MAX_STRING_LEN];
++ int ret;
++
++ if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf,
++ APLOG_MODULE_INDEX)))
++ {
++ /* In the case of a timeout reading script output, clear
++ * the brigade to avoid a second attempt to read the
++ * output. */
++ if (ret == HTTP_GATEWAY_TIME_OUT) {
++ apr_brigade_cleanup(bb);
++ }
++
++ ret = log_script(r, conf, ret, logdata, sbuf, bb, script_err);
++
++ /*
++ * ret could be HTTP_NOT_MODIFIED in the case that the CGI script
++ * does not set an explicit status and ap_meets_conditions, which
++ * is called by ap_scan_script_header_err_brigade, detects that
++ * the conditions of the requests are met and the response is
++ * not modified.
++ * In this case set r->status and return OK in order to prevent
++ * running through the error processing stack as this would
++ * break with mod_cache, if the conditions had been set by
++ * mod_cache itself to validate a stale entity.
++ * BTW: We circumvent the error processing stack anyway if the
++ * CGI script set an explicit status code (whatever it is) and
++ * the only possible values for ret here are:
++ *
++ * HTTP_NOT_MODIFIED (set by ap_meets_conditions)
++ * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions)
++ * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the
++ * processing of the response of the CGI script, e.g broken headers
++ * or a crashed CGI process).
++ */
++ if (ret == HTTP_NOT_MODIFIED) {
++ r->status = ret;
++ return OK;
++ }
++
++ return ret;
++ }
++
++ location = apr_table_get(r->headers_out, "Location");
++
++ if (location && r->status == 200) {
++ /* For a redirect whether internal or not, discard any
++ * remaining stdout from the script, and log any remaining
++ * stderr output, as normal. */
++ discard_script_output(bb);
++ apr_brigade_destroy(bb);
++
++ if (script_err) {
++ apr_file_pipe_timeout_set(script_err, timeout);
++ log_script_err(r, script_err);
++ }
++ }
++
++ if (location && location[0] == '/' && r->status == 200) {
++ /* This redirect needs to be a GET no matter what the original
++ * method was.
++ */
++ r->method = "GET";
++ r->method_number = M_GET;
++
++ /* We already read the message body (if any), so don't allow
++ * the redirected request to think it has one. We can ignore
++ * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR.
++ */
++ apr_table_unset(r->headers_in, "Content-Length");
++
++ ap_internal_redirect_handler(location, r);
++ return OK;
++ }
++ else if (location && r->status == 200) {
++ /* XXX: Note that if a script wants to produce its own Redirect
++ * body, it now has to explicitly *say* "Status: 302"
++ */
++ discard_script_output(bb);
++ apr_brigade_destroy(bb);
++ return HTTP_MOVED_TEMPORARILY;
++ }
++
++ rv = ap_pass_brigade(r->output_filters, bb);
++ }
++ else /* nph */ {
++ struct ap_filter_t *cur;
++
++ /* get rid of all filters up through protocol... since we
++ * haven't parsed off the headers, there is no way they can
++ * work
++ */
++
++ cur = r->proto_output_filters;
++ while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) {
++ cur = cur->next;
++ }
++ r->output_filters = r->proto_output_filters = cur;
++
++ rv = ap_pass_brigade(r->output_filters, bb);
++ }
++
++ /* don't soak up script output if errors occurred writing it
++ * out... otherwise, we prolong the life of the script when the
++ * connection drops or we stopped sending output for some other
++ * reason */
++ if (script_err && rv == APR_SUCCESS && !r->connection->aborted) {
++ apr_file_pipe_timeout_set(script_err, timeout);
++ log_script_err(r, script_err);
++ }
++
++ if (script_err) apr_file_close(script_err);
++
++ return OK; /* NOT r->status, even if it has changed. */
++}
++
++/* Read the request body and write it to fd 'script_out', using 'bb'
++ * as temporary bucket brigade. If 'logbuf' is non-NULL, the first
++ * logbufbytes of stdout are stored in logbuf. */
++static apr_status_t cgi_handle_request(request_rec *r, apr_file_t *script_out,
++ apr_bucket_brigade *bb,
++ char *logbuf, apr_size_t logbufbytes)
++{
++ int seen_eos = 0;
++ int child_stopped_reading = 0;
++ apr_status_t rv;
++ int dbpos = 0;
++
++ do {
++ apr_bucket *bucket;
++
++ rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
++ APR_BLOCK_READ, HUGE_STRING_LEN);
++
++ if (rv != APR_SUCCESS) {
++ return rv;
++ }
++
++ for (bucket = APR_BRIGADE_FIRST(bb);
++ bucket != APR_BRIGADE_SENTINEL(bb);
++ bucket = APR_BUCKET_NEXT(bucket))
++ {
++ const char *data;
++ apr_size_t len;
++
++ if (APR_BUCKET_IS_EOS(bucket)) {
++ seen_eos = 1;
++ break;
++ }
++
++ /* We can't do much with this. */
++ if (APR_BUCKET_IS_FLUSH(bucket)) {
++ continue;
++ }
++
++ /* If the child stopped, we still must read to EOS. */
++ if (child_stopped_reading) {
++ continue;
++ }
++
++ /* read */
++ rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
++ if (rv) {
++ return rv;
++ }
++
++ if (logbufbytes && dbpos < logbufbytes) {
++ int cursize;
++
++ if ((dbpos + len) > logbufbytes) {
++ cursize = logbufbytes - dbpos;
++ }
++ else {
++ cursize = len;
++ }
++ memcpy(logbuf + dbpos, data, cursize);
++ dbpos += cursize;
++ }
++
++ /* Keep writing data to the child until done or too much time
++ * elapses with no progress or an error occurs.
++ */
++ rv = apr_file_write_full(script_out, data, len, NULL);
++
++ if (rv != APR_SUCCESS) {
++ /* silly script stopped reading, soak up remaining message */
++ child_stopped_reading = 1;
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02651)
++ "Error writing request body to script %s",
++ r->filename);
++ }
++ }
++ apr_brigade_cleanup(bb);
++ }
++ while (!seen_eos);
++
++ if (logbuf) {
++ logbuf[dbpos] = '\0';
++ }
++
++ return APR_SUCCESS;
++}
+diff --git a/modules/generators/config5.m4 b/modules/generators/config5.m4
+index bf295217e0..086355353b 100644
+--- a/modules/generators/config5.m4
++++ b/modules/generators/config5.m4
+@@ -78,4 +78,15 @@ fi
+
+ APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
+
++AC_ARG_ENABLE(cgid-fdpassing,
++ [APACHE_HELP_STRING(--enable-cgid-fdpassing,Enable experimental mod_cgid support for fd passing)],
++ [if test "$enableval" = "yes"; then
++ AC_CHECK_DECL(CMSG_DATA,
++ [AC_DEFINE([HAVE_CGID_FDPASSING], 1, [Enable FD passing support in mod_cgid])],
++ [AC_MSG_ERROR([cannot support mod_cgid fd-passing on this system])], [
++#include <sys/types.h>
++#include <sys/socket.h>])
++ fi
++])
++
+ APACHE_MODPATH_FINISH
+diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c
+index 7e4b126c10..421124a0cb 100644
+--- a/modules/generators/mod_cgi.c
++++ b/modules/generators/mod_cgi.c
+@@ -61,9 +61,6 @@
+
+ module AP_MODULE_DECLARE_DATA cgi_module;
+
+-static APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgi_pfn_reg_with_ssi;
+-static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgi_pfn_gtv;
+-static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgi_pfn_ps;
+ static APR_OPTIONAL_FN_TYPE(ap_cgi_build_command) *cgi_build_command;
+
+ /* Read and discard the data in the brigade produced by a CGI script */
+@@ -92,6 +89,15 @@ typedef struct {
+ apr_size_t bufbytes;
+ } cgi_server_conf;
+
++typedef struct {
++ apr_interval_time_t timeout;
++} cgi_dirconf;
++
++#if APR_FILES_AS_SOCKETS
++#define WANT_CGI_BUCKET
++#endif
++#include "cgi_common.h"
++
+ static void *create_cgi_config(apr_pool_t *p, server_rec *s)
+ {
+ cgi_server_conf *c =
+@@ -112,6 +118,12 @@ static void *merge_cgi_config(apr_pool_t *p, void *basev, void *overridesv)
+ return overrides->logname ? overrides : base;
+ }
+
++static void *create_cgi_dirconf(apr_pool_t *p, char *dummy)
++{
++ cgi_dirconf *c = (cgi_dirconf *) apr_pcalloc(p, sizeof(cgi_dirconf));
++ return c;
++}
++
+ static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg)
+ {
+ server_rec *s = cmd->server;
+@@ -150,6 +162,17 @@ static const char *set_scriptlog_buffer(cmd_parms *cmd, void *dummy,
+ return NULL;
+ }
+
++static const char *set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg)
++{
++ cgi_dirconf *dc = dummy;
++
++ if (ap_timeout_parameter_parse(arg, &dc->timeout, "s") != APR_SUCCESS) {
++ return "CGIScriptTimeout has wrong format";
++ }
++
++ return NULL;
++}
++
+ static const command_rec cgi_cmds[] =
+ {
+ AP_INIT_TAKE1("ScriptLog", set_scriptlog, NULL, RSRC_CONF,
+@@ -158,67 +181,12 @@ AP_INIT_TAKE1("ScriptLogLength", set_scriptlog_length, NULL, RSRC_CONF,
+ "the maximum length (in bytes) of the script debug log"),
+ AP_INIT_TAKE1("ScriptLogBuffer", set_scriptlog_buffer, NULL, RSRC_CONF,
+ "the maximum size (in bytes) to record of a POST request"),
++AP_INIT_TAKE1("CGIScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_CONF,
++ "The amount of time to wait between successful reads from "
++ "the CGI script, in seconds."),
+ {NULL}
+ };
+
+-static int log_scripterror(request_rec *r, cgi_server_conf * conf, int ret,
+- apr_status_t rv, char *logno, char *error)
+-{
+- apr_file_t *f = NULL;
+- apr_finfo_t finfo;
+- char time_str[APR_CTIME_LEN];
+- int log_flags = rv ? APLOG_ERR : APLOG_ERR;
+-
+- /* Intentional no APLOGNO */
+- /* Callee provides APLOGNO in error text */
+- ap_log_rerror(APLOG_MARK, log_flags, rv, r,
+- "%s%s: %s", logno ? logno : "", error, r->filename);
+-
+- /* XXX Very expensive mainline case! Open, then getfileinfo! */
+- if (!conf->logname ||
+- ((apr_stat(&finfo, conf->logname,
+- APR_FINFO_SIZE, r->pool) == APR_SUCCESS) &&
+- (finfo.size > conf->logbytes)) ||
+- (apr_file_open(&f, conf->logname,
+- APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT,
+- r->pool) != APR_SUCCESS)) {
+- return ret;
+- }
+-
+- /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */
+- apr_ctime(time_str, apr_time_now());
+- apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri,
+- r->args ? "?" : "", r->args ? r->args : "", r->protocol);
+- /* "%% 500 /usr/local/apache/cgi-bin */
+- apr_file_printf(f, "%%%% %d %s\n", ret, r->filename);
+-
+- apr_file_printf(f, "%%error\n%s\n", error);
+-
+- apr_file_close(f);
+- return ret;
+-}
+-
+-/* Soak up stderr from a script and redirect it to the error log.
+- */
+-static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err)
+-{
+- char argsbuffer[HUGE_STRING_LEN];
+- char *newline;
+- apr_status_t rv;
+- cgi_server_conf *conf = ap_get_module_config(r->server->module_config, &cgi_module);
+-
+- while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN,
+- script_err)) == APR_SUCCESS) {
+- newline = strchr(argsbuffer, '\n');
+- if (newline) {
+- *newline = '\0';
+- }
+- log_scripterror(r, conf, r->status, 0, APLOGNO(01215), argsbuffer);
+- }
+-
+- return rv;
+-}
+-
+ static int log_script(request_rec *r, cgi_server_conf * conf, int ret,
+ char *dbuf, const char *sbuf, apr_bucket_brigade *bb,
+ apr_file_t *script_err)
+@@ -466,23 +434,26 @@ static apr_status_t run_cgi_child(apr_file_t **script_out,
+ apr_filepath_name_get(r->filename));
+ }
+ else {
++ cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module);
++ apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout;
++
+ apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT);
+
+ *script_in = procnew->out;
+ if (!*script_in)
+ return APR_EBADF;
+- apr_file_pipe_timeout_set(*script_in, r->server->timeout);
++ apr_file_pipe_timeout_set(*script_in, timeout);
+
+ if (e_info->prog_type == RUN_AS_CGI) {
+ *script_out = procnew->in;
+ if (!*script_out)
+ return APR_EBADF;
+- apr_file_pipe_timeout_set(*script_out, r->server->timeout);
++ apr_file_pipe_timeout_set(*script_out, timeout);
+
+ *script_err = procnew->err;
+ if (!*script_err)
+ return APR_EBADF;
+- apr_file_pipe_timeout_set(*script_err, r->server->timeout);
++ apr_file_pipe_timeout_set(*script_err, timeout);
+ }
+ }
+ }
+@@ -536,234 +507,30 @@ static apr_status_t default_build_command(const char **cmd, const char ***argv,
+ return APR_SUCCESS;
+ }
+
+-static void discard_script_output(apr_bucket_brigade *bb)
+-{
+- apr_bucket *e;
+- const char *buf;
+- apr_size_t len;
+-
+- for (e = APR_BRIGADE_FIRST(bb);
+- e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e);
+- e = APR_BRIGADE_FIRST(bb))
+- {
+- if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) {
+- break;
+- }
+- apr_bucket_delete(e);
+- }
+-}
+-
+-#if APR_FILES_AS_SOCKETS
+-
+-/* A CGI bucket type is needed to catch any output to stderr from the
+- * script; see PR 22030. */
+-static const apr_bucket_type_t bucket_type_cgi;
+-
+-struct cgi_bucket_data {
+- apr_pollset_t *pollset;
+- request_rec *r;
+-};
+-
+-/* Create a CGI bucket using pipes from script stdout 'out'
+- * and stderr 'err', for request 'r'. */
+-static apr_bucket *cgi_bucket_create(request_rec *r,
+- apr_file_t *out, apr_file_t *err,
+- apr_bucket_alloc_t *list)
+-{
+- apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
+- apr_status_t rv;
+- apr_pollfd_t fd;
+- struct cgi_bucket_data *data = apr_palloc(r->pool, sizeof *data);
+-
+- APR_BUCKET_INIT(b);
+- b->free = apr_bucket_free;
+- b->list = list;
+- b->type = &bucket_type_cgi;
+- b->length = (apr_size_t)(-1);
+- b->start = -1;
+-
+- /* Create the pollset */
+- rv = apr_pollset_create(&data->pollset, 2, r->pool, 0);
+- if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01217)
+- "apr_pollset_create(); check system or user limits");
+- return NULL;
+- }
+-
+- fd.desc_type = APR_POLL_FILE;
+- fd.reqevents = APR_POLLIN;
+- fd.p = r->pool;
+- fd.desc.f = out; /* script's stdout */
+- fd.client_data = (void *)1;
+- rv = apr_pollset_add(data->pollset, &fd);
+- if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01218)
+- "apr_pollset_add(); check system or user limits");
+- return NULL;
+- }
+-
+- fd.desc.f = err; /* script's stderr */
+- fd.client_data = (void *)2;
+- rv = apr_pollset_add(data->pollset, &fd);
+- if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01219)
+- "apr_pollset_add(); check system or user limits");
+- return NULL;
+- }
+-
+- data->r = r;
+- b->data = data;
+- return b;
+-}
+-
+-/* Create a duplicate CGI bucket using given bucket data */
+-static apr_bucket *cgi_bucket_dup(struct cgi_bucket_data *data,
+- apr_bucket_alloc_t *list)
+-{
+- apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
+- APR_BUCKET_INIT(b);
+- b->free = apr_bucket_free;
+- b->list = list;
+- b->type = &bucket_type_cgi;
+- b->length = (apr_size_t)(-1);
+- b->start = -1;
+- b->data = data;
+- return b;
+-}
+-
+-/* Handle stdout from CGI child. Duplicate of logic from the _read
+- * method of the real APR pipe bucket implementation. */
+-static apr_status_t cgi_read_stdout(apr_bucket *a, apr_file_t *out,
+- const char **str, apr_size_t *len)
+-{
+- char *buf;
+- apr_status_t rv;
+-
+- *str = NULL;
+- *len = APR_BUCKET_BUFF_SIZE;
+- buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */
+-
+- rv = apr_file_read(out, buf, len);
+-
+- if (rv != APR_SUCCESS && rv != APR_EOF) {
+- apr_bucket_free(buf);
+- return rv;
+- }
+-
+- if (*len > 0) {
+- struct cgi_bucket_data *data = a->data;
+- apr_bucket_heap *h;
+-
+- /* Change the current bucket to refer to what we read */
+- a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free);
+- h = a->data;
+- h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */
+- *str = buf;
+- APR_BUCKET_INSERT_AFTER(a, cgi_bucket_dup(data, a->list));
+- }
+- else {
+- apr_bucket_free(buf);
+- a = apr_bucket_immortal_make(a, "", 0);
+- *str = a->data;
+- }
+- return rv;
+-}
+-
+-/* Read method of CGI bucket: polls on stderr and stdout of the child,
+- * sending any stderr output immediately away to the error log. */
+-static apr_status_t cgi_bucket_read(apr_bucket *b, const char **str,
+- apr_size_t *len, apr_read_type_e block)
+-{
+- struct cgi_bucket_data *data = b->data;
+- apr_interval_time_t timeout;
+- apr_status_t rv;
+- int gotdata = 0;
+-
+- timeout = block == APR_NONBLOCK_READ ? 0 : data->r->server->timeout;
+-
+- do {
+- const apr_pollfd_t *results;
+- apr_int32_t num;
+-
+- rv = apr_pollset_poll(data->pollset, timeout, &num, &results);
+- if (APR_STATUS_IS_TIMEUP(rv)) {
+- if (timeout) {
+- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, data->r, APLOGNO(01220)
+- "Timeout waiting for output from CGI script %s",
+- data->r->filename);
+- return rv;
+- }
+- else {
+- return APR_EAGAIN;
+- }
+- }
+- else if (APR_STATUS_IS_EINTR(rv)) {
+- continue;
+- }
+- else if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, data->r, APLOGNO(01221)
+- "poll failed waiting for CGI child");
+- return rv;
+- }
+-
+- for (; num; num--, results++) {
+- if (results[0].client_data == (void *)1) {
+- /* stdout */
+- rv = cgi_read_stdout(b, results[0].desc.f, str, len);
+- if (APR_STATUS_IS_EOF(rv)) {
+- rv = APR_SUCCESS;
+- }
+- gotdata = 1;
+- } else {
+- /* stderr */
+- apr_status_t rv2 = log_script_err(data->r, results[0].desc.f);
+- if (APR_STATUS_IS_EOF(rv2)) {
+- apr_pollset_remove(data->pollset, &results[0]);
+- }
+- }
+- }
+-
+- } while (!gotdata);
+-
+- return rv;
+-}
+-
+-static const apr_bucket_type_t bucket_type_cgi = {
+- "CGI", 5, APR_BUCKET_DATA,
+- apr_bucket_destroy_noop,
+- cgi_bucket_read,
+- apr_bucket_setaside_notimpl,
+- apr_bucket_split_notimpl,
+- apr_bucket_copy_notimpl
+-};
+-
+-#endif
+-
+ static int cgi_handler(request_rec *r)
+ {
+ int nph;
+- apr_size_t dbpos = 0;
++ apr_size_t dbufsize;
+ const char *argv0;
+ const char *command;
+ const char **argv;
+ char *dbuf = NULL;
+ apr_file_t *script_out = NULL, *script_in = NULL, *script_err = NULL;
+- apr_bucket_brigade *bb;
++ conn_rec *c = r->connection;
++ apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc);
+ apr_bucket *b;
+ int is_included;
+- int seen_eos, child_stopped_reading;
+ apr_pool_t *p;
+ cgi_server_conf *conf;
+ apr_status_t rv;
+ cgi_exec_info_t e_info;
+- conn_rec *c;
++ cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module);
++ apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout;
+
+ if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) {
+ return DECLINED;
+ }
+
+- c = r->connection;
+-
+ is_included = !strcmp(r->protocol, "INCLUDED");
+
+ p = r->main ? r->main->pool : r->pool;
+@@ -832,83 +599,24 @@ static int cgi_handler(request_rec *r)
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+- /* Transfer any put/post args, CERN style...
+- * Note that we already ignore SIGPIPE in the core server.
+- */
+- bb = apr_brigade_create(r->pool, c->bucket_alloc);
+- seen_eos = 0;
+- child_stopped_reading = 0;
++ /* Buffer for logging script stdout. */
+ if (conf->logname) {
+- dbuf = apr_palloc(r->pool, conf->bufbytes + 1);
+- dbpos = 0;
++ dbufsize = conf->bufbytes;
++ dbuf = apr_palloc(r->pool, dbufsize + 1);
+ }
+- do {
+- apr_bucket *bucket;
+-
+- rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+- APR_BLOCK_READ, HUGE_STRING_LEN);
+-
+- if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01225)
+- "Error reading request entity data");
+- return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
+- }
+-
+- for (bucket = APR_BRIGADE_FIRST(bb);
+- bucket != APR_BRIGADE_SENTINEL(bb);
+- bucket = APR_BUCKET_NEXT(bucket))
+- {
+- const char *data;
+- apr_size_t len;
+-
+- if (APR_BUCKET_IS_EOS(bucket)) {
+- seen_eos = 1;
+- break;
+- }
+-
+- /* We can't do much with this. */
+- if (APR_BUCKET_IS_FLUSH(bucket)) {
+- continue;
+- }
+-
+- /* If the child stopped, we still must read to EOS. */
+- if (child_stopped_reading) {
+- continue;
+- }
+-
+- /* read */
+- apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
+-
+- if (conf->logname && dbpos < conf->bufbytes) {
+- int cursize;
+-
+- if ((dbpos + len) > conf->bufbytes) {
+- cursize = conf->bufbytes - dbpos;
+- }
+- else {
+- cursize = len;
+- }
+- memcpy(dbuf + dbpos, data, cursize);
+- dbpos += cursize;
+- }
+-
+- /* Keep writing data to the child until done or too much time
+- * elapses with no progress or an error occurs.
+- */
+- rv = apr_file_write_full(script_out, data, len, NULL);
+-
+- if (rv != APR_SUCCESS) {
+- /* silly script stopped reading, soak up remaining message */
+- child_stopped_reading = 1;
+- }
+- }
+- apr_brigade_cleanup(bb);
++ else {
++ dbufsize = 0;
++ dbuf = NULL;
+ }
+- while (!seen_eos);
+
+- if (conf->logname) {
+- dbuf[dbpos] = '\0';
++ /* Read the request body. */
++ rv = cgi_handle_request(r, script_out, bb, dbuf, dbufsize);
++ if (rv) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01225)
++ "Error reading request entity data");
++ return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
+ }
++
+ /* Is this flush really needed? */
+ apr_file_flush(script_out);
+ apr_file_close(script_out);
+@@ -916,10 +624,7 @@ static int cgi_handler(request_rec *r)
+ AP_DEBUG_ASSERT(script_in != NULL);
+
+ #if APR_FILES_AS_SOCKETS
+- apr_file_pipe_timeout_set(script_in, 0);
+- apr_file_pipe_timeout_set(script_err, 0);
+-
+- b = cgi_bucket_create(r, script_in, script_err, c->bucket_alloc);
++ b = cgi_bucket_create(r, dc->timeout, script_in, script_err, c->bucket_alloc);
+ if (b == NULL)
+ return HTTP_INTERNAL_SERVER_ERROR;
+ #else
+@@ -929,111 +634,7 @@ static int cgi_handler(request_rec *r)
+ b = apr_bucket_eos_create(c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, b);
+
+- /* Handle script return... */
+- if (!nph) {
+- const char *location;
+- char sbuf[MAX_STRING_LEN];
+- int ret;
+-
+- if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf,
+- APLOG_MODULE_INDEX)))
+- {
+- ret = log_script(r, conf, ret, dbuf, sbuf, bb, script_err);
+-
+- /*
+- * ret could be HTTP_NOT_MODIFIED in the case that the CGI script
+- * does not set an explicit status and ap_meets_conditions, which
+- * is called by ap_scan_script_header_err_brigade, detects that
+- * the conditions of the requests are met and the response is
+- * not modified.
+- * In this case set r->status and return OK in order to prevent
+- * running through the error processing stack as this would
+- * break with mod_cache, if the conditions had been set by
+- * mod_cache itself to validate a stale entity.
+- * BTW: We circumvent the error processing stack anyway if the
+- * CGI script set an explicit status code (whatever it is) and
+- * the only possible values for ret here are:
+- *
+- * HTTP_NOT_MODIFIED (set by ap_meets_conditions)
+- * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions)
+- * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the
+- * processing of the response of the CGI script, e.g broken headers
+- * or a crashed CGI process).
+- */
+- if (ret == HTTP_NOT_MODIFIED) {
+- r->status = ret;
+- return OK;
+- }
+-
+- return ret;
+- }
+-
+- location = apr_table_get(r->headers_out, "Location");
+-
+- if (location && r->status == 200) {
+- /* For a redirect whether internal or not, discard any
+- * remaining stdout from the script, and log any remaining
+- * stderr output, as normal. */
+- discard_script_output(bb);
+- apr_brigade_destroy(bb);
+- apr_file_pipe_timeout_set(script_err, r->server->timeout);
+- log_script_err(r, script_err);
+- }
+-
+- if (location && location[0] == '/' && r->status == 200) {
+- /* This redirect needs to be a GET no matter what the original
+- * method was.
+- */
+- r->method = "GET";
+- r->method_number = M_GET;
+-
+- /* We already read the message body (if any), so don't allow
+- * the redirected request to think it has one. We can ignore
+- * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR.
+- */
+- apr_table_unset(r->headers_in, "Content-Length");
+-
+- ap_internal_redirect_handler(location, r);
+- return OK;
+- }
+- else if (location && r->status == 200) {
+- /* XXX: Note that if a script wants to produce its own Redirect
+- * body, it now has to explicitly *say* "Status: 302"
+- */
+- return HTTP_MOVED_TEMPORARILY;
+- }
+-
+- rv = ap_pass_brigade(r->output_filters, bb);
+- }
+- else /* nph */ {
+- struct ap_filter_t *cur;
+-
+- /* get rid of all filters up through protocol... since we
+- * haven't parsed off the headers, there is no way they can
+- * work
+- */
+-
+- cur = r->proto_output_filters;
+- while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) {
+- cur = cur->next;
+- }
+- r->output_filters = r->proto_output_filters = cur;
+-
+- rv = ap_pass_brigade(r->output_filters, bb);
+- }
+-
+- /* don't soak up script output if errors occurred writing it
+- * out... otherwise, we prolong the life of the script when the
+- * connection drops or we stopped sending output for some other
+- * reason */
+- if (rv == APR_SUCCESS && !r->connection->aborted) {
+- apr_file_pipe_timeout_set(script_err, r->server->timeout);
+- log_script_err(r, script_err);
+- }
+-
+- apr_file_close(script_err);
+-
+- return OK; /* NOT r->status, even if it has changed. */
++ return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err);
+ }
+
+ /*============================================================================
+@@ -1147,107 +748,9 @@ static apr_status_t include_cmd(include_ctx_t *ctx, ap_filter_t *f,
+ return APR_SUCCESS;
+ }
+
+-static apr_status_t handle_exec(include_ctx_t *ctx, ap_filter_t *f,
+- apr_bucket_brigade *bb)
+-{
+- char *tag = NULL;
+- char *tag_val = NULL;
+- request_rec *r = f->r;
+- char *file = r->filename;
+- char parsed_string[MAX_STRING_LEN];
+-
+- if (!ctx->argc) {
+- ap_log_rerror(APLOG_MARK,
+- (ctx->flags & SSI_FLAG_PRINTING)
+- ? APLOG_ERR : APLOG_WARNING,
+- 0, r, APLOGNO(03195)
+- "missing argument for exec element in %s", r->filename);
+- }
+-
+- if (!(ctx->flags & SSI_FLAG_PRINTING)) {
+- return APR_SUCCESS;
+- }
+-
+- if (!ctx->argc) {
+- SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+- return APR_SUCCESS;
+- }
+-
+- if (ctx->flags & SSI_FLAG_NO_EXEC) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01228) "exec used but not allowed "
+- "in %s", r->filename);
+- SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+- return APR_SUCCESS;
+- }
+-
+- while (1) {
+- cgi_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED);
+- if (!tag || !tag_val) {
+- break;
+- }
+-
+- if (!strcmp(tag, "cmd")) {
+- apr_status_t rv;
+-
+- cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string),
+- SSI_EXPAND_LEAVE_NAME);
+-
+- rv = include_cmd(ctx, f, bb, parsed_string);
+- if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01229) "execution failure "
+- "for parameter \"%s\" to tag exec in file %s",
+- tag, r->filename);
+- SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+- break;
+- }
+- }
+- else if (!strcmp(tag, "cgi")) {
+- apr_status_t rv;
+-
+- cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string),
+- SSI_EXPAND_DROP_NAME);
+-
+- rv = include_cgi(ctx, f, bb, parsed_string);
+- if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01230) "invalid CGI ref "
+- "\"%s\" in %s", tag_val, file);
+- SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+- break;
+- }
+- }
+- else {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01231) "unknown parameter "
+- "\"%s\" to tag exec in %s", tag, file);
+- SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+- break;
+- }
+- }
+-
+- return APR_SUCCESS;
+-}
+-
+-
+-/*============================================================================
+- *============================================================================
+- * This is the end of the cgi filter code moved from mod_include.
+- *============================================================================
+- *============================================================================*/
+-
+-
+ static int cgi_post_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+ {
+- cgi_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler);
+- cgi_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value);
+- cgi_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string);
+-
+- if ((cgi_pfn_reg_with_ssi) && (cgi_pfn_gtv) && (cgi_pfn_ps)) {
+- /* Required by mod_include filter. This is how mod_cgi registers
+- * with mod_include to provide processing of the exec directive.
+- */
+- cgi_pfn_reg_with_ssi("exec", handle_exec);
+- }
+-
+ /* This is the means by which unusual (non-unix) os's may find alternate
+ * means to run a given command (e.g. shebang/registry parsing on Win32)
+ */
+@@ -1263,12 +766,13 @@ static void register_hooks(apr_pool_t *p)
+ static const char * const aszPre[] = { "mod_include.c", NULL };
+ ap_hook_handler(cgi_handler, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_post_config(cgi_post_config, aszPre, NULL, APR_HOOK_REALLY_FIRST);
++ ap_hook_optional_fn_retrieve(cgi_optfns_retrieve, NULL, NULL, APR_HOOK_MIDDLE);
+ }
+
+ AP_DECLARE_MODULE(cgi) =
+ {
+ STANDARD20_MODULE_STUFF,
+- NULL, /* dir config creater */
++ create_cgi_dirconf, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ create_cgi_config, /* server config */
+ merge_cgi_config, /* merge server config */
+diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c
+index 2258a683b7..dddfb25254 100644
+--- a/modules/generators/mod_cgid.c
++++ b/modules/generators/mod_cgid.c
+@@ -80,11 +80,6 @@ module AP_MODULE_DECLARE_DATA cgid_module;
+
+ static int cgid_start(apr_pool_t *p, server_rec *main_server, apr_proc_t *procnew);
+ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server);
+-static int handle_exec(include_ctx_t *ctx, ap_filter_t *f, apr_bucket_brigade *bb);
+-
+-static APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgid_pfn_reg_with_ssi;
+-static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgid_pfn_gtv;
+-static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgid_pfn_ps;
+
+ static apr_pool_t *pcgi = NULL;
+ static pid_t daemon_pid;
+@@ -220,6 +215,15 @@ typedef struct {
+ #endif
+ } cgid_req_t;
+
++#define cgi_server_conf cgid_server_conf
++#define cgi_module cgid_module
++
++#ifdef HAVE_CGID_FDPASSING
++/* Pull in CGI bucket implementation. */
++#define WANT_CGI_BUCKET
++#endif
++#include "cgi_common.h"
++
+ /* This routine is called to create the argument list to be passed
+ * to the CGI script. When suexec is enabled, the suexec path, user, and
+ * group are the first three arguments to be passed; if not, all three
+@@ -342,15 +346,19 @@ static apr_status_t close_unix_socket(void *thefd)
+ return close(fd);
+ }
+
+-/* deal with incomplete reads and signals
+- * assume you really have to read buf_size bytes
+- */
+-static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size)
++/* Read from the socket dealing with incomplete messages and signals.
++ * Returns 0 on success or errno on failure. Stderr fd passed as
++ * auxiliary data from other end is written to *errfd, or else stderr
++ * fileno if not present. */
++static apr_status_t sock_readhdr(int fd, int *errfd, void *vbuf, size_t buf_size)
+ {
+- char *buf = vbuf;
+ int rc;
++#ifndef HAVE_CGID_FDPASSING
++ char *buf = vbuf;
+ size_t bytes_read = 0;
+
++ if (errfd) *errfd = 0;
++
+ do {
+ do {
+ rc = read(fd, buf + bytes_read, buf_size - bytes_read);
+@@ -365,9 +373,60 @@ static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size)
+ }
+ } while (bytes_read < buf_size);
+
++
++#else /* with FD passing */
++ struct msghdr msg = {0};
++ struct iovec vec = {vbuf, buf_size};
++ struct cmsghdr *cmsg;
++ union { /* union to ensure alignment */
++ struct cmsghdr cm;
++ char buf[CMSG_SPACE(sizeof(int))];
++ } u;
++
++ msg.msg_iov = &vec;
++ msg.msg_iovlen = 1;
++
++ if (errfd) {
++ msg.msg_control = u.buf;
++ msg.msg_controllen = sizeof(u.buf);
++ *errfd = 0;
++ }
++
++ /* use MSG_WAITALL to skip loop on truncated reads */
++ do {
++ rc = recvmsg(fd, &msg, MSG_WAITALL);
++ } while (rc < 0 && errno == EINTR);
++
++ if (rc == 0) {
++ return ECONNRESET;
++ }
++ else if (rc < 0) {
++ return errno;
++ }
++ else if (rc != buf_size) {
++ /* MSG_WAITALL should ensure the recvmsg blocks until the
++ * entire length is read, but let's be paranoid. */
++ return APR_INCOMPLETE;
++ }
++
++ if (errfd
++ && (cmsg = CMSG_FIRSTHDR(&msg)) != NULL
++ && cmsg->cmsg_len == CMSG_LEN(sizeof(*errfd))
++ && cmsg->cmsg_level == SOL_SOCKET
++ && cmsg->cmsg_type == SCM_RIGHTS) {
++ *errfd = *((int *) CMSG_DATA(cmsg));
++ }
++#endif
++
+ return APR_SUCCESS;
+ }
+
++/* As sock_readhdr but without auxiliary fd passing. */
++static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size)
++{
++ return sock_readhdr(fd, NULL, vbuf, buf_size);
++}
++
+ /* deal with signals
+ */
+ static apr_status_t sock_write(int fd, const void *buf, size_t buf_size)
+@@ -384,7 +443,7 @@ static apr_status_t sock_write(int fd, const void *buf, size_t buf_size)
+ return APR_SUCCESS;
+ }
+
+-static apr_status_t sock_writev(int fd, request_rec *r, int count, ...)
++static apr_status_t sock_writev(int fd, int auxfd, request_rec *r, int count, ...)
+ {
+ va_list ap;
+ int rc;
+@@ -399,9 +458,39 @@ static apr_status_t sock_writev(int fd, request_rec *r, int count, ...)
+ }
+ va_end(ap);
+
++#ifndef HAVE_CGID_FDPASSING
+ do {
+ rc = writev(fd, vec, count);
+ } while (rc < 0 && errno == EINTR);
++#else
++ {
++ struct msghdr msg = { 0 };
++ struct cmsghdr *cmsg;
++ union { /* union for alignment */
++ char buf[CMSG_SPACE(sizeof(int))];
++ struct cmsghdr align;
++ } u;
++
++ msg.msg_iov = vec;
++ msg.msg_iovlen = count;
++
++ if (auxfd) {
++ msg.msg_control = u.buf;
++ msg.msg_controllen = sizeof(u.buf);
++
++ cmsg = CMSG_FIRSTHDR(&msg);
++ cmsg->cmsg_level = SOL_SOCKET;
++ cmsg->cmsg_type = SCM_RIGHTS;
++ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
++ *((int *) CMSG_DATA(cmsg)) = auxfd;
++ }
++
++ do {
++ rc = sendmsg(fd, &msg, 0);
++ } while (rc < 0 && errno == EINTR);
++ }
++#endif
++
+ if (rc < 0) {
+ return errno;
+ }
+@@ -410,7 +499,7 @@ static apr_status_t sock_writev(int fd, request_rec *r, int count, ...)
+ }
+
+ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env,
+- cgid_req_t *req)
++ int *errfd, cgid_req_t *req)
+ {
+ int i;
+ char **environ;
+@@ -421,7 +510,7 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env,
+ r->server = apr_pcalloc(r->pool, sizeof(server_rec));
+
+ /* read the request header */
+- stat = sock_read(fd, req, sizeof(*req));
++ stat = sock_readhdr(fd, errfd, req, sizeof(*req));
+ if (stat != APR_SUCCESS) {
+ return stat;
+ }
+@@ -431,6 +520,14 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env,
+ return APR_SUCCESS;
+ }
+
++ /* Sanity check the structure received. */
++ if (req->env_count < 0 || req->uri_len == 0
++ || req->filename_len > APR_PATH_MAX || req->filename_len == 0
++ || req->argv0_len > APR_PATH_MAX || req->argv0_len == 0
++ || req->loglevel > APLOG_TRACE8) {
++ return APR_EINVAL;
++ }
++
+ /* handle module indexes and such */
+ rconf = (void **)ap_create_request_config(r->pool);
+
+@@ -479,14 +576,15 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env,
+ return APR_SUCCESS;
+ }
+
+-static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env,
+- int req_type)
++static apr_status_t send_req(int fd, apr_file_t *errpipe, request_rec *r,
++ const char *argv0, char **env, int req_type)
+ {
+ int i;
+ cgid_req_t req = {0};
+ apr_status_t stat;
+ ap_unix_identity_t * ugid = ap_run_get_suexec_identity(r);
+ core_dir_config *core_conf = ap_get_core_module_config(r->per_dir_config);
++ int errfd;
+
+
+ if (ugid == NULL) {
+@@ -507,16 +605,21 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env,
+ req.args_len = r->args ? strlen(r->args) : 0;
+ req.loglevel = r->server->log.level;
+
++ if (errpipe)
++ apr_os_file_get(&errfd, errpipe);
++ else
++ errfd = 0;
++
+ /* Write the request header */
+ if (req.args_len) {
+- stat = sock_writev(fd, r, 5,
++ stat = sock_writev(fd, errfd, r, 5,
+ &req, sizeof(req),
+ r->filename, req.filename_len,
+ argv0, req.argv0_len,
+ r->uri, req.uri_len,
+ r->args, req.args_len);
+ } else {
+- stat = sock_writev(fd, r, 4,
++ stat = sock_writev(fd, errfd, r, 4,
+ &req, sizeof(req),
+ r->filename, req.filename_len,
+ argv0, req.argv0_len,
+@@ -531,7 +634,7 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env,
+ for (i = 0; i < req.env_count; i++) {
+ apr_size_t curlen = strlen(env[i]);
+
+- if ((stat = sock_writev(fd, r, 2, &curlen, sizeof(curlen),
++ if ((stat = sock_writev(fd, 0, r, 2, &curlen, sizeof(curlen),
+ env[i], curlen)) != APR_SUCCESS) {
+ return stat;
+ }
+@@ -582,20 +685,34 @@ static void daemon_signal_handler(int sig)
+ }
+ }
+
++/* Callback executed in the forked child process if exec of the CGI
++ * script fails. For the fd-passing case, output to stderr goes to
++ * the client (request handling thread) and is logged via
++ * ap_log_rerror there. For the non-fd-passing case, the "fake"
++ * request_rec passed via userdata is used to log. */
+ static void cgid_child_errfn(apr_pool_t *pool, apr_status_t err,
+ const char *description)
+ {
+- request_rec *r;
+ void *vr;
+
+ apr_pool_userdata_get(&vr, ERRFN_USERDATA_KEY, pool);
+- r = vr;
+-
+- /* sure we got r, but don't call ap_log_rerror() because we don't
+- * have r->headers_in and possibly other storage referenced by
+- * ap_log_rerror()
+- */
+- ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, APLOGNO(01241) "%s", description);
++ if (vr) {
++ request_rec *r = vr;
++
++ /* sure we got r, but don't call ap_log_rerror() because we don't
++ * have r->headers_in and possibly other storage referenced by
++ * ap_log_rerror()
++ */
++ ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, APLOGNO(01241) "%s", description);
++ }
++ else {
++ const char *logstr;
++
++ logstr = apr_psprintf(pool, APLOGNO(01241) "error spawning CGI child: %s (%pm)\n",
++ description, &err);
++ fputs(logstr, stderr);
++ fflush(stderr);
++ }
+ }
+
+ static int cgid_server(void *data)
+@@ -670,7 +787,7 @@ static int cgid_server(void *data)
+ }
+
+ while (!daemon_should_exit) {
+- int errfileno = STDERR_FILENO;
++ int errfileno;
+ char *argv0 = NULL;
+ char **env = NULL;
+ const char * const *argv;
+@@ -710,7 +827,7 @@ static int cgid_server(void *data)
+ r = apr_pcalloc(ptrans, sizeof(request_rec));
+ procnew = apr_pcalloc(ptrans, sizeof(*procnew));
+ r->pool = ptrans;
+- stat = get_req(sd2, r, &argv0, &env, &cgid_req);
++ stat = get_req(sd2, r, &argv0, &env, &errfileno, &cgid_req);
+ if (stat != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, stat,
+ main_server, APLOGNO(01248)
+@@ -742,6 +859,16 @@ static int cgid_server(void *data)
+ continue;
+ }
+
++ if (errfileno == 0) {
++ errfileno = STDERR_FILENO;
++ }
++ else {
++ ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, main_server,
++ "using passed fd %d as stderr", errfileno);
++ /* Limit the received fd lifetime to pool lifetime */
++ apr_pool_cleanup_register(ptrans, (void *)((long)errfileno),
++ close_unix_socket, close_unix_socket);
++ }
+ apr_os_file_put(&r->server->error_log, &errfileno, 0, r->pool);
+ apr_os_file_put(&inout, &sd2, 0, r->pool);
+
+@@ -801,7 +928,10 @@ static int cgid_server(void *data)
+ close(sd2);
+ }
+ else {
+- apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans);
++ if (errfileno == STDERR_FILENO) {
++ /* Used by cgid_child_errfn without fd-passing. */
++ apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans);
++ }
+
+ argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL, argv0, r->args);
+
+@@ -946,16 +1076,6 @@ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
+ if (ret != OK ) {
+ return ret;
+ }
+- cgid_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler);
+- cgid_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value);
+- cgid_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string);
+-
+- if ((cgid_pfn_reg_with_ssi) && (cgid_pfn_gtv) && (cgid_pfn_ps)) {
+- /* Required by mod_include filter. This is how mod_cgid registers
+- * with mod_include to provide processing of the exec directive.
+- */
+- cgid_pfn_reg_with_ssi("exec", handle_exec);
+- }
+ }
+ return ret;
+ }
+@@ -1066,41 +1186,6 @@ static const command_rec cgid_cmds[] =
+ {NULL}
+ };
+
+-static int log_scripterror(request_rec *r, cgid_server_conf * conf, int ret,
+- apr_status_t rv, char *error)
+-{
+- apr_file_t *f = NULL;
+- struct stat finfo;
+- char time_str[APR_CTIME_LEN];
+- int log_flags = rv ? APLOG_ERR : APLOG_ERR;
+-
+- /* Intentional no APLOGNO */
+- /* Callee provides APLOGNO in error text */
+- ap_log_rerror(APLOG_MARK, log_flags, rv, r,
+- "%s: %s", error, r->filename);
+-
+- /* XXX Very expensive mainline case! Open, then getfileinfo! */
+- if (!conf->logname ||
+- ((stat(conf->logname, &finfo) == 0)
+- && (finfo.st_size > conf->logbytes)) ||
+- (apr_file_open(&f, conf->logname,
+- APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, r->pool) != APR_SUCCESS)) {
+- return ret;
+- }
+-
+- /* "%% [Wed Jun 19 10:53:21 1996] GET /cgid-bin/printenv HTTP/1.0" */
+- apr_ctime(time_str, apr_time_now());
+- apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri,
+- r->args ? "?" : "", r->args ? r->args : "", r->protocol);
+- /* "%% 500 /usr/local/apache/cgid-bin */
+- apr_file_printf(f, "%%%% %d %s\n", ret, r->filename);
+-
+- apr_file_printf(f, "%%error\n%s\n", error);
+-
+- apr_file_close(f);
+- return ret;
+-}
+-
+ static int log_script(request_rec *r, cgid_server_conf * conf, int ret,
+ char *dbuf, const char *sbuf, apr_bucket_brigade *bb,
+ apr_file_t *script_err)
+@@ -1221,7 +1306,7 @@ static int connect_to_daemon(int *sdptr, request_rec *r,
+ ++connect_tries;
+ if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ return log_scripterror(r, conf, HTTP_INTERNAL_SERVER_ERROR, errno,
+- APLOGNO(01255) "unable to create socket to cgi daemon");
++ APLOGNO(01255), "unable to create socket to cgi daemon");
+ }
+ if (connect(sd, (struct sockaddr *)server_addr, server_addr_len) < 0) {
+ /* Save errno for later */
+@@ -1242,7 +1327,7 @@ static int connect_to_daemon(int *sdptr, request_rec *r,
+ }
+ else {
+ close(sd);
+- return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, APLOGNO(01257)
++ return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, APLOGNO(01257),
+ "unable to connect to cgi daemon after multiple tries");
+ }
+ }
+@@ -1258,13 +1343,15 @@ static int connect_to_daemon(int *sdptr, request_rec *r,
+ if (connect_errno == ENOENT &&
+ apr_time_sec(apr_time_now() - ap_scoreboard_image->global->restart_time) >
+ DEFAULT_CONNECT_STARTUP_DELAY) {
+- return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno,
+- apr_pstrcat(r->pool, APLOGNO(02833) "ScriptSock ", sockname, " does not exist", NULL));
++ return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno,
++ APLOGNO(02833),
++ apr_pstrcat(r->pool,
++ "ScriptSock ", sockname, " does not exist", NULL));
+ }
+
+ /* gotta try again, but make sure the cgid daemon is still around */
+ if (connect_errno != ENOENT && kill(daemon_pid, 0) != 0) {
+- return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, APLOGNO(01258)
++ return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, APLOGNO(01258),
+ "cgid daemon is gone; is Apache terminating?");
+ }
+ }
+@@ -1272,23 +1359,6 @@ static int connect_to_daemon(int *sdptr, request_rec *r,
+ return OK;
+ }
+
+-static void discard_script_output(apr_bucket_brigade *bb)
+-{
+- apr_bucket *e;
+- const char *buf;
+- apr_size_t len;
+-
+- for (e = APR_BRIGADE_FIRST(bb);
+- e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e);
+- e = APR_BRIGADE_FIRST(bb))
+- {
+- if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) {
+- break;
+- }
+- apr_bucket_delete(e);
+- }
+-}
+-
+ /****************************************************************
+ *
+ * Actual cgid handling...
+@@ -1374,7 +1444,9 @@ static apr_status_t get_cgi_pid(request_rec *r, cgid_server_conf *conf, pid_t *
+ return stat;
+ }
+
+- if (pid == 0) {
++ /* Don't accept zero as a pid here, calling kill(0, SIGTERM) etc
++ * later is unpleasant. */
++ if (*pid == 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01261)
+ "daemon couldn't find CGI process for connection %lu",
+ r->connection->id);
+@@ -1393,19 +1465,21 @@ static apr_status_t cleanup_script(void *vptr)
+
+ static int cgid_handler(request_rec *r)
+ {
+- int retval, nph, dbpos;
++ conn_rec *c = r->connection;
++ int retval, nph;
+ char *argv0, *dbuf;
+- apr_bucket_brigade *bb;
++ apr_size_t dbufsize;
++ apr_bucket_brigade *bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+ apr_bucket *b;
+ cgid_server_conf *conf;
+ int is_included;
+- int seen_eos, child_stopped_reading;
+ int sd;
+ char **env;
+- apr_file_t *tempsock;
++ apr_file_t *tempsock, *script_err, *errpipe_out;
+ struct cleanup_script_info *info;
+ apr_status_t rv;
+ cgid_dirconf *dc;
++ apr_interval_time_t timeout;
+
+ if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) {
+ return DECLINED;
+@@ -1414,7 +1488,7 @@ static int cgid_handler(request_rec *r)
+ conf = ap_get_module_config(r->server->module_config, &cgid_module);
+ dc = ap_get_module_config(r->per_dir_config, &cgid_module);
+
+-
++ timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout;
+ is_included = !strcmp(r->protocol, "INCLUDED");
+
+ if ((argv0 = strrchr(r->filename, '/')) != NULL) {
+@@ -1429,12 +1503,12 @@ static int cgid_handler(request_rec *r)
+ argv0 = r->filename;
+
+ if (!(ap_allow_options(r) & OPT_EXECCGI) && !is_scriptaliased(r)) {
+- return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01262)
++ return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01262),
+ "Options ExecCGI is off in this directory");
+ }
+
+ if (nph && is_included) {
+- return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01263)
++ return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01263),
+ "attempt to include NPH CGI script");
+ }
+
+@@ -1443,12 +1517,12 @@ static int cgid_handler(request_rec *r)
+ #error at mod_cgi.c for required code in this path.
+ #else
+ if (r->finfo.filetype == APR_NOFILE) {
+- return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01264)
++ return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01264),
+ "script not found or unable to stat");
+ }
+ #endif
+ if (r->finfo.filetype == APR_DIR) {
+- return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01265)
++ return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01265),
+ "attempt to invoke directory as script");
+ }
+
+@@ -1456,7 +1530,7 @@ static int cgid_handler(request_rec *r)
+ r->path_info && *r->path_info)
+ {
+ /* default to accept */
+- return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01266)
++ return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01266),
+ "AcceptPathInfo off disallows user's path");
+ }
+ /*
+@@ -1467,6 +1541,17 @@ static int cgid_handler(request_rec *r)
+ }
+ */
+
++#ifdef HAVE_CGID_FDPASSING
++ rv = apr_file_pipe_create(&script_err, &errpipe_out, r->pool);
++ if (rv) {
++ return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10176),
++ "could not create pipe for stderr");
++ }
++#else
++ script_err = NULL;
++ errpipe_out = NULL;
++#endif
++
+ /*
+ * httpd core function used to add common environment variables like
+ * DOCUMENT_ROOT.
+@@ -1479,24 +1564,28 @@ static int cgid_handler(request_rec *r)
+ return retval;
+ }
+
+- rv = send_req(sd, r, argv0, env, CGI_REQ);
++ rv = send_req(sd, errpipe_out, r, argv0, env, CGI_REQ);
+ if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01268)
+- "write to cgi daemon process");
++ return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10245),
++ "could not send request to cgi daemon");
+ }
+
++ /* The write-end of the pipe is only used by the server, so close
++ * it here. */
++ if (errpipe_out) apr_file_close(errpipe_out);
++
+ info = apr_palloc(r->pool, sizeof(struct cleanup_script_info));
+ info->conf = conf;
+ info->r = r;
+ rv = get_cgi_pid(r, conf, &(info->pid));
+
+- if (APR_SUCCESS == rv){
++ if (rv == APR_SUCCESS) {
+ apr_pool_cleanup_register(r->pool, info,
+- cleanup_script,
+- apr_pool_cleanup_null);
++ cleanup_script, apr_pool_cleanup_null);
+ }
+ else {
+- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "error determining cgi PID");
++ return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10246),
++ "failed reading PID from cgi daemon");
+ }
+
+ /* We are putting the socket discriptor into an apr_file_t so that we can
+@@ -1506,95 +1595,25 @@ static int cgid_handler(request_rec *r)
+ */
+
+ apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool);
+- if (dc->timeout > 0) {
+- apr_file_pipe_timeout_set(tempsock, dc->timeout);
+- }
+- else {
+- apr_file_pipe_timeout_set(tempsock, r->server->timeout);
+- }
++ apr_file_pipe_timeout_set(tempsock, timeout);
+ apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket);
+
+- /* Transfer any put/post args, CERN style...
+- * Note that we already ignore SIGPIPE in the core server.
+- */
+- bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+- seen_eos = 0;
+- child_stopped_reading = 0;
+- dbuf = NULL;
+- dbpos = 0;
++ /* Buffer for logging script stdout. */
+ if (conf->logname) {
+- dbuf = apr_palloc(r->pool, conf->bufbytes + 1);
++ dbufsize = conf->bufbytes;
++ dbuf = apr_palloc(r->pool, dbufsize + 1);
+ }
+- do {
+- apr_bucket *bucket;
+-
+- rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+- APR_BLOCK_READ, HUGE_STRING_LEN);
+-
+- if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01270)
+- "Error reading request entity data");
+- return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
+- }
+-
+- for (bucket = APR_BRIGADE_FIRST(bb);
+- bucket != APR_BRIGADE_SENTINEL(bb);
+- bucket = APR_BUCKET_NEXT(bucket))
+- {
+- const char *data;
+- apr_size_t len;
+-
+- if (APR_BUCKET_IS_EOS(bucket)) {
+- seen_eos = 1;
+- break;
+- }
+-
+- /* We can't do much with this. */
+- if (APR_BUCKET_IS_FLUSH(bucket)) {
+- continue;
+- }
+-
+- /* If the child stopped, we still must read to EOS. */
+- if (child_stopped_reading) {
+- continue;
+- }
+-
+- /* read */
+- apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
+-
+- if (conf->logname && dbpos < conf->bufbytes) {
+- int cursize;
+-
+- if ((dbpos + len) > conf->bufbytes) {
+- cursize = conf->bufbytes - dbpos;
+- }
+- else {
+- cursize = len;
+- }
+- memcpy(dbuf + dbpos, data, cursize);
+- dbpos += cursize;
+- }
+-
+- /* Keep writing data to the child until done or too much time
+- * elapses with no progress or an error occurs.
+- */
+- rv = apr_file_write_full(tempsock, data, len, NULL);
+-
+- if (rv != APR_SUCCESS) {
+- /* silly script stopped reading, soak up remaining message */
+- child_stopped_reading = 1;
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02651)
+- "Error writing request body to script %s",
+- r->filename);
+-
+- }
+- }
+- apr_brigade_cleanup(bb);
++ else {
++ dbuf = NULL;
++ dbufsize = 0;
+ }
+- while (!seen_eos);
+
+- if (conf->logname) {
+- dbuf[dbpos] = '\0';
++ /* Read the request body. */
++ rv = cgi_handle_request(r, tempsock, bb, dbuf, dbufsize);
++ if (rv) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01270)
++ "Error reading request entity data");
++ return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
+ }
+
+ /* we're done writing, or maybe we didn't write at all;
+@@ -1603,125 +1622,22 @@ static int cgid_handler(request_rec *r)
+ */
+ shutdown(sd, 1);
+
+- /* Handle script return... */
+- if (!nph) {
+- conn_rec *c = r->connection;
+- const char *location;
+- char sbuf[MAX_STRING_LEN];
+- int ret;
+-
+- bb = apr_brigade_create(r->pool, c->bucket_alloc);
+- b = apr_bucket_pipe_create(tempsock, c->bucket_alloc);
+- APR_BRIGADE_INSERT_TAIL(bb, b);
+- b = apr_bucket_eos_create(c->bucket_alloc);
+- APR_BRIGADE_INSERT_TAIL(bb, b);
+-
+- if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf,
+- APLOG_MODULE_INDEX)))
+- {
+- ret = log_script(r, conf, ret, dbuf, sbuf, bb, NULL);
+-
+- /*
+- * ret could be HTTP_NOT_MODIFIED in the case that the CGI script
+- * does not set an explicit status and ap_meets_conditions, which
+- * is called by ap_scan_script_header_err_brigade, detects that
+- * the conditions of the requests are met and the response is
+- * not modified.
+- * In this case set r->status and return OK in order to prevent
+- * running through the error processing stack as this would
+- * break with mod_cache, if the conditions had been set by
+- * mod_cache itself to validate a stale entity.
+- * BTW: We circumvent the error processing stack anyway if the
+- * CGI script set an explicit status code (whatever it is) and
+- * the only possible values for ret here are:
+- *
+- * HTTP_NOT_MODIFIED (set by ap_meets_conditions)
+- * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions)
+- * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the
+- * processing of the response of the CGI script, e.g broken headers
+- * or a crashed CGI process).
+- */
+- if (ret == HTTP_NOT_MODIFIED) {
+- r->status = ret;
+- return OK;
+- }
+-
+- return ret;
+- }
+-
+- location = apr_table_get(r->headers_out, "Location");
+-
+- if (location && location[0] == '/' && r->status == 200) {
+-
+- /* Soak up all the script output */
+- discard_script_output(bb);
+- apr_brigade_destroy(bb);
+- /* This redirect needs to be a GET no matter what the original
+- * method was.
+- */
+- r->method = "GET";
+- r->method_number = M_GET;
+-
+- /* We already read the message body (if any), so don't allow
+- * the redirected request to think it has one. We can ignore
+- * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR.
+- */
+- apr_table_unset(r->headers_in, "Content-Length");
+-
+- ap_internal_redirect_handler(location, r);
+- return OK;
+- }
+- else if (location && r->status == 200) {
+- /* XXX: Note that if a script wants to produce its own Redirect
+- * body, it now has to explicitly *say* "Status: 302"
+- */
+- discard_script_output(bb);
+- apr_brigade_destroy(bb);
+- return HTTP_MOVED_TEMPORARILY;
+- }
+-
+- rv = ap_pass_brigade(r->output_filters, bb);
+- if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r,
+- "Failed to flush CGI output to client");
+- }
+- }
+-
+- if (nph) {
+- conn_rec *c = r->connection;
+- struct ap_filter_t *cur;
+-
+- /* get rid of all filters up through protocol... since we
+- * haven't parsed off the headers, there is no way they can
+- * work
+- */
+-
+- cur = r->proto_output_filters;
+- while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) {
+- cur = cur->next;
+- }
+- r->output_filters = r->proto_output_filters = cur;
+-
+- bb = apr_brigade_create(r->pool, c->bucket_alloc);
+- b = apr_bucket_pipe_create(tempsock, c->bucket_alloc);
+- APR_BRIGADE_INSERT_TAIL(bb, b);
+- b = apr_bucket_eos_create(c->bucket_alloc);
+- APR_BRIGADE_INSERT_TAIL(bb, b);
+- ap_pass_brigade(r->output_filters, bb);
+- }
++ bb = apr_brigade_create(r->pool, c->bucket_alloc);
++#ifdef HAVE_CGID_FDPASSING
++ b = cgi_bucket_create(r, dc->timeout, tempsock, script_err, c->bucket_alloc);
++ if (b == NULL)
++ return HTTP_INTERNAL_SERVER_ERROR; /* should call log_scripterror() w/ _UNAVAILABLE? */
++#else
++ b = apr_bucket_pipe_create(tempsock, c->bucket_alloc);
++#endif
++ APR_BRIGADE_INSERT_TAIL(bb, b);
++ b = apr_bucket_eos_create(c->bucket_alloc);
++ APR_BRIGADE_INSERT_TAIL(bb, b);
+
+- return OK; /* NOT r->status, even if it has changed. */
++ return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err);
+ }
+
+-
+-
+-
+-/*============================================================================
+- *============================================================================
+- * This is the beginning of the cgi filter code moved from mod_include. This
+- * is the code required to handle the "exec" SSI directive.
+- *============================================================================
+- *============================================================================*/
++/* Handling include= for mod_include. */
+ static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f,
+ apr_bucket_brigade *bb, char *s)
+ {
+@@ -1806,7 +1722,7 @@ static void add_ssi_vars(request_rec *r)
+ }
+
+ static int include_cmd(include_ctx_t *ctx, ap_filter_t *f,
+- apr_bucket_brigade *bb, char *command)
++ apr_bucket_brigade *bb, const char *command)
+ {
+ char **env;
+ int sd;
+@@ -1827,7 +1743,7 @@ static int include_cmd(include_ctx_t *ctx, ap_filter_t *f,
+ return retval;
+ }
+
+- send_req(sd, r, command, env, SSI_REQ);
++ send_req(sd, NULL, r, command, env, SSI_REQ);
+
+ info = apr_palloc(r->pool, sizeof(struct cleanup_script_info));
+ info->conf = conf;
+@@ -1872,91 +1788,6 @@ static int include_cmd(include_ctx_t *ctx, ap_filter_t *f,
+ return APR_SUCCESS;
+ }
+
+-static apr_status_t handle_exec(include_ctx_t *ctx, ap_filter_t *f,
+- apr_bucket_brigade *bb)
+-{
+- char *tag = NULL;
+- char *tag_val = NULL;
+- request_rec *r = f->r;
+- char *file = r->filename;
+- char parsed_string[MAX_STRING_LEN];
+-
+- if (!ctx->argc) {
+- ap_log_rerror(APLOG_MARK,
+- (ctx->flags & SSI_FLAG_PRINTING)
+- ? APLOG_ERR : APLOG_WARNING,
+- 0, r, APLOGNO(03196)
+- "missing argument for exec element in %s", r->filename);
+- }
+-
+- if (!(ctx->flags & SSI_FLAG_PRINTING)) {
+- return APR_SUCCESS;
+- }
+-
+- if (!ctx->argc) {
+- SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+- return APR_SUCCESS;
+- }
+-
+- if (ctx->flags & SSI_FLAG_NO_EXEC) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01271) "exec used but not allowed "
+- "in %s", r->filename);
+- SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+- return APR_SUCCESS;
+- }
+-
+- while (1) {
+- cgid_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED);
+- if (!tag || !tag_val) {
+- break;
+- }
+-
+- if (!strcmp(tag, "cmd")) {
+- apr_status_t rv;
+-
+- cgid_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string),
+- SSI_EXPAND_LEAVE_NAME);
+-
+- rv = include_cmd(ctx, f, bb, parsed_string);
+- if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01272)
+- "execution failure for parameter \"%s\" "
+- "to tag exec in file %s", tag, r->filename);
+- SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+- break;
+- }
+- }
+- else if (!strcmp(tag, "cgi")) {
+- apr_status_t rv;
+-
+- cgid_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string),
+- SSI_EXPAND_DROP_NAME);
+-
+- rv = include_cgi(ctx, f, bb, parsed_string);
+- if (rv != APR_SUCCESS) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01273) "invalid CGI ref "
+- "\"%s\" in %s", tag_val, file);
+- SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+- break;
+- }
+- }
+- else {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01274) "unknown parameter "
+- "\"%s\" to tag exec in %s", tag, file);
+- SSI_CREATE_ERROR_BUCKET(ctx, f, bb);
+- break;
+- }
+- }
+-
+- return APR_SUCCESS;
+-}
+-/*============================================================================
+- *============================================================================
+- * This is the end of the cgi filter code moved from mod_include.
+- *============================================================================
+- *============================================================================*/
+-
+-
+ static void register_hook(apr_pool_t *p)
+ {
+ static const char * const aszPre[] = { "mod_include.c", NULL };
+@@ -1964,6 +1795,7 @@ static void register_hook(apr_pool_t *p)
+ ap_hook_pre_config(cgid_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_post_config(cgid_init, aszPre, NULL, APR_HOOK_MIDDLE);
+ ap_hook_handler(cgid_handler, NULL, NULL, APR_HOOK_MIDDLE);
++ ap_hook_optional_fn_retrieve(cgi_optfns_retrieve, NULL, NULL, APR_HOOK_MIDDLE);
+ }
+
+ AP_DECLARE_MODULE(cgid) = {
diff --git a/backport-httpd-2.4.53-detect-systemd.patch b/backport-httpd-2.4.53-detect-systemd.patch
new file mode 100644
index 0000000..d501b06
--- /dev/null
+++ b/backport-httpd-2.4.53-detect-systemd.patch
@@ -0,0 +1,45 @@
+diff --git a/Makefile.in b/Makefile.in
+index a2e9c82..bd8045c 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -4,7 +4,7 @@ CLEAN_SUBDIRS = test
+
+ PROGRAM_NAME = $(progname)
+ PROGRAM_SOURCES = modules.c
+-PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(PCRE_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
++PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
+ PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c
+ PROGRAM_DEPENDENCIES = \
+ server/libmain.la \
+diff --git a/acinclude.m4 b/acinclude.m4
+index 97484c9..05abe18 100644
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -631,6 +631,7 @@ case $host in
+ if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
+ AC_MSG_WARN([Your system does not support systemd.])
+ else
++ APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS])
+ AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported])
+ fi
+ fi
+diff --git a/configure.in b/configure.in
+index cf437fe..521fc45 100644
+--- a/configure.in
++++ b/configure.in
+@@ -239,6 +239,7 @@ if test "x$PCRE_CONFIG" != "x"; then
+ AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG])
+ APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`])
+ APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs8 2>/dev/null || $PCRE_CONFIG --libs`])
++ APR_ADDTO(HTTPD_LIBS, [\$(PCRE_LIBS)])
+ else
+ AC_MSG_ERROR([pcre(2)-config for libpcre not found. PCRE is required and available from http://pcre.org/])
+ fi
+@@ -734,6 +735,7 @@ APACHE_SUBST(OS_DIR)
+ APACHE_SUBST(BUILTIN_LIBS)
+ APACHE_SUBST(SHLIBPATH_VAR)
+ APACHE_SUBST(OS_SPECIFIC_VARS)
++APACHE_SUBST(HTTPD_LIBS)
+
+ PRE_SHARED_CMDS='echo ""'
+ POST_SHARED_CMDS='echo ""'
diff --git a/backport-httpd-2.4.53-export.patch b/backport-httpd-2.4.53-export.patch
new file mode 100644
index 0000000..d240360
--- /dev/null
+++ b/backport-httpd-2.4.53-export.patch
@@ -0,0 +1,56 @@
+diff --git a/Makefile.in b/Makefile.in
+index bd8045c..d6733a5 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -4,8 +4,15 @@ CLEAN_SUBDIRS = test
+
+ PROGRAM_NAME = $(progname)
+ PROGRAM_SOURCES = modules.c
+-PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
++PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) \
++ $(PROGRAM_LDDEPS) \
++ $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
+ PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c
++PROGRAM_LDDEPS = \
++ $(BUILTIN_LIBS) \
++ $(MPM_LIB) \
++ -Wl,--whole-archive,server/.libs/libmain.a,--no-whole-archive \
++ os/$(OS_DIR)/libos.la
+ PROGRAM_DEPENDENCIES = \
+ server/libmain.la \
+ $(BUILTIN_LIBS) \
+diff --git a/server/Makefile.in b/server/Makefile.in
+index 8111877..f00bb3f 100644
+--- a/server/Makefile.in
++++ b/server/Makefile.in
+@@ -12,7 +12,7 @@ LTLIBRARY_SOURCES = \
+ connection.c listen.c util_mutex.c \
+ mpm_common.c mpm_unix.c mpm_fdqueue.c \
+ util_charset.c util_cookies.c util_debug.c util_xml.c \
+- util_filter.c util_pcre.c util_regex.c exports.c \
++ util_filter.c util_pcre.c util_regex.c \
+ scoreboard.c error_bucket.c protocol.c core.c request.c ssl.c provider.c \
+ eoc_bucket.c eor_bucket.c core_filters.c \
+ util_expr_parse.c util_expr_scan.c util_expr_eval.c
+diff --git a/server/main.c b/server/main.c
+index 7da7aa2..e63d2eb 100644
+--- a/server/main.c
++++ b/server/main.c
+@@ -857,17 +857,3 @@ int main(int argc, const char * const argv[])
+ return !OK;
+ }
+
+-#ifdef AP_USING_AUTOCONF
+-/* This ugly little hack pulls any function referenced in exports.c into
+- * the web server. exports.c is generated during the build, and it
+- * has all of the APR functions specified by the apr/apr.exports and
+- * apr-util/aprutil.exports files.
+- */
+-const void *ap_suck_in_APR(void);
+-const void *ap_suck_in_APR(void)
+-{
+- extern const void *ap_ugly_hack;
+-
+- return ap_ugly_hack;
+-}
+-#endif
diff --git a/backport-httpd-2.4.54-icons.patch b/backport-httpd-2.4.54-icons.patch
new file mode 100644
index 0000000..efc0c4d
--- /dev/null
+++ b/backport-httpd-2.4.54-icons.patch
@@ -0,0 +1,49 @@
+diff --git a/docs/conf/extra/httpd-autoindex.conf.in b/docs/conf/extra/httpd-autoindex.conf.in
+index 51b02ed..93a2b87 100644
+--- a/docs/conf/extra/httpd-autoindex.conf.in
++++ b/docs/conf/extra/httpd-autoindex.conf.in
+@@ -21,7 +21,7 @@ IndexOptions FancyIndexing HTMLTable VersionSort
+ Alias /icons/ "@exp_iconsdir@/"
+
+ <Directory "@exp_iconsdir@">
+- Options Indexes MultiViews
++ Options Indexes MultiViews FollowSymlinks
+ AllowOverride None
+ Require all granted
+ </Directory>
+@@ -37,6 +37,7 @@ AddIconByType (TXT,/icons/text.gif) text/*
+ AddIconByType (IMG,/icons/image2.gif) image/*
+ AddIconByType (SND,/icons/sound2.gif) audio/*
+ AddIconByType (VID,/icons/movie.gif) video/*
++AddIconByType /icons/bomb.gif application/x-coredump
+
+ AddIcon /icons/binary.gif .bin .exe
+ AddIcon /icons/binhex.gif .hqx
+@@ -53,7 +54,6 @@ AddIcon /icons/dvi.gif .dvi
+ AddIcon /icons/uuencoded.gif .uu
+ AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
+ AddIcon /icons/tex.gif .tex
+-AddIcon /icons/bomb.gif core
+
+ AddIcon /icons/back.gif ..
+ AddIcon /icons/hand.right.gif README
+diff --git a/docs/conf/magic b/docs/conf/magic
+index bc891d9..9a41b44 100644
+--- a/docs/conf/magic
++++ b/docs/conf/magic
+@@ -383,3 +383,15 @@
+ 4 string moov video/quicktime
+ 4 string mdat video/quicktime
+
++
++#------------------------------------------------------------------------------
++# application/x-coredump for LE/BE ELF
++#
++0 string \177ELF
++>5 byte 1
++>16 leshort 4 application/x-coredump
++
++0 string \177ELF
++>5 byte 2
++>16 beshort 4 application/x-coredump
++
diff --git a/backport-httpd-2.4.9-apxs.patch b/backport-httpd-2.4.9-apxs.patch
new file mode 100644
index 0000000..f3e8b97
--- /dev/null
+++ b/backport-httpd-2.4.9-apxs.patch
@@ -0,0 +1,58 @@
+diff --git a/support/apxs.in b/support/apxs.in
+index ad1287f..efcfcf6 100644
+--- a/support/apxs.in
++++ b/support/apxs.in
+@@ -25,7 +25,18 @@ package apxs;
+
+ my %config_vars = ();
+
+-my $installbuilddir = "@exp_installbuilddir@";
++# Awful hack to make apxs libdir-agnostic:
++my $pkg_config = "/usr/bin/pkg-config";
++if (! -x "$pkg_config") {
++ error("$pkg_config not found!");
++ exit(1);
++}
++
++my $libdir = `pkg-config --variable=libdir apr-1`;
++chomp $libdir;
++
++my $installbuilddir = $libdir . "/httpd/build";
++
+ get_config_vars($destdir . "$installbuilddir/config_vars.mk",\%config_vars);
+
+ # read the configuration variables once
+@@ -275,7 +286,7 @@ if ($opt_g) {
+ $data =~ s|%NAME%|$name|sg;
+ $data =~ s|%TARGET%|$CFG_TARGET|sg;
+ $data =~ s|%PREFIX%|$prefix|sg;
+- $data =~ s|%INSTALLBUILDDIR%|$installbuilddir|sg;
++ $data =~ s|%LIBDIR%|$libdir|sg;
+
+ my ($mkf, $mods, $src) = ($data =~ m|^(.+)-=#=-\n(.+)-=#=-\n(.+)|s);
+
+@@ -453,11 +464,11 @@ if ($opt_c) {
+ my $ldflags = "$CFG_LDFLAGS";
+ if ($opt_p == 1) {
+
+- my $apr_libs=`$apr_config --cflags --ldflags --link-libtool --libs`;
++ my $apr_libs=`$apr_config --cflags --ldflags --link-libtool`;
+ chomp($apr_libs);
+ my $apu_libs="";
+ if ($apr_major_version < 2) {
+- $apu_libs=`$apu_config --ldflags --link-libtool --libs`;
++ $apu_libs=`$apu_config --ldflags --link-libtool`;
+ chomp($apu_libs);
+ }
+
+@@ -672,8 +683,8 @@ __DATA__
+
+ builddir=.
+ top_srcdir=%PREFIX%
+-top_builddir=%PREFIX%
+-include %INSTALLBUILDDIR%/special.mk
++top_builddir=%LIBDIR%/httpd
++include %LIBDIR%/httpd/build/special.mk
+
+ # the used tools
+ APACHECTL=apachectl
diff --git a/backport-layout_add_openEuler.patch b/backport-layout_add_openEuler.patch
new file mode 100644
index 0000000..54e0c97
--- /dev/null
+++ b/backport-layout_add_openEuler.patch
@@ -0,0 +1,34 @@
+diff -urN a/config.layout b/config.layout
+--- a/config.layout 2018-02-09 18:30:35.000000000 +0800
++++ b/config.layout 2019-09-21 09:36:47.000000000 +0800
+@@ -154,6 +154,30 @@
+ proxycachedir: ${localstatedir}/cache/httpd/proxy
+ </Layout>
+
++# Layout used in openEuler httpd packaging.
++<Layout openEuler>
++ prefix: /usr
++ exec_prefix: ${prefix}
++ bindir: ${prefix}/bin
++ sbindir: ${prefix}/sbin
++ libdir: ${prefix}/lib
++ libexecdir: ${prefix}/libexec
++ mandir: ${prefix}/man
++ sysconfdir: /etc/httpd/conf
++ datadir: ${prefix}/share/httpd
++ installbuilddir: ${libdir}/httpd/build
++ errordir: ${datadir}/error
++ iconsdir: ${datadir}/icons
++ htdocsdir: /var/www/html
++ manualdir: ${datadir}/manual
++ cgidir: /var/www/cgi-bin
++ includedir: ${prefix}/include/httpd
++ localstatedir: /var
++ runtimedir: /run/httpd
++ logfiledir: ${localstatedir}/log/httpd
++ proxycachedir: ${localstatedir}/cache/httpd/proxy
++</Layout>
++
+ # According to the /opt filesystem conventions
+ <Layout opt>
+ prefix: /opt/apache
diff --git a/htcacheclean.service b/htcacheclean.service
new file mode 100644
index 0000000..166067b
--- /dev/null
+++ b/htcacheclean.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Disk Cache Cleaning Daemon for Apache HTTP Server
+After=httpd.service
+
+[Service]
+Type=forking
+User=apache
+PIDFile=/run/httpd/htcacheclean/pid
+EnvironmentFile=/etc/sysconfig/htcacheclean
+ExecStart=/usr/sbin/htcacheclean -P /run/httpd/htcacheclean/pid -d $INTERVAL -p $CACHE_ROOT -l $LIMIT $OPTIONS
diff --git a/htcacheclean.sysconf b/htcacheclean.sysconf
new file mode 100644
index 0000000..fffa17b
--- /dev/null
+++ b/htcacheclean.sysconf
@@ -0,0 +1,16 @@
+#
+# Configuration options for systemd service, htcacheclean.service.
+# See htcacheclean(8) for more information on available options.
+#
+
+# Interval between cache clean runs, in minutes
+INTERVAL=15
+
+# Default cache root.
+CACHE_ROOT=/var/cache/httpd/proxy
+
+# Cache size limit in bytes (K=Kbytes, M=Mbytes)
+LIMIT=100M
+
+# Any other options...
+OPTIONS=
diff --git a/httpd-init.service b/httpd-init.service
new file mode 100644
index 0000000..3074778
--- /dev/null
+++ b/httpd-init.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=One-time temporary TLS key generation for httpd.service
+Documentation=man:httpd-init.service(8)
+
+ConditionPathExists=|!/etc/pki/tls/certs/localhost.crt
+ConditionPathExists=|!/etc/pki/tls/private/localhost.key
+
+[Service]
+Type=oneshot
+RemainAfterExit=no
+
+ExecStart=/usr/libexec/httpd-ssl-gencerts
diff --git a/httpd-ssl-gencerts b/httpd-ssl-gencerts
new file mode 100644
index 0000000..350f5b5
--- /dev/null
+++ b/httpd-ssl-gencerts
@@ -0,0 +1,39 @@
+#!/usr/bin/bash
+
+set -e
+
+FQDN=`hostname`
+ssldotconf=/etc/httpd/conf.d/ssl.conf
+
+if test -f /etc/pki/tls/certs/localhost.crt -a \
+ -f /etc/pki/tls/private/localhost.key; then
+ exit 0
+fi
+
+if test -f /etc/pki/tls/certs/localhost.crt -a \
+ ! -f /etc/pki/tls/private/localhost.key; then
+ echo "Missing certificate key!"
+ exit 1
+fi
+
+if test ! -f /etc/pki/tls/certs/localhost.crt -a \
+ -f /etc/pki/tls/private/localhost.key; then
+ echo "Missing certificate, but key is present!"
+ exit 1
+fi
+
+if ! test -f ${ssldotconf} || \
+ ! grep -q '^SSLCertificateFile /etc/pki/tls/certs/localhost.crt' ${ssldotconf} || \
+ ! grep -q '^SSLCertificateKeyFile /etc/pki/tls/private/localhost.key' ${ssldotconf}; then
+ # Non-default configuration, do nothing.
+ exit 0
+fi
+
+sscg -q \
+ --cert-file /etc/pki/tls/certs/localhost.crt \
+ --cert-key-file /etc/pki/tls/private/localhost.key \
+ --ca-file /etc/pki/tls/certs/localhost.crt \
+ --lifetime 365 \
+ --hostname $FQDN \
+ --email root@$FQDN
+
diff --git a/httpd-ssl-pass-dialog b/httpd-ssl-pass-dialog
new file mode 100644
index 0000000..79318a6
--- /dev/null
+++ b/httpd-ssl-pass-dialog
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec /bin/systemd-ask-password "Enter TLS private key passphrase for $1 ($2) : "
diff --git a/httpd.conf b/httpd.conf
new file mode 100644
index 0000000..7f14227
--- /dev/null
+++ b/httpd.conf
@@ -0,0 +1,355 @@
+#
+# This is the main Apache HTTP server configuration file. It contains the
+# configuration directives that give the server its instructions.
+# See <URL:http://httpd.apache.org/docs/2.4/> for detailed information.
+# In particular, see
+# <URL:http://httpd.apache.org/docs/2.4/mod/directives.html>
+# for a discussion of each configuration directive.
+#
+# Do NOT simply read the instructions in here without understanding
+# what they do. They're here only as hints or reminders. If you are unsure
+# consult the online docs. You have been warned.
+#
+# Configuration and logfile names: If the filenames you specify for many
+# of the server's control files begin with "/" (or "drive:/" for Win32), the
+# server will use that explicit path. If the filenames do *not* begin
+# with "/", the value of ServerRoot is prepended -- so 'log/access_log'
+# with ServerRoot set to '/www' will be interpreted by the
+# server as '/www/log/access_log', where as '/log/access_log' will be
+# interpreted as '/log/access_log'.
+
+#
+# ServerRoot: The top of the directory tree under which the server's
+# configuration, error, and log files are kept.
+#
+# Do not add a slash at the end of the directory path. If you point
+# ServerRoot at a non-local disk, be sure to specify a local disk on the
+# Mutex directive, if file-based mutexes are used. If you wish to share the
+# same ServerRoot for multiple httpd daemons, you will need to change at
+# least PidFile.
+#
+ServerRoot "/etc/httpd"
+
+#
+# Listen: Allows you to bind Apache to specific IP addresses and/or
+# ports, instead of the default. See also the <VirtualHost>
+# directive.
+#
+# Change this to Listen on a specific IP address, but note that if
+# httpd.service is enabled to run at boot time, the address may not be
+# available when the service starts. See the httpd.service(8) man
+# page for more information.
+#
+#Listen 12.34.56.78:80
+Listen 80
+
+#
+# Dynamic Shared Object (DSO) Support
+#
+# To be able to use the functionality of a module which was built as a DSO you
+# have to place corresponding `LoadModule' lines at this location so the
+# directives contained in it are actually available _before_ they are used.
+# Statically compiled modules (those listed by `httpd -l') do not need
+# to be loaded here.
+#
+# Example:
+# LoadModule foo_module modules/mod_foo.so
+#
+Include conf.modules.d/*.conf
+
+#
+# If you wish httpd to run as a different user or group, you must run
+# httpd as root initially and it will switch.
+#
+# User/Group: The name (or #number) of the user/group to run httpd as.
+# It is usually good practice to create a dedicated user and group for
+# running httpd, as with most system services.
+#
+User apache
+Group apache
+
+# 'Main' server configuration
+#
+# The directives in this section set up the values used by the 'main'
+# server, which responds to any requests that aren't handled by a
+# <VirtualHost> definition. These values also provide defaults for
+# any <VirtualHost> containers you may define later in the file.
+#
+# All of these directives may appear inside <VirtualHost> containers,
+# in which case these default settings will be overridden for the
+# virtual host being defined.
+#
+
+#
+# ServerAdmin: Your address, where problems with the server should be
+# e-mailed. This address appears on some server-generated pages, such
+# as error documents. e.g. admin@your-domain.com
+#
+ServerAdmin root@localhost
+
+#
+# ServerName gives the name and port that the server uses to identify itself.
+# This can often be determined automatically, but we recommend you specify
+# it explicitly to prevent problems during startup.
+#
+# If your host doesn't have a registered DNS name, enter its IP address here.
+#
+#ServerName www.example.com:80
+
+#
+# Deny access to the entirety of your server's filesystem. You must
+# explicitly permit access to web content directories in other
+# <Directory> blocks below.
+#
+<Directory />
+ AllowOverride none
+ Require all denied
+</Directory>
+
+#
+# Note that from this point forward you must specifically allow
+# particular features to be enabled - so if something's not working as
+# you might expect, make sure that you have specifically enabled it
+# below.
+#
+
+#
+# DocumentRoot: The directory out of which you will serve your
+# documents. By default, all requests are taken from this directory, but
+# symbolic links and aliases may be used to point to other locations.
+#
+DocumentRoot "/var/www/html"
+
+#
+# Relax access to content within /var/www.
+#
+<Directory "/var/www">
+ AllowOverride None
+ # Allow open access:
+ Require all granted
+</Directory>
+
+# Further relax access to the default document root:
+<Directory "/var/www/html">
+ #
+ # Possible values for the Options directive are "None", "All",
+ # or any combination of:
+ # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
+ #
+ # Note that "MultiViews" must be named *explicitly* --- "Options All"
+ # doesn't give it to you.
+ #
+ # The Options directive is both complicated and important. Please see
+ # http://httpd.apache.org/docs/2.4/mod/core.html#options
+ # for more information.
+ #
+ Options Indexes FollowSymLinks
+
+ #
+ # AllowOverride controls what directives may be placed in .htaccess files.
+ # It can be "All", "None", or any combination of the keywords:
+ # Options FileInfo AuthConfig Limit
+ #
+ AllowOverride None
+
+ #
+ # Controls who can get stuff from this server.
+ #
+ Require all granted
+</Directory>
+
+#
+# DirectoryIndex: sets the file that Apache will serve if a directory
+# is requested.
+#
+<IfModule dir_module>
+ DirectoryIndex index.html
+</IfModule>
+
+#
+# The following lines prevent .htaccess and .htpasswd files from being
+# viewed by Web clients.
+#
+<Files ".ht*">
+ Require all denied
+</Files>
+
+#
+# ErrorLog: The location of the error log file.
+# If you do not specify an ErrorLog directive within a <VirtualHost>
+# container, error messages relating to that virtual host will be
+# logged here. If you *do* define an error logfile for a <VirtualHost>
+# container, that host's errors will be logged there and not here.
+#
+ErrorLog "logs/error_log"
+
+#
+# LogLevel: Control the number of messages logged to the error_log.
+# Possible values include: debug, info, notice, warn, error, crit,
+# alert, emerg.
+#
+LogLevel warn
+
+<IfModule log_config_module>
+ #
+ # The following directives define some format nicknames for use with
+ # a CustomLog directive (see below).
+ #
+ LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+ LogFormat "%h %l %u %t \"%r\" %>s %b" common
+
+ <IfModule logio_module>
+ # You need to enable mod_logio.c to use %I and %O
+ LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
+ </IfModule>
+
+ #
+ # The location and format of the access logfile (Common Logfile Format).
+ # If you do not define any access logfiles within a <VirtualHost>
+ # container, they will be logged here. Contrariwise, if you *do*
+ # define per-<VirtualHost> access logfiles, transactions will be
+ # logged therein and *not* in this file.
+ #
+ #CustomLog "logs/access_log" common
+
+ #
+ # If you prefer a logfile with access, agent, and referer information
+ # (Combined Logfile Format) you can use the following directive.
+ #
+ CustomLog "logs/access_log" combined
+</IfModule>
+
+<IfModule alias_module>
+ #
+ # Redirect: Allows you to tell clients about documents that used to
+ # exist in your server's namespace, but do not anymore. The client
+ # will make a new request for the document at its new location.
+ # Example:
+ # Redirect permanent /foo http://www.example.com/bar
+
+ #
+ # Alias: Maps web paths into filesystem paths and is used to
+ # access content that does not live under the DocumentRoot.
+ # Example:
+ # Alias /webpath /full/filesystem/path
+ #
+ # If you include a trailing / on /webpath then the server will
+ # require it to be present in the URL. You will also likely
+ # need to provide a <Directory> section to allow access to
+ # the filesystem path.
+
+ #
+ # ScriptAlias: This controls which directories contain server scripts.
+ # ScriptAliases are essentially the same as Aliases, except that
+ # documents in the target directory are treated as applications and
+ # run by the server when requested rather than as documents sent to the
+ # client. The same rules about trailing "/" apply to ScriptAlias
+ # directives as to Alias.
+ #
+ ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
+
+</IfModule>
+
+#
+# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased
+# CGI directory exists, if you have that configured.
+#
+<Directory "/var/www/cgi-bin">
+ AllowOverride None
+ Options None
+ Require all granted
+</Directory>
+
+<IfModule mime_module>
+ #
+ # TypesConfig points to the file containing the list of mappings from
+ # filename extension to MIME-type.
+ #
+ TypesConfig /etc/mime.types
+
+ #
+ # AddType allows you to add to or override the MIME configuration
+ # file specified in TypesConfig for specific file types.
+ #
+ #AddType application/x-gzip .tgz
+ #
+ # AddEncoding allows you to have certain browsers uncompress
+ # information on the fly. Note: Not all browsers support this.
+ #
+ #AddEncoding x-compress .Z
+ #AddEncoding x-gzip .gz .tgz
+ #
+ # If the AddEncoding directives above are commented-out, then you
+ # probably should define those extensions to indicate media types:
+ #
+ AddType application/x-compress .Z
+ AddType application/x-gzip .gz .tgz
+
+ #
+ # AddHandler allows you to map certain file extensions to "handlers":
+ # actions unrelated to filetype. These can be either built into the server
+ # or added with the Action directive (see below)
+ #
+ # To use CGI scripts outside of ScriptAliased directories:
+ # (You will also need to add "ExecCGI" to the "Options" directive.)
+ #
+ #AddHandler cgi-script .cgi
+
+ # For type maps (negotiated resources):
+ #AddHandler type-map var
+
+ #
+ # Filters allow you to process content before it is sent to the client.
+ #
+ # To parse .shtml files for server-side includes (SSI):
+ # (You will also need to add "Includes" to the "Options" directive.)
+ #
+ AddType text/html .shtml
+ AddOutputFilter INCLUDES .shtml
+</IfModule>
+
+#
+# Specify a default charset for all content served; this enables
+# interpretation of all content as UTF-8 by default. To use the
+# default browser choice (ISO-8859-1), or to allow the META tags
+# in HTML content to override this choice, comment out this
+# directive:
+#
+AddDefaultCharset UTF-8
+
+<IfModule mime_magic_module>
+ #
+ # The mod_mime_magic module allows the server to use various hints from the
+ # contents of the file itself to determine its type. The MIMEMagicFile
+ # directive tells the module where the hint definitions are located.
+ #
+ MIMEMagicFile conf/magic
+</IfModule>
+
+#
+# Customizable error responses come in three flavors:
+# 1) plain text 2) local redirects 3) external redirects
+#
+# Some examples:
+#ErrorDocument 500 "The server made a boo boo."
+#ErrorDocument 404 /missing.html
+#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
+#ErrorDocument 402 http://www.example.com/subscription_info.html
+#
+
+#
+# EnableMMAP and EnableSendfile: On systems that support it,
+# memory-mapping or the sendfile syscall may be used to deliver
+# files. This usually improves server performance, but must
+# be turned off when serving from networked-mounted
+# filesystems or if support for these functions is otherwise
+# broken on your system.
+# Defaults if commented: EnableMMAP On, EnableSendfile Off
+#
+#EnableMMAP off
+EnableSendfile on
+
+# Supplemental configuration
+#
+# Load config files in the "/etc/httpd/conf.d" directory, if any.
+IncludeOptional conf.d/*.conf
diff --git a/httpd.logrotate b/httpd.logrotate
new file mode 100644
index 0000000..28c9730
--- /dev/null
+++ b/httpd.logrotate
@@ -0,0 +1,9 @@
+/var/log/httpd/*log {
+ missingok
+ notifempty
+ sharedscripts
+ delaycompress
+ postrotate
+ /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
+ endscript
+}
diff --git a/httpd.service b/httpd.service
new file mode 100644
index 0000000..6ff4e8b
--- /dev/null
+++ b/httpd.service
@@ -0,0 +1,32 @@
+# See httpd.service(8) for more information on using the httpd service.
+
+# Modifying this file in-place is not recommended, because changes
+# will be overwritten during package upgrades. To customize the
+# behaviour, run "systemctl edit httpd" to create an override unit.
+
+# For example, to pass additional options (such as -D definitions) to
+# the httpd binary at startup, create an override unit (as is done by
+# systemctl edit) and enter the following:
+
+# [Service]
+# Environment=OPTIONS=-DMY_DEFINE
+
+[Unit]
+Description=The Apache HTTP Server
+Wants=httpd-init.service
+After=network.target remote-fs.target nss-lookup.target httpd-init.service
+Documentation=man:httpd.service(8)
+
+[Service]
+Type=notify
+Environment=LANG=C
+
+ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
+ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
+# Send SIGWINCH for graceful stop
+KillSignal=SIGWINCH
+KillMode=mixed
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
diff --git a/httpd.service.xml b/httpd.service.xml
new file mode 100644
index 0000000..4a6038d
--- /dev/null
+++ b/httpd.service.xml
@@ -0,0 +1,338 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+
+]>
+<!--
+ Copyright 2018 Red Hat, Inc.
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<refentry>
+ <refentryinfo>
+ <title>httpd systemd units</title>
+ <productname>httpd</productname>
+ <author><contrib>Author</contrib><surname>Orton</surname><firstname>Joe</firstname><email>jorton@redhat.com</email></author>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>httpd.service</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>httpd.service</refname>
+ <refname>httpd@.service</refname>
+ <refname>httpd.socket</refname>
+ <refname>httpd-init.service</refname>
+ <refpurpose>httpd unit files for systemd</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para>
+ <filename>/usr/lib/systemd/system/httpd.service</filename>,
+ <filename>/usr/lib/systemd/system/httpd@.service</filename>,
+ <filename>/usr/lib/systemd/system/httpd-init.service</filename>,
+ <filename>/usr/lib/systemd/system/httpd.socket</filename>
+ </para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This manual page describes the <command>systemd</command>
+ unit files used to integrate the <command>httpd</command> daemon
+ with <command>systemd</command>. Two main unit files are
+ available: <command>httpd.service</command> allows the
+ <command>httpd</command> daemon to be run as a system service, and
+ <command>httpd.socket</command> allows httpd to be started via
+ socket-based activation. Most systems will use
+ <command>httpd.service</command>.</para>
+
+ <para>The <command>apachectl</command> command has been modified
+ to invoke <command>systemctl</command> for most uses, so for
+ example, running <command>apachectl start</command> is equivalent
+ to running <command>systemctl start httpd.service</command>. This
+ ensures that the running httpd daemon is tracked and managed by
+ <command>systemd</command>. In contrast, running
+ <command>httpd</command> directly from a root shell will start the
+ service outside of <command>systemd</command>; in this case,
+ default security restrictions described below (including, but not
+ limited to, SELinux) will not be enforced.</para>
+
+ <refsect2>
+ <title>Changing default behaviour</title>
+
+ <para>To change the default behaviour of the httpd service, an
+ <emphasis>over-ride</emphasis> file should be created, rather
+ than changing
+ <filename>/usr/lib/systemd/system/httpd.service</filename>
+ directly, since such changes would be lost over package
+ upgrades. Running <command>systemctl edit
+ httpd.service</command> or <command>systemctl edit
+ httpd.socket</command> as root will create a drop-in file (in
+ the former case, in
+ <filename>/etc/systemd/system/httpd.service.d</filename>) which
+ over-rides the system defaults.</para>
+
+ <para>For example, to set the <option>LD_LIBRARY_PATH</option>
+ environment variable for the daemon, run <command>systemctl edit
+ httpd.service</command> and enter:
+
+ <programlisting>[Service]
+Environment=LD_LIBRARY_PATH=/opt/vendor/lib</programlisting></para>
+ </refsect2>
+
+ <refsect2>
+ <title>Starting the service at boot time</title>
+
+ <para>The httpd.service and httpd.socket units are
+ <emphasis>disabled</emphasis> by default. To start the httpd
+ service at boot time, run: <command>systemctl enable
+ httpd.service</command>. In the default configuration, the
+ httpd daemon will accept connections on port 80 (and, if mod_ssl
+ is installed, TLS connections on port 443) for any configured
+ IPv4 or IPv6 address.</para>
+
+ <para>If httpd is configured to depend on any specific IP
+ address (for example, with a "Listen" directive) which may only
+ become available during start-up, or if httpd depends on other
+ services (such as a database daemon), the service
+ <emphasis>must</emphasis> be configured to ensure correct
+ start-up ordering.</para>
+
+ <para>For example, to ensure httpd is only running after all
+ configured network interfaces are configured, create a drop-in
+ file (as described above) with the following section:
+
+ <programlisting>[Unit]
+After=network-online.target
+Wants=network-online.target</programlisting>
+
+ See <ulink
+ url="https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/"/>
+ for more information on start-up ordering with systemd.</para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>SSL/TLS certificate generation</title>
+
+ <para>The <command>httpd-init.service</command> unit is provided
+ with the mod_ssl package. This oneshot unit automatically
+ creates a TLS server certificate and key (using a generated
+ self-signed CA certificate and key) for testing purposes before
+ httpd is started. To inhibit certificate generation, use
+ <command>systemctl mask httpd-init.service</command> after
+ installing mod_ssl, and adjust the mod_ssl configuration to use
+ an appropriate certificate and key.</para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Reloading and stopping the service</title>
+
+ <para>When running <command>systemctl reload
+ httpd.service</command>, a <emphasis>graceful</emphasis>
+ restart is used, which sends a signal to the httpd parent
+ process to reload the configuration and re-open log files. Any
+ children with open connections at the time of reload will
+ terminate only once they have completed serving requests. This
+ prevents users of the server seeing errors (or potentially
+ losing data) due to the reload, but means some there is some
+ delay before any configuration changes take effect for all
+ users.</para>
+
+ <para>Similarly, a <emphasis>graceful stop</emphasis> is used
+ when <command>systemctl stop httpd.service</command> is run,
+ which terminates the server only once active connections have
+ been processed.</para>
+
+ <para>To "ungracefully" stop the server without waiting for
+ requests to complete, use <command>systemctl kill
+ --kill-who=main httpd</command>; similarly to "ungracefully"
+ reload the configuration, use <command>systemctl kill
+ --kill-who=main --signal=HUP httpd</command>.</para>
+ </refsect2>
+
+ <refsect2>
+ <title>Automated service restarts</title>
+
+ <para>System packages (including the httpd package itself) may
+ restart the httpd service automatically after packages are
+ upgraded, installed, or removed. This is done using the
+ <command>systemctl reload httpd.service</command>, which
+ produces a <emphasis>graceful</emphasis> restart by default as
+ described above.</para>
+
+ <para>To suppress automatic reloads entirely, create the file
+ <filename>/etc/sysconfig/httpd-disable-posttrans</filename>.</para>
+ </refsect2>
+
+ <refsect2>
+ <title>Changing the default MPM (Multi-Processing Module)</title>
+
+ <para>httpd offers a choice of multi-processing modules (MPMs),
+ which can be configured in
+ <filename>/etc/httpd/conf.modules.d/00-mpm.conf</filename>. The
+ default is to use the <emphasis>@MPM@</emphasis> MPM.</para>
+
+ <para>If using the <emphasis>prefork</emphasis> MPM, the
+ "httpd_graceful_shutdown" SELinux boolean should also be
+ enabled, since with this MPM, httpd needs to establish TCP
+ connections to local ports to successfully complete a graceful
+ restart or shutdown. This boolean can be enabled by running the
+ command: <command>semanage boolean -m --on
+ httpd_graceful_shutdown</command></para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>systemd integration and mod_systemd</title>
+
+ <para>The httpd service uses the <option>notify</option> systemd
+ service type. The <literal>mod_systemd</literal> module must be
+ loaded (as in the default configuration) for this to work
+ correctly - the service will fail if this module is not
+ loaded. <literal>mod_systemd</literal> also makes worker and
+ request statistics available when running <command>systemctl status
+ httpd</command>. See
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for more information on systemd service types.</para>
+ </refsect2>
+
+ <refsect2>
+ <title>Security and SELinux</title>
+
+ <para>The default SELinux policy restricts the httpd service in
+ various ways. For example, the default policy limits the ports
+ to which httpd can bind (using the <literal>Listen</literal>
+ directive), which parts of the filesystem can be accessed, and
+ whether outgoing TCP connections are possible. Many of these
+ restrictions can be relaxed or adjusted by using
+ <command>semanage</command> to change booleans or other
+ types. See
+ <citerefentry><refentrytitle>httpd_selinux</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ for more information.</para>
+
+ <para>The httpd service enables <emphasis>PrivateTmp</emphasis>
+ by default. The <filename>/tmp</filename> and
+ <filename>/var/tmp</filename> directories available within the
+ httpd process (and CGI scripts, etc) are not shared by other
+ processes. See
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for more information.</para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Socket activation</title>
+
+ <para>Socket activation (see
+ <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for more information) can be used with <command>httpd</command>
+ by enabling the <command>httpd.socket</command> unit. The
+ <command>httpd</command> listener configuration must exactly
+ match the <literal>ListenStream</literal> options configured for
+ the <command>httpd.socket</command> unit. The default
+ <command>httpd.socket</command> has a
+ <literal>ListenStream=80</literal> and, if mod_ssl is installed,
+ <literal>ListenStream=443</literal> by a drop-in file. If
+ additional <literal>Listen</literal> directives are added to the
+ httpd configuration, corresponding
+ <literal>ListenStream</literal> options should be added via
+ drop-in files, for example via <command>systemctl edit
+ httpd.socket</command>.</para>
+
+ <para>If using socket activation with httpd, only one listener
+ on any given TCP port is supported; a configuration with both
+ "<literal>Listen 127.0.0.1:80</literal>" and "<literal>Listen
+ 192.168.1.2:80</literal>" will not work.</para>
+ </refsect2>
+
+ <refsect2>
+ <title>Instantiated services</title>
+
+ <para>The <command>httpd@.service</command> unit is an
+ instantiated template service. An instance of this unit will be
+ started using the configuration file
+ <filename>/etc/httpd/conf/INSTANCE.conf</filename>, where
+ <emphasis>INSTANCE</emphasis> is replaced with the instance
+ name. For example, <command>systemctl start
+ httpd@foobar.service</command> will start httpd using the
+ configuration file
+ <filename>/etc/httpd/conf/foobar.conf</filename>. The
+ <option>HTTPD_INSTANCE</option> environment variable is set to
+ the instance name by the unit and is available for use within
+ the configuration file.</para>
+
+ <para>To allow multiple instances of httpd to run
+ simultaneously, a number of configuration directives must be
+ changed, such as <command>PidFile</command> and
+ <command>DefaultRuntimeDir</command> to pick non-conflicting
+ paths, and <command>Listen</command> to choose different ports.
+ The example configuration file
+ <filename>/usr/share/doc/httpd/instance.conf</filename>
+ demonstrates how to make such changes using
+ <option>HTTPD_INSTANCE</option> variable.</para>
+
+ <para>It can be useful to configure instances of
+ <command>httpd@.service</command> to reload when
+ <command>httpd.service</command> is reloaded; for example,
+ <command>logrotate</command> will reload only
+ <command>httpd.service</command> when logs are rotated. If this
+ behaviour is required, create a drop-in file for the instance as
+ follows:
+
+ <programlisting>[Unit]
+ReloadPropagatedFrom=httpd.service</programlisting>
+
+ As with normal units, drop-in files for instances can be created
+ using <command>systemctl edit</command>, e.g. <command>systemctl edit
+ httpd@foobar.service</command>.</para>
+ </refsect2>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Files</title>
+
+ <para><filename>/usr/lib/systemd/system/httpd.service</filename>,
+ <filename>/usr/lib/systemd/system/httpd.socket</filename>,
+ <filename>/usr/lib/systemd/system/httpd@.service</filename>,
+ <filename>/etc/systemd/systemd/httpd.service.d</filename></para>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para>
+ <citerefentry><refentrytitle>httpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>httpd_selinux</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>semanage</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
+
+<!-- LocalWords: systemd PidFile
+-->
diff --git a/httpd.socket b/httpd.socket
new file mode 100644
index 0000000..074695e
--- /dev/null
+++ b/httpd.socket
@@ -0,0 +1,13 @@
+# See httpd.socket(8) for more information on using the httpd service.
+
+[Unit]
+Description=Apache httpd Server Socket
+Documentation=man:httpd.socket(8)
+
+[Socket]
+ListenStream=80
+NoDelay=true
+DeferAcceptSec=30
+
+[Install]
+WantedBy=sockets.target
diff --git a/httpd.spec b/httpd.spec
new file mode 100644
index 0000000..d107682
--- /dev/null
+++ b/httpd.spec
@@ -0,0 +1,733 @@
+%define contentdir %{_datadir}/httpd
+%define docroot /var/www
+%define suexec_caller apache
+%define mmn 20120211
+%define mmnisa %{mmn}%{__isa_name}%{__isa_bits}
+%global mpm event
+
+Name: httpd
+Summary: Apache HTTP Server
+Version: 2.4.58
+Release: 1
+License: ASL 2.0
+URL: https://httpd.apache.org/
+Source0: https://archive.apache.org/dist/httpd/httpd-%{version}.tar.bz2
+Source1: index.html
+Source2: httpd.logrotate
+Source3: instance.conf
+Source4: httpd-ssl-pass-dialog
+Source5: httpd.tmpfiles
+Source6: httpd.service
+Source7: action-graceful.sh
+Source8: action-configtest.sh
+Source9: server-status.conf
+Source10: httpd.conf
+Source11: 00-base.conf
+Source12: 00-mpm.conf
+Source13: 00-lua.conf
+Source14: 01-cgi.conf
+Source15: 00-dav.conf
+Source16: 00-proxy.conf
+Source17: 00-ssl.conf
+Source18: 01-ldap.conf
+Source19: 00-proxyhtml.conf
+Source20: userdir.conf
+Source21: ssl.conf
+Source22: welcome.conf
+Source23: manual.conf
+Source24: 00-systemd.conf
+Source25: 01-session.conf
+Source26: 10-listen443.conf
+Source27: httpd.socket
+Source28: 00-optional.conf
+Source29: 01-md.conf
+Source30: README.confd
+Source31: README.confmod
+Source32: httpd.service.xml
+Source40: htcacheclean.service
+Source41: htcacheclean.sysconf
+Source42: httpd-init.service
+Source43: httpd-ssl-gencerts
+Source44: httpd@.service
+
+Patch0: backport-httpd-2.4.1-apctl.patch
+Patch1: backport-httpd-2.4.9-apxs.patch
+Patch2: backport-httpd-2.4.1-deplibs.patch
+Patch3: backport-httpd-2.4.3-apctl-systemd.patch
+Patch4: backport-httpd-2.4.53-detect-systemd.patch
+Patch5: backport-httpd-2.4.53-export.patch
+Patch6: backport-httpd-2.4.43-corelimit.patch
+Patch7: backport-httpd-2.4.25-selinux.patch
+Patch8: backport-httpd-2.4.54-icons.patch
+Patch9: backport-httpd-2.4.43-cachehardmax.patch
+Patch10: backport-httpd-2.4.43-socket-activation.patch
+Patch11: backport-httpd-2.4.43-sslciphdefault.patch
+Patch12: backport-httpd-2.4.43-sslprotdefault.patch
+Patch13: backport-httpd-2.4.43-enable-sslv3.patch
+Patch14: backport-layout_add_openEuler.patch
+Patch15: backport-httpd-2.4.43-gettid.patch
+Patch16: backport-httpd-2.4.43-r1861793+.patch
+Patch17: backport-httpd-2.4.48-r1828172+.patch
+Patch18: backport-httpd-2.4.46-htcacheclean-dont-break.patch
+
+BuildRequires: gcc autoconf pkgconfig findutils xmlto perl-interpreter perl-generators systemd-devel
+BuildRequires: zlib-devel libselinux-devel lua-devel brotli-devel
+BuildRequires: apr-devel >= 1.5.0 apr-util-devel >= 1.5.0 pcre2-devel
+Requires: mailcap system-logos-httpd mod_http2
+Requires: httpd-tools = %{version}-%{release} httpd-filesystem = %{version}-%{release}
+Requires(pre): httpd-filesystem
+Requires(preun): systemd-units
+Requires(postun): systemd-units
+Requires(post): systemd-units
+Provides: mod_proxy_uwsgi = %{version}-%{release}
+Provides: webserver httpd-mmn = %{mmn} httpd-mmn = %{mmnisa}
+Provides: mod_dav = %{version}-%{release} httpd-suexec = %{version}-%{release}
+Obsoletes: mod_proxy_uwsgi < 2.0.17.1-2 httpd-suexec
+Conflicts: apr < 1.5.0-1
+
+%description
+Apache HTTP Server is a powerful and flexible HTTP/1.1 compliant web server.
+
+%package devel
+Summary: Development files for %{name}
+Requires: apr-devel apr-util-devel pkgconfig httpd = %{version}-%{release}
+
+%description devel
+This package provides APXS binary and other files used to compile
+and develop additional modules for Apache.
+
+%package help
+Summary: Documents and man pages for HTTP Server
+Requires: httpd = %{version}-%{release}
+BuildArch: noarch
+
+%description help
+This packages provides manual and reference guide for HTTP Server.
+
+%package filesystem
+Summary: The basic directory for HTTP Server
+BuildArch: noarch
+Requires(pre): shadow-utils
+
+%description filesystem
+This package contains the basic directory layout for HTTP Server.
+
+%package tools
+Summary: Related tools for use HTTP Server
+
+%description tools
+This package contains tools used for HTTP Server.
+
+%package -n mod_ssl
+Summary: SSL and TLS modules for HTTP Server
+Epoch: 1
+BuildRequires: openssl-devel
+Requires(pre): httpd-filesystem
+Requires: httpd = 0:%{version}-%{release} httpd-mmn = %{mmnisa} sscg >= 2.2.0
+Conflicts: openssl-libs < 1:1.0.1h-4
+
+%description -n mod_ssl
+This module provides strong cryptography via SSL and TLS for HTTP Server.
+
+%package -n mod_md
+Summary: Certificate provisioning using ACME for HTTP Server
+Requires: httpd = 0:%{version}-%{release} httpd-mmn = %{mmnisa}
+BuildRequires: jansson-devel libcurl-devel
+
+%description -n mod_md
+This module manages common properties for one or more virtual hosts.
+It uses the ACME protocol to automate certificate provisioning.
+
+%package -n mod_proxy_html
+Summary: HTML content filters for the HTTP Server
+Requires: httpd = 0:%{version}-%{release} httpd-mmn = %{mmnisa}
+BuildRequires: libxml2-devel
+Epoch: 1
+Obsoletes: mod_proxy_html < 1:2.4.1-2
+
+%description -n mod_proxy_html
+This module provides filters which can modify HTML link.
+
+%package -n mod_ldap
+Summary: LDAP authentication module for Apache HTTP Server
+Requires: httpd = 0:%{version}-%{release} httpd-mmn = %{mmnisa}
+Requires: apr-util-ldap
+
+%description -n mod_ldap
+This module adds support for LDAP authentication to Apache HTTP Server.
+
+%package -n mod_session
+Summary: Session support for Apache HTTP Server
+Requires: httpd = 0:%{version}-%{release} httpd-mmn = %{mmnisa}
+
+%description -n mod_session
+Ths module provides session support for per-user.
+
+%prep
+%autosetup -p1
+
+sed -i '/suexec/s,setcap ,echo Skipping setcap for ,' Makefile.in
+
+# Example conf for instances
+cp $RPM_SOURCE_DIR/instance.conf .
+sed < $RPM_SOURCE_DIR/httpd.conf >> instance.conf '
+0,/^ServerRoot/d;
+/# Supplemental configuration/,$d
+/^ *CustomLog .logs/s,logs/,logs/${HTTPD_INSTANCE}_,
+/^ *ErrorLog .logs/s,logs/,logs/${HTTPD_INSTANCE}_,
+'
+touch -r $RPM_SOURCE_DIR/instance.conf instance.conf
+cp -p $RPM_SOURCE_DIR/server-status.conf server-status.conf
+
+sed 's/@MPM@/%{mpm}/' < $RPM_SOURCE_DIR/httpd.service.xml \
+ > httpd.service.xml
+
+xmlto man ./httpd.service.xml
+
+%build
+%ifarch loongarch64
+%_update_config_guess
+%_update_config_sub
+%endif
+rm -rf srclib/{apr,apr-util,pcre}
+
+autoheader && autoconf || exit 1
+
+%{__perl} -pi -e "s:\@exp_installbuilddir\@:%{_libdir}/httpd/build:g" support/apxs.in
+
+export CFLAGS=$RPM_OPT_FLAGS
+export LDFLAGS="-Wl,-z,relro,-z,now"
+export LYNX_PATH=/usr/bin/links
+
+./configure \
+ --prefix=%{_sysconfdir}/httpd --exec-prefix=%{_prefix} --bindir=%{_bindir} \
+ --sbindir=%{_sbindir} --mandir=%{_mandir} --libdir=%{_libdir} \
+ --sysconfdir=%{_sysconfdir}/httpd/conf --includedir=%{_includedir}/httpd \
+ --libexecdir=%{_libdir}/httpd/modules --datadir=%{contentdir} \
+ --with-installbuilddir=%{_libdir}/httpd/build --enable-layout=openEuler \
+ --enable-mpms-shared=all --with-apr=%{_prefix} --with-apr-util=%{_prefix} \
+ --enable-suexec --with-suexec --enable-suexec-capabilities \
+ --with-suexec-caller=%{suexec_caller} --with-suexec-docroot=%{docroot} \
+ --without-suexec-logfile --with-suexec-syslog \
+ --with-suexec-bin=%{_sbindir}/suexec --with-brotli --enable-pie --with-pcre2 \
+ --with-suexec-uidmin=1000 --with-suexec-gidmin=1000 \
+ --enable-mods-shared=all --enable-ssl --with-ssl --disable-distcache \
+ --enable-proxy --enable-proxy-fdpass --enable-cache --enable-disk-cache \
+ --enable-ldap --enable-authnz-ldap --enable-cgid --enable-cgi \
+ --enable-authn-anon --enable-authn-alias --enable-systemd \
+ --disable-imagemap --disable-file-cache --disable-http2 $*
+
+%make_build
+
+%install
+rm -rf $RPM_BUILD_ROOT
+%make_install
+
+install -d $RPM_BUILD_ROOT%{_unitdir}
+install -p -m644 $RPM_SOURCE_DIR/httpd.service $RPM_BUILD_ROOT%{_unitdir}/httpd.service
+install -p -m644 $RPM_SOURCE_DIR/{htcacheclean.service,httpd.socket,httpd@.service,httpd-init.service} $RPM_BUILD_ROOT%{_unitdir}/
+
+install -D -m644 $RPM_SOURCE_DIR/README.confd $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/README
+install -D -m644 $RPM_SOURCE_DIR/README.confmod $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/README
+install -p -m644 $RPM_SOURCE_DIR/0*.conf $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/
+
+sed -i '/^#LoadModule mpm_%{mpm}_module /s/^#//' $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/00-mpm.conf
+touch -r $RPM_SOURCE_DIR/00-mpm.conf $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/00-mpm.conf
+
+install -d $RPM_BUILD_ROOT%{_unitdir}/httpd.service.d
+install -D -m 644 -p $RPM_SOURCE_DIR/10-listen443.conf $RPM_BUILD_ROOT%{_unitdir}/httpd.socket.d/10-listen443.conf
+install -m644 -p $RPM_SOURCE_DIR/{welcome.conf,ssl.conf,manual.conf,userdir.conf} $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/
+install -m 644 docs/conf/extra/httpd-autoindex.conf $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/autoindex.conf
+
+rm -v docs/conf/extra/httpd-{ssl,userdir}.conf
+rm $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf/*.conf
+
+install -m 644 -p $RPM_SOURCE_DIR/httpd.conf $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf/httpd.conf
+
+install -D -m 644 -p $RPM_SOURCE_DIR/htcacheclean.sysconf \
+ $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/htcacheclean
+
+install -D -m 644 -p $RPM_SOURCE_DIR/httpd.tmpfiles \
+ $RPM_BUILD_ROOT%{_prefix}/lib/tmpfiles.d/httpd.conf
+
+install -d $RPM_BUILD_ROOT%{_localstatedir}/lib/{dav,httpd} \
+ $RPM_BUILD_ROOT/run/httpd/htcacheclean
+
+sed -i \
+ "s,@@ServerRoot@@/var,%{_localstatedir}/lib/dav,;
+ s,@@ServerRoot@@/user.passwd,/etc/httpd/conf/user.passwd,;
+ s,@@ServerRoot@@/docs,%{docroot},;
+ s,@@ServerRoot@@,%{docroot},;
+ s,@@Port@@,80,;" \
+ docs/conf/extra/*.conf
+
+install -d $RPM_BUILD_ROOT%{_localstatedir}/cache/httpd/{proxy,ssl}
+
+install -d $RPM_BUILD_ROOT%{_rpmconfigdir}/macros.d
+cat > $RPM_BUILD_ROOT%{_rpmconfigdir}/macros.d/macros.httpd <<EOF
+%%_httpd_mmn %{mmnisa}
+%%_httpd_apxs %%{_bindir}/apxs
+%%_httpd_modconfdir %%{_sysconfdir}/httpd/conf.modules.d
+%%_httpd_confdir %%{_sysconfdir}/httpd/conf.d
+%%_httpd_contentdir %{contentdir}
+%%_httpd_moddir %%{_libdir}/httpd/modules
+EOF
+
+install -d $RPM_BUILD_ROOT%{contentdir}/{noindex,server-status}
+install -m 644 -p $RPM_SOURCE_DIR/index.html \
+ $RPM_BUILD_ROOT%{contentdir}/noindex/index.html
+install -m 644 -p docs/server-status/* \
+ $RPM_BUILD_ROOT%{contentdir}/server-status
+
+rm -rf %{contentdir}/htdocs
+find $RPM_BUILD_ROOT%{contentdir}/manual \( \
+ -name \*.xml -o -name \*.xml.* -o -name \*.ent -o -name \*.xsl -o -name \*.dtd \
+ \) -print0 | xargs -0 rm -f
+
+
+
+for f in `find $RPM_BUILD_ROOT%{contentdir}/manual -name \*.html -type f`; do
+ if test -f ${f}.en; then
+ cp ${f}.en ${f}
+ rm ${f}.*
+ fi
+done
+
+rm -v $RPM_BUILD_ROOT%{docroot}/html/*.html \
+ $RPM_BUILD_ROOT%{docroot}/cgi-bin/*
+
+ln -s ../../pixmaps/poweredby.png \
+ $RPM_BUILD_ROOT%{contentdir}/icons/poweredby.png
+
+ln -s ../..%{_localstatedir}/log/httpd $RPM_BUILD_ROOT/etc/httpd/logs
+ln -s ../..%{_localstatedir}/lib/httpd $RPM_BUILD_ROOT/etc/httpd/state
+ln -s /run/httpd $RPM_BUILD_ROOT/etc/httpd/run
+ln -s ../..%{_libdir}/httpd/modules $RPM_BUILD_ROOT/etc/httpd/modules
+
+install -D -m755 $RPM_SOURCE_DIR/httpd-ssl-pass-dialog \
+ $RPM_BUILD_ROOT%{_libexecdir}/httpd-ssl-pass-dialog
+
+install -m755 $RPM_SOURCE_DIR/httpd-ssl-gencerts $RPM_BUILD_ROOT%{_libexecdir}/httpd-ssl-gencerts
+
+install -D -p -m 755 $RPM_SOURCE_DIR/action-graceful.sh $RPM_BUILD_ROOT%{_libexecdir}/initscripts/legacy-actions/httpd/graceful
+install -p -m 755 $RPM_SOURCE_DIR/action-configtest.sh $RPM_BUILD_ROOT%{_libexecdir}/initscripts/legacy-actions/httpd/configtest
+
+install -D -m 644 -p $RPM_SOURCE_DIR/httpd.logrotate \
+ $RPM_BUILD_ROOT/etc/logrotate.d/httpd
+
+install -m 644 -p httpd.service.8 httpd-init.service.8 httpd.socket.8 httpd@.service.8 \
+ $RPM_BUILD_ROOT%{_mandir}/man8
+
+sed -e "s|/usr/local/apache2/conf/httpd.conf|/etc/httpd/conf/httpd.conf|" \
+ -e "s|/usr/local/apache2/conf/mime.types|/etc/mime.types|" \
+ -e "s|/usr/local/apache2/conf/magic|/etc/httpd/conf/magic|" \
+ -e "s|/usr/local/apache2/logs/error_log|/var/log/httpd/error_log|" \
+ -e "s|/usr/local/apache2/logs/access_log|/var/log/httpd/access_log|" \
+ -e "s|/usr/local/apache2/logs/httpd.pid|/run/httpd/httpd.pid|" \
+ -e "s|/usr/local/apache2|/etc/httpd|" < docs/man/httpd.8 \
+ > $RPM_BUILD_ROOT%{_mandir}/man8/httpd.8
+
+sed -i '/.*DEFAULT_..._LIBEXECDIR/d;/DEFAULT_..._INSTALLBUILDDIR/d' \
+ $RPM_BUILD_ROOT%{_includedir}/httpd/ap_config_layout.h
+
+rm -vf \
+ $RPM_BUILD_ROOT%{_libdir}/*.exp \
+ $RPM_BUILD_ROOT/etc/httpd/conf/mime.types \
+ $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.exp \
+ $RPM_BUILD_ROOT%{_libdir}/httpd/build/config.nice \
+ $RPM_BUILD_ROOT%{_bindir}/{ap?-config,dbmmanage} \
+ $RPM_BUILD_ROOT%{_sbindir}/{checkgid,envvars*} \
+ $RPM_BUILD_ROOT%{contentdir}/htdocs/* \
+ $RPM_BUILD_ROOT%{_mandir}/man1/dbmmanage.* \
+ $RPM_BUILD_ROOT%{contentdir}/cgi-bin/*
+
+rm -rf $RPM_BUILD_ROOT/etc/httpd/conf/{original,extra}
+
+%pre filesystem
+getent group apache >/dev/null || groupadd -g 48 -r apache
+getent passwd apache >/dev/null || \
+ useradd -r -u 48 -g apache -s /sbin/nologin \
+ -d %{contentdir} -c "Apache" apache
+exit 0
+
+%post
+%systemd_post httpd.service htcacheclean.service httpd.socket
+
+%preun
+%systemd_preun httpd.service htcacheclean.service httpd.socket
+
+%postun
+%systemd_postun httpd.service htcacheclean.service httpd.socket
+
+%posttrans
+test -f /etc/sysconfig/httpd-disable-posttrans || \
+ /bin/systemctl try-restart --no-block httpd.service htcacheclean.service >/dev/null 2>&1 || :
+
+%check
+if readelf -d $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.so | grep TEXTREL; then
+ : modules contain non-relocatable code
+ exit 1
+fi
+set +x
+rv=0
+for f in $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.so; do
+ m=${f##*/}
+ if ! grep -q $m $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/*.conf; then
+ echo ERROR: Module $m not configured. Disable it, or load it.
+ rv=1
+ fi
+done
+mods=`grep -h ^LoadModule $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/*.conf | sed 's,.*modules/,,'`
+for m in $mods; do
+ f=$RPM_BUILD_ROOT%{_libdir}/httpd/modules/${m}
+ if ! test -x $f; then
+ echo ERROR: Module $m is configured but not built.
+ rv=1
+ fi
+done
+set -x
+exit $rv
+
+%files
+%doc ABOUT_APACHE README CHANGES LICENSE VERSIONING NOTICE
+%doc docs/conf/extra/*.conf
+%doc instance.conf server-status.conf
+
+%{_sysconfdir}/httpd/{modules,logs,*run,state}
+%config(noreplace) %{_sysconfdir}/httpd/conf/{httpd.conf,magic}
+%config(noreplace) %{_sysconfdir}/logrotate.d/httpd
+%config(noreplace) %{_sysconfdir}/httpd/conf.d/*.conf
+%exclude %{_sysconfdir}/httpd/conf.d/ssl.conf
+%exclude %{_sysconfdir}/httpd/conf.d/manual.conf
+%{_sysconfdir}/httpd/conf.modules.d/README
+%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/*.conf
+%exclude %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf
+%exclude %{_sysconfdir}/httpd/conf.modules.d/00-proxyhtml.conf
+%exclude %{_sysconfdir}/httpd/conf.modules.d/01-ldap.conf
+%exclude %{_sysconfdir}/httpd/conf.modules.d/01-session.conf
+%exclude %{_sysconfdir}/httpd/conf.modules.d/01-md.conf
+
+%config(noreplace) %{_sysconfdir}/sysconfig/htcacheclean
+%ghost %{_sysconfdir}/sysconfig/httpd
+%{_prefix}/lib/tmpfiles.d/httpd.conf
+%{_libexecdir}/initscripts/legacy-actions/httpd/*
+%{_sbindir}/ht*
+%{_sbindir}/fcgistarter
+%{_sbindir}/apachectl
+%{_sbindir}/rotatelogs
+%caps(cap_setuid,cap_setgid+pe) %attr(510,root,%{suexec_caller}) %{_sbindir}/suexec
+%{_libdir}/httpd/modules/mod*.so
+%exclude %{_libdir}/httpd/modules/mod_auth_form.so
+%exclude %{_libdir}/httpd/modules/mod_ssl.so
+%exclude %{_libdir}/httpd/modules/mod_md.so
+%exclude %{_libdir}/httpd/modules/mod_*ldap.so
+%exclude %{_libdir}/httpd/modules/mod_proxy_html.so
+%exclude %{_libdir}/httpd/modules/mod_xml2enc.so
+%exclude %{_libdir}/httpd/modules/mod_session*.so
+
+%{contentdir}/icons/*
+%{contentdir}/error/README
+%{contentdir}/error/*.var
+%{contentdir}/error/include/*.html
+%{contentdir}/noindex/index.html
+%{contentdir}/server-status/*
+
+%attr(0710,root,apache) %dir /run/httpd
+%attr(0700,apache,apache) %dir /run/httpd/htcacheclean
+%attr(0700,root,root) %dir %{_localstatedir}/log/httpd
+%attr(0700,apache,apache) %dir %{_localstatedir}/lib/dav
+%attr(0700,apache,apache) %dir %{_localstatedir}/lib/httpd
+%attr(0700,apache,apache) %dir %{_localstatedir}/cache/httpd
+%attr(0700,apache,apache) %dir %{_localstatedir}/cache/httpd/proxy
+
+%{_mandir}/man8/*
+%exclude %{_mandir}/man8/httpd-init.*
+
+%{_unitdir}/httpd.service
+%{_unitdir}/httpd@.service
+%{_unitdir}/htcacheclean.service
+%{_unitdir}/*.socket
+
+%files filesystem
+%{_sysconfdir}/httpd/conf.d/README
+%dir %{docroot}/cgi-bin
+%dir %{docroot}/html
+%dir %{contentdir}/icons
+%attr(755,root,root) %dir %{_unitdir}/httpd.service.d
+%attr(755,root,root) %dir %{_unitdir}/httpd.socket.d
+
+%files tools
+%doc LICENSE NOTICE
+%{_bindir}/*
+%{_mandir}/man1/*
+%exclude %{_bindir}/apxs
+%exclude %{_mandir}/man1/apxs.1*
+
+%files help
+%{contentdir}/manual
+%config(noreplace) %{_sysconfdir}/httpd/conf.d/manual.conf
+
+%files -n mod_ssl
+%{_libdir}/httpd/modules/mod_ssl.so
+%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf
+%config(noreplace) %{_sysconfdir}/httpd/conf.d/ssl.conf
+%attr(0700,apache,root) %dir %{_localstatedir}/cache/httpd/ssl
+%{_unitdir}/httpd-init.service
+%{_libexecdir}/httpd-ssl-pass-dialog
+%{_libexecdir}/httpd-ssl-gencerts
+%{_unitdir}/httpd.socket.d/10-listen443.conf
+%{_mandir}/man8/httpd-init.*
+
+%files -n mod_proxy_html
+%{_libdir}/httpd/modules/mod_proxy_html.so
+%{_libdir}/httpd/modules/mod_xml2enc.so
+%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-proxyhtml.conf
+
+%files -n mod_ldap
+%{_libdir}/httpd/modules/mod_*ldap.so
+%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/01-ldap.conf
+
+%files -n mod_session
+%{_libdir}/httpd/modules/mod_session*.so
+%{_libdir}/httpd/modules/mod_auth_form.so
+%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/01-session.conf
+
+%files -n mod_md
+%{_libdir}/httpd/modules/mod_md.so
+%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/01-md.conf
+
+%files devel
+%{_includedir}/httpd
+%{_bindir}/apxs
+%{_mandir}/man1/apxs.1*
+%{_libdir}/httpd/build/*.mk
+%{_libdir}/httpd/build/*.sh
+%{_rpmconfigdir}/macros.d/macros.httpd
+
+%changelog
+* Sat Jan 27 2024 Funda Wang <fundawang@yeah.net> - 1:2.4.58-1
+- 2.4.58
+
+* Mon Aug 28 2023 Funda Wang <fundawang@yeah.net> - 1:2.4.57-1
+- 2.4.57
+
+* Mon Aug 14 2023 chengyechun <chengyechun1@huawei.com> - 2.4.55-4
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:fix memory leak in calc_sha256_hash
+
+* Thu Mar 9 2023 chengyechun <chengyechun1@huawei.com> - 2.4.55-3
+- Type:CVE
+- ID:CVE-2023-27522, CVE-2023-25690
+- SUG:restart
+- DESC:fix CVE-2023-27522, CVE-2023-25690
+
+* Sat Mar 4 2023 Wenlong Zhang <zhangwenlong@loongson.cn> - 2.4.55-2
+- Type:bugfix
+- ID:NA
+- SUG:restart
+- DESC:fix build error for loongarch64
+
+* Wed Feb 1 2023 chengyechun <chengyechun1@huawei.com> - 2.4.55-1
+- Type:enhancement
+- ID:NA
+- SUG:restart
+- DESC:update to httpd-2.4.55
+
+* Thu Dec 15 2022 chengyechun <chengyechun1@huawei.com> - 2.4.51-9
+- Type:bugfix
+- ID:
+- SUG:restart
+- DESC:reduce the dependency of httpd on system-logos installation
+
+* Tue Dec 13 2022 chengyechun <chengyechun1@huawei.com> - 2.4.51-8
+- Type:bugfix
+- ID:
+- SUG:restart
+- DESC:fix the name of the CVE
+
+* Thu Jul 21 2022 chengyechun <chengyechun1@huawei.com> - 2.4.51-7
+- Type:CVE
+- ID:CVE-2022-28330
+- SUG:restart
+- DESC:fix CVE-2022-28330
+
+* Sat Jun 25 2022 seuzw <930zhaowei@163.com> - 2.4.51-5
+- Type:bugfix
+- ID:NA
+- SUG:restart
+- DESC:switch from PCRE to PCRE2
+
+* Mon Jun 20 2022 chengyechun <chengyechun1@huawei.com> - 2.4.51-5
+- Type:CVE
+- ID:NA
+- SUG:restart
+- DESC:fix CVE-2022-31813,CVE-2022-28614,CVE-2022-29404,CVE-2022-26377,CVE-2022-30522,CVE-2022-30556
+
+* Mon Jun 20 2022 chengyechun <chengyechun1@huawei.com> - 2.4.51-4
+- Type:CVE
+- ID:NA
+- SUG:restart
+- DESC:fix CVE-2022-28615
+
+* Wed Mar 30 2022 yanglu <yanglu72@h-partners.com> - 2.4.51-3
+- Type:cves
+- ID:NA
+- SUG:restart
+- DESC:fix CVE-2021-44224
+
+* Mon Mar 28 2022 yanglu <yanglu72@h-partners.com> - 2.4.51-2
+- Type:cves
+- ID:NA
+- SUG:restart
+- DESC:fix CVE-2022-22719 CVE-2022-22720 CVE-2022-22721 CVE-2022-23934
+
+* Sat Mar 26 2022 yanglu <yanglu72@h-partners.com> - 2.4.51-1
+- Type:requirement
+- ID:NA
+- SUG:NA
+- DESC:update httpd to 2.4.51
+
+* Mon Jan 24 2022 quanhongfei <quanhongfei@huawei.com> - 2.4.48-6
+- Type:bugfix
+- ID:NA
+- SUG:restart
+- DESC:fix mod info in configuration
+
+* Wed Dec 29 2021 orange-snn <songnannan2@huawei.com> - 2.4.48-5
+- Type:cves
+- ID:NA
+- SUG:restart
+- DESC:fix CVE-2021-44790
+
+* Fri Nov 05 2021 gaihuiying <gaihuiying1@huawei.com> - 2.4.48-4
+- Type:bugfix
+- ID:NA
+- SUG:restart
+- DESC:fix int overflow in ap_timeout_parameter_parse
+ Improve fix to please a fuzzer int overflow
+
+* Wed Sep 29 2021 gaihuiying <gaihuiying1@huawei.com> - 2.4.48-3
+- Type:cves
+- ID:CVE-2021-40438 CVE-2021-39275
+- SUG:restart
+- DESC:fix CVE-2021-40438 fully and correctly
+ fix CVE-2021-39275
+
+* Tue Sep 28 2021 gaihuiying <gaihuiying1@huawei.com> - 2.4.48-2
+- Type:cves
+- ID:CVE-2021-34798 CVE-2021-36160 CVE-2021-40438
+- SUG:restart
+- DESC:fix CVE-2021-34798 CVE-2021-36160 CVE-2021-40438
+
+* Tue Jul 13 2021 gaihuiying<gaihuiying1@huawei.com> - 2.4.48-1
+- Type:requirement
+- ID:NA
+- SUG:NA
+- DESC:update to 2.4.48
+
+* Wed Jun 23 2021 gaihuiying <gaihuiying1@huawei.com> - 2.4.46-5
+- Type:cves
+- ID:CVE-2021-26690
+- SUG:NA
+- DESC:fix CVE-2021-26690
+
+* Tue Jun 22 2021 gaihuiying <gaihuiying1@huawei.com> - 2.4.46-4
+- Type:cves
+- ID:CVE-2021-30641
+- SUG:NA
+- DESC:fix CVE-2021-30641
+
+* Mon Jun 21 2021 yanglu <yanglu72@huawei.com> - 2.4.46-3
+- Type:cves
+- ID:CVE-2020-13950 CVE-2020-35452
+- SUG:NA
+- DESC:fix CVE-2020-13950 CVE-2020-35452
+
+* Wed Jun 16 2021 yanglu <yanglu72@huawei.com> - 2.4.46-2
+- Type:cves
+- ID:CVE-2021-26691
+- SUG:NA
+- DESC:fix CVE-2021-26691
+
+* Tue Jan 26 2021 xihaochen<xihaochen@huawei.com> - 2.4.46-1
+- Type:requirements
+- ID:NA
+- SUG:NA
+- DESC: update httpd to 2.4.46
+
+* Sun Sep 27 2020 yuboyun <yuboyun@huawei.com> - 2.4.43-4
+- Type:cves
+- ID:CVE-2020-9490 CVE-2020-11984 CVE-2020-11993
+- SUG:restart
+- DESC:fix CVE-2020-9490 CVE-2020-11984 CVE-2020-11993
+
+* Sat Sep 5 2020 zhaowei<zhaowei23@huawei.com> - 2.4.43-3
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC: update source URL
+
+* Thu Aug 06 2020 gaihuiying <gaihuiying1@huawei.com> - 2.4.43-2
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:fix build error
+
+* Fri Jul 24 2020 zhujunhao <zhujunhao8@huawei.com> - 2.4.43-1
+- Type:NA
+- ID:NA
+- SUG:NA
+- DESC:Update to 2.4.43
+
+* Thu Apr 23 2020 openEuler Buildteam <buildteam@openeuler.org> - 2.4.34-17
+- Type:cves
+- ID:CVE-2019-9517 CVE-2019-10081 CVE-2019-10082 CVE-2020-1927 CVE-2020-1934
+- SUG:restart
+- DESC:fix CVE-2019-9517 CVE-2019-10081 CVE-2019-10082 CVE-2020-1927 CVE-2020-1934
+
+* Wed Apr 15 2020 chenzhen <chenzhen44@huawei.com> - 2.4.34-16
+- Type:cves
+- ID:CVE-2019-10092 CVE-2019-10097 CVE-2019-10098 CVE-2019-0196 CVE-2019-0197
+- SUG:NA
+- DESC:fix CVE-2019-10092 CVE-2019-10097 CVE-2019-10098 CVE-2019-0196 CVE-2019-0197
+
+* Mon Feb 03 2020 yanzhihua <yanzhihua4@huawei.com> - 2.4.34-15
+- Type:cves
+- ID:CVE-2018-17199
+- SUG:NA
+- DESC:fix CVE-2018-17199
+
+* Sun Jan 19 2020 openEuler Buildteam <buildteam@openeuler.org> - 2.4.34-14
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:add SSLCipherSuite
+
+* Sat Jan 11 2020 openEuler Buildteam <buildteam@openeuler.org> - 2.4.34-13
+- Type:NA
+- ID:NA
+- SUG:NA
+- DESC:delete patches
+
+* Wed Dec 25 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.4.34-12
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:change source
+
+* Tue Oct 29 2019 zhuchengliang <zhuchengliang4@huawei.com> - 2.4.34-11
+- Type:NA
+- ID:NA
+- SUG:NA
+- DESC:add systemd_postun para
+
+* Wed Sep 25 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.4.34-10
+- Type:cves
+- ID:CVE-2019-0220
+- SUG:NA
+- DESC:fix CVE-2019-0220
+
+* Sat Sep 21 2019 liyongqiang<liyongqiang10@huawei.com> - 2.4.34-9
+- Package init
diff --git a/httpd.tmpfiles b/httpd.tmpfiles
new file mode 100644
index 0000000..f148886
--- /dev/null
+++ b/httpd.tmpfiles
@@ -0,0 +1,2 @@
+d /run/httpd 710 root apache
+d /run/httpd/htcacheclean 700 apache apache
diff --git a/httpd@.service b/httpd@.service
new file mode 100644
index 0000000..c58ae88
--- /dev/null
+++ b/httpd@.service
@@ -0,0 +1,23 @@
+# This is a template for httpd instances.
+# See httpd@.service(8) for more information.
+
+[Unit]
+Description=The Apache HTTP Server
+After=network.target remote-fs.target nss-lookup.target
+Documentation=man:httpd@.service(8)
+
+[Service]
+Type=notify
+Environment=LANG=C
+Environment=HTTPD_INSTANCE=%i
+ExecStartPre=/bin/mkdir -m 710 -p /run/httpd/instance-%i
+ExecStartPre=/bin/chown root.apache /run/httpd/instance-%i
+ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND -f conf/%i.conf
+ExecReload=/usr/sbin/httpd $OPTIONS -k graceful -f conf/%i.conf
+# Send SIGWINCH for graceful stop
+KillSignal=SIGWINCH
+KillMode=mixed
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..9a6f426
--- /dev/null
+++ b/index.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <title>Test Page for the Apache HTTP Server on openEuler Linux</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <style type="text/css">
+ /*<![CDATA[*/
+ body {
+ background-color: #fff;
+ color: #000;
+ font-size: 0.9em;
+ font-family: sans-serif,helvetica;
+ margin: 0;
+ padding: 0;
+ }
+ :link {
+ color: #c00;
+ }
+ :visited {
+ color: #c00;
+ }
+ a:hover {
+ color: #f50;
+ }
+ h1 {
+ text-align: center;
+ margin: 0;
+ padding: 0.6em 2em 0.4em;
+ background-color: #900;
+ color: #fff;
+ font-weight: normal;
+ font-size: 1.75em;
+ border-bottom: 2px solid #000;
+ }
+ h1 strong {
+ font-weight: bold;
+ }
+ h2 {
+ font-size: 1.1em;
+ font-weight: bold;
+ }
+ hr {
+ display: none;
+ }
+ .content {
+ padding: 1em 5em;
+ }
+ .content-columns {
+ /* Setting relative positioning allows for
+ absolute positioning for sub-classes */
+ position: relative;
+ padding-top: 1em;
+ }
+ .content-column-left {
+ /* Value for IE/Win; will be overwritten for other browsers */
+ width: 47%;
+ padding-right: 3%;
+ float: left;
+ padding-bottom: 2em;
+ }
+ .content-column-left hr {
+ display: none;
+ }
+ .content-column-right {
+ /* Values for IE/Win; will be overwritten for other browsers */
+ width: 47%;
+ padding-left: 3%;
+ float: left;
+ padding-bottom: 2em;
+ }
+ .content-columns>.content-column-left, .content-columns>.content-column-right {
+ /* Non-IE/Win */
+ }
+ img {
+ border: 2px solid #fff;
+ padding: 2px;
+ margin: 2px;
+ }
+ a:hover img {
+ border: 2px solid #f50;
+ }
+ /*]]>*/
+ </style>
+ </head>
+
+ <body>
+ <h1>openEuler Linux <strong>Test Page</strong></h1>
+
+ <div class="content">
+ <div class="content-middle">
+ <p>This page is used to test the proper operation of the Apache HTTP server after it has been installed. If you can read this page, it means that the Apache HTTP server installed at this site is working properly.</p>
+ </div>
+ <hr />
+
+ <div class="content-columns">
+ <div class="content-column-left">
+ <h2>If you are a member of the general public:</h2>
+
+ <p>The fact that you are seeing this page indicates that the website you just visited is either experiencing problems, or is undergoing routine maintenance.</p>
+
+ <p>If you would like to let the administrators of this website know that you've seen this page instead of the page you expected, you should send them e-mail. In general, mail sent to the name "webmaster" and directed to the website's domain should reach the appropriate person.</p>
+
+ <p>For example, if you experienced problems while visiting www.example.com, you should send e-mail to "webmaster@example.com".</p>
+
+ <p>For information on openEuler Linux, please visit the <a href="https://openeuler.org/">openEuler, Inc. website</a>. The documentation for openEuler Linux is <a href="https://openeuler.org/">available on the openEuler, Inc. website</a>.</p>
+ <hr />
+ </div>
+
+ <div class="content-column-right">
+ <h2>If you are the website administrator:</h2>
+
+ <p>You may now add content to the directory <tt>/var/www/html/</tt>. Note that until you do so, people visiting your website will see this page, and not your content. To prevent this page from ever being used, follow the instructions in the file <tt>/etc/httpd/conf.d/welcome.conf</tt>.</p>
+
+ <p>You are free to use the image below on web sites powered by the Apache HTTP Server:</p>
+
+ <p align="center"><a href="http://httpd.apache.org/"><img src="/icons/apache_pb2.gif" alt="[ Powered by Apache ]"/></a></p>
+
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/instance.conf b/instance.conf
new file mode 100644
index 0000000..f2b03f7
--- /dev/null
+++ b/instance.conf
@@ -0,0 +1,23 @@
+#
+# This is an example instance-specific configuration file. See the
+# httpd.service(8) man page for detailed information on using the
+# the httpd@.service with instances.
+#
+# To use this example, copy instance.conf to /etc/httpd/conf/foobar.conf
+# This config will then used as the default configuration when
+# running:
+#
+# # systemctl start httpd@foobar.service
+#
+# The changes compared to the default are:
+# - DefaultRuntime and Pidfile renamed to be instance-specific
+# - default logfile names are prefixed with the instance name
+# - /etc/httpd/conf.d is NOT included by default (conf.modules.d still is)
+#
+# Further customisations will be required for an instance to run
+# simultaneously to httpd.service under the default configuration,
+# e.g. changing the port used with Listen.
+#
+
+DefaultRuntimeDir /run/httpd/instance-${HTTPD_INSTANCE}
+PidFile /run/httpd/instance-${HTTPD_INSTANCE}.pid
diff --git a/manual.conf b/manual.conf
new file mode 100644
index 0000000..133652b
--- /dev/null
+++ b/manual.conf
@@ -0,0 +1,13 @@
+#
+# This configuration file allows the manual to be accessed at
+# http://localhost/manual/
+#
+Alias /manual /usr/share/httpd/manual
+
+<Directory "/usr/share/httpd/manual">
+ Options Indexes
+ AllowOverride None
+ Require all granted
+
+ RedirectMatch 301 ^/manual/(?:da|de|en|es|fr|ja|ko|pt-br|ru|tr|zh-cn)(/.*)$ "/manual$1"
+</Directory>
diff --git a/server-status.conf b/server-status.conf
new file mode 100644
index 0000000..be98f1b
--- /dev/null
+++ b/server-status.conf
@@ -0,0 +1,10 @@
+#
+# Lua-based server-status page; requires mod_lua to be loaded
+# as per default configuration.
+#
+LuaMapHandler ^/server-status$ /usr/share/httpd/server-status/server-status.lua
+
+<Directory /usr/share/httpd/server-status>
+ AllowOverride None
+ Require local
+</Directory>
diff --git a/sources b/sources
new file mode 100644
index 0000000..5fc5e22
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+30377ec4d7fb8361e1d1f2ab3158b467 httpd-2.4.58.tar.bz2
diff --git a/ssl.conf b/ssl.conf
new file mode 100644
index 0000000..afc92d3
--- /dev/null
+++ b/ssl.conf
@@ -0,0 +1,219 @@
+#
+# When we also provide SSL we have to listen to the
+# standard HTTPS port in addition.
+#
+Listen 443 https
+
+##
+## SSL Global Context
+##
+## All SSL configuration in this context applies both to
+## the main server and all SSL-enabled virtual hosts.
+##
+
+# Pass Phrase Dialog:
+# Configure the pass phrase gathering process.
+# The filtering dialog program (`builtin' is a internal
+# terminal dialog) has to provide the pass phrase on stdout.
+SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
+
+# Inter-Process Session Cache:
+# Configure the SSL Session Cache: First the mechanism
+# to use and second the expiring timeout (in seconds).
+SSLSessionCache shmcb:/run/httpd/sslcache(512000)
+SSLSessionCacheTimeout 300
+
+# Pseudo Random Number Generator (PRNG):
+# Configure one or more sources to seed the PRNG of the
+# SSL library. The seed data should be of good random quality.
+# WARNING! On some platforms /dev/random blocks if not enough entropy
+# is available. This means you then cannot use the /dev/random device
+# because it would lead to very long connection times (as long as
+# it requires to make more entropy available). But usually those
+# platforms additionally provide a /dev/urandom device which doesn't
+# block. So, if available, use this one instead. Read the mod_ssl User
+# Manual for more details.
+SSLRandomSeed startup file:/dev/urandom 256
+SSLRandomSeed connect builtin
+#SSLRandomSeed startup file:/dev/random 512
+#SSLRandomSeed connect file:/dev/random 512
+#SSLRandomSeed connect file:/dev/urandom 512
+
+#
+# Use "SSLCryptoDevice" to enable any supported hardware
+# accelerators. Use "openssl engine -v" to list supported
+# engine names. NOTE: If you enable an accelerator and the
+# server does not start, consult the error logs and ensure
+# your accelerator is functioning properly.
+#
+SSLCryptoDevice builtin
+#SSLCryptoDevice ubsec
+
+##
+## SSL Virtual Host Context
+##
+
+<VirtualHost _default_:443>
+
+# General setup for the virtual host, inherited from global configuration
+#DocumentRoot "/var/www/html"
+#ServerName www.example.com:443
+
+# Use separate log files for the SSL virtual host; note that LogLevel
+# is not inherited from httpd.conf.
+ErrorLog logs/ssl_error_log
+TransferLog logs/ssl_access_log
+LogLevel warn
+
+# SSL Engine Switch:
+# Enable/Disable SSL for this virtual host.
+SSLEngine on
+
+# List the protocol versions which clients are allowed to connect with.
+# The OpenSSL system profile is configured by default. See
+# update-crypto-policies(8) for more details.
+#SSLProtocol all -SSLv3
+#SSLProxyProtocol all -SSLv3
+
+# User agents such as web browsers are not configured for the user's
+# own preference of either security or performance, therefore this
+# must be the prerogative of the web server administrator who manages
+# cpu load versus confidentiality, so enforce the server's cipher order.
+SSLHonorCipherOrder on
+
+# SSL Cipher Suite:
+# List the ciphers that the client is permitted to negotiate.
+# See the mod_ssl documentation for a complete list.
+# The OpenSSL system profile is configured by default. See
+# update-crypto-policies(8) for more details.
+SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SHA1:!RC4
+SSLProxyCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SHA1:!RC4
+
+# Point SSLCertificateFile at a PEM encoded certificate. If
+# the certificate is encrypted, then you will be prompted for a
+# pass phrase. Note that restarting httpd will prompt again. Keep
+# in mind that if you have both an RSA and a DSA certificate you
+# can configure both in parallel (to also allow the use of DSA
+# ciphers, etc.)
+# Some ECC cipher suites (http://www.ietf.org/rfc/rfc4492.txt)
+# require an ECC certificate which can also be configured in
+# parallel.
+SSLCertificateFile /etc/pki/tls/certs/localhost.crt
+
+# Server Private Key:
+# If the key is not combined with the certificate, use this
+# directive to point at the key file. Keep in mind that if
+# you've both a RSA and a DSA private key you can configure
+# both in parallel (to also allow the use of DSA ciphers, etc.)
+# ECC keys, when in use, can also be configured in parallel
+SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
+
+# Server Certificate Chain:
+# Point SSLCertificateChainFile at a file containing the
+# concatenation of PEM encoded CA certificates which form the
+# certificate chain for the server certificate. Alternatively
+# the referenced file can be the same as SSLCertificateFile
+# when the CA certificates are directly appended to the server
+# certificate for convenience.
+#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
+
+# Certificate Authority (CA):
+# Set the CA certificate verification path where to find CA
+# certificates for client authentication or alternatively one
+# huge file containing all of them (file must be PEM encoded)
+#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
+
+# Client Authentication (Type):
+# Client certificate verification type and depth. Types are
+# none, optional, require and optional_no_ca. Depth is a
+# number which specifies how deeply to verify the certificate
+# issuer chain before deciding the certificate is not valid.
+#SSLVerifyClient require
+#SSLVerifyDepth 10
+
+# Access Control:
+# With SSLRequire you can do per-directory access control based
+# on arbitrary complex boolean expressions containing server
+# variable checks and other lookup directives. The syntax is a
+# mixture between C and Perl. See the mod_ssl documentation
+# for more details.
+#<Location />
+#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
+# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
+# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
+# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
+# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
+# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
+#</Location>
+
+# SSL Engine Options:
+# Set various options for the SSL engine.
+# o FakeBasicAuth:
+# Translate the client X.509 into a Basic Authorisation. This means that
+# the standard Auth/DBMAuth methods can be used for access control. The
+# user name is the `one line' version of the client's X.509 certificate.
+# Note that no password is obtained from the user. Every entry in the user
+# file needs this password: `xxj31ZMTZzkVA'.
+# o ExportCertData:
+# This exports two additional environment variables: SSL_CLIENT_CERT and
+# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
+# server (always existing) and the client (only existing when client
+# authentication is used). This can be used to import the certificates
+# into CGI scripts.
+# o StdEnvVars:
+# This exports the standard SSL/TLS related `SSL_*' environment variables.
+# Per default this exportation is switched off for performance reasons,
+# because the extraction step is an expensive operation and is usually
+# useless for serving static content. So one usually enables the
+# exportation for CGI and SSI requests only.
+# o StrictRequire:
+# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
+# under a "Satisfy any" situation, i.e. when it applies access is denied
+# and no other module can change it.
+# o OptRenegotiate:
+# This enables optimized SSL connection renegotiation handling when SSL
+# directives are used in per-directory context.
+#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
+<FilesMatch "\.(cgi|shtml|phtml|php)$">
+ SSLOptions +StdEnvVars
+</FilesMatch>
+<Directory "/var/www/cgi-bin">
+ SSLOptions +StdEnvVars
+</Directory>
+
+# SSL Protocol Adjustments:
+# The safe and default but still SSL/TLS standard compliant shutdown
+# approach is that mod_ssl sends the close notify alert but doesn't wait for
+# the close notify alert from client. When you need a different shutdown
+# approach you can use one of the following variables:
+# o ssl-unclean-shutdown:
+# This forces an unclean shutdown when the connection is closed, i.e. no
+# SSL close notify alert is sent or allowed to be received. This violates
+# the SSL/TLS standard but is needed for some brain-dead browsers. Use
+# this when you receive I/O errors because of the standard approach where
+# mod_ssl sends the close notify alert.
+# o ssl-accurate-shutdown:
+# This forces an accurate shutdown when the connection is closed, i.e. a
+# SSL close notify alert is sent and mod_ssl waits for the close notify
+# alert of the client. This is 100% SSL/TLS standard compliant, but in
+# practice often causes hanging connections with brain-dead browsers. Use
+# this only for browsers where you know that their SSL implementation
+# works correctly.
+# Notice: Most problems of broken clients are also related to the HTTP
+# keep-alive facility, so you usually additionally want to disable
+# keep-alive for those clients, too. Use variable "nokeepalive" for this.
+# Similarly, one has to force some clients to use HTTP/1.0 to workaround
+# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
+# "force-response-1.0" for this.
+BrowserMatch "MSIE [2-5]" \
+ nokeepalive ssl-unclean-shutdown \
+ downgrade-1.0 force-response-1.0
+
+# Per-Server Logging:
+# The home of a custom SSL log file. Use this when you want a
+# compact non-error SSL logfile on a virtual host basis.
+CustomLog logs/ssl_request_log \
+ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
+
+</VirtualHost>
+
diff --git a/userdir.conf b/userdir.conf
new file mode 100644
index 0000000..b5d7a49
--- /dev/null
+++ b/userdir.conf
@@ -0,0 +1,36 @@
+#
+# UserDir: The name of the directory that is appended onto a user's home
+# directory if a ~user request is received.
+#
+# The path to the end user account 'public_html' directory must be
+# accessible to the webserver userid. This usually means that ~userid
+# must have permissions of 711, ~userid/public_html must have permissions
+# of 755, and documents contained therein must be world-readable.
+# Otherwise, the client will only receive a "403 Forbidden" message.
+#
+<IfModule mod_userdir.c>
+ #
+ # UserDir is disabled by default since it can confirm the presence
+ # of a username on the system (depending on home directory
+ # permissions).
+ #
+ UserDir disabled
+
+ #
+ # To enable requests to /~user/ to serve the user's public_html
+ # directory, remove the "UserDir disabled" line above, and uncomment
+ # the following line instead:
+ #
+ #UserDir public_html
+</IfModule>
+
+#
+# Control access to UserDir directories. The following is an example
+# for a site where these directories are restricted to read-only.
+#
+<Directory "/home/*/public_html">
+ AllowOverride FileInfo AuthConfig Limit Indexes
+ Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
+ Require method GET POST OPTIONS
+</Directory>
+
diff --git a/welcome.conf b/welcome.conf
new file mode 100644
index 0000000..5d1e452
--- /dev/null
+++ b/welcome.conf
@@ -0,0 +1,18 @@
+#
+# This configuration file enables the default "Welcome" page if there
+# is no default index page present for the root URL. To disable the
+# Welcome page, comment out all the lines below.
+#
+# NOTE: if this file is removed, it will be restored on upgrades.
+#
+<LocationMatch "^/+$">
+ Options -Indexes
+ ErrorDocument 403 /.noindex.html
+</LocationMatch>
+
+<Directory /usr/share/httpd/noindex>
+ AllowOverride None
+ Require all granted
+</Directory>
+
+Alias /.noindex.html /usr/share/httpd/noindex/index.html