diff --git a/01-cgi.conf b/01-cgi.conf
index 5b8b936..4b680cf 100644
--- a/01-cgi.conf
+++ b/01-cgi.conf
@@ -2,10 +2,7 @@
# which has been configured in 00-mpm.conf. mod_cgid should be used
# with a threaded MPM; mod_cgi with the prefork MPM.
-
- LoadModule cgid_module modules/mod_cgid.so
-
-
+
LoadModule cgid_module modules/mod_cgid.so
diff --git a/01-md.conf b/01-md.conf
deleted file mode 100644
index 2739202..0000000
--- a/01-md.conf
+++ /dev/null
@@ -1 +0,0 @@
-LoadModule md_module modules/mod_md.so
diff --git a/apachectl.sh b/apachectl.sh
index ee2dba8..e0f6f78 100755
--- a/apachectl.sh
+++ b/apachectl.sh
@@ -22,6 +22,7 @@ fi
ACMD="$1"
ARGV="$@"
SVC='httpd.service'
+HTTPD='@HTTPDBIN@'
if [ "x$2" != "x" ] ; then
echo Passing arguments to httpd using apachectl is no longer supported.
@@ -48,8 +49,12 @@ graceful-stop)
/usr/bin/systemctl kill --signal=SIGWINCH $SVC
ERROR=$?
;;
-configtest)
- /usr/sbin/service ${SVC/.service//} $ACMD
+configtest|-t)
+ $HTTPD -t
+ ERROR=$?
+ ;;
+-v|-V)
+ $HTTPD $ACMD
ERROR=$?
;;
*)
diff --git a/httpd-2.4.33-export.patch b/httpd-2.4.33-export.patch
deleted file mode 100644
index 9adf398..0000000
--- a/httpd-2.4.33-export.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-
-There is no need to "suck in" the apr/apr-util symbols when using
-a shared libapr{,util}, it just bloats the symbol table; so don't.
-
-Upstream-HEAD: needed
-Upstream-2.0: omit
-Upstream-Status: EXPORT_DIRS change is conditional on using shared apr
-
---- httpd-2.4.33/server/Makefile.in.export
-+++ httpd-2.4.33/server/Makefile.in
-@@ -60,9 +60,6 @@
- ls $$dir/*.h ; \
- done; \
- echo "$(top_srcdir)/server/mpm_fdqueue.h"; \
-- for dir in $(EXPORT_DIRS_APR); do \
-- ls $$dir/ap[ru].h $$dir/ap[ru]_*.h 2>/dev/null; \
-- done; \
- ) | sed -e s,//,/,g | sort -u > $@
-
- exports.c: export_files
diff --git a/httpd-2.4.37-r1828172+.patch b/httpd-2.4.37-r1828172+.patch
new file mode 100644
index 0000000..822cccf
--- /dev/null
+++ b/httpd-2.4.37-r1828172+.patch
@@ -0,0 +1,1069 @@
+# ./pullrev.sh 1828172 1862968 1863191
+http://svn.apache.org/viewvc?view=revision&revision=1828172
+http://svn.apache.org/viewvc?view=revision&revision=1862968
+http://svn.apache.org/viewvc?view=revision&revision=1863191
+
+--- httpd-2.4.37/modules/generators/mod_cgi.c
++++ httpd-2.4.37/modules/generators/mod_cgi.c
+@@ -92,6 +92,10 @@
+ apr_size_t bufbytes;
+ } cgi_server_conf;
+
++typedef struct {
++ apr_interval_time_t timeout;
++} cgi_dirconf;
++
+ static void *create_cgi_config(apr_pool_t *p, server_rec *s)
+ {
+ cgi_server_conf *c =
+@@ -112,6 +116,12 @@
+ 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 +160,17 @@
+ 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,6 +179,9 @@
+ "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}
+ };
+
+@@ -471,23 +495,26 @@
+ 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);
+ }
+ }
+ }
+@@ -563,189 +590,7 @@
+ }
+
+ #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
+-};
+-
++#include "cgi_common.h"
+ #endif
+
+ static int cgi_handler(request_rec *r)
+@@ -766,6 +611,8 @@
+ 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;
+@@ -928,7 +775,7 @@
+ 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
+@@ -985,7 +832,7 @@
+ * stderr output, as normal. */
+ discard_script_output(bb);
+ apr_brigade_destroy(bb);
+- apr_file_pipe_timeout_set(script_err, r->server->timeout);
++ apr_file_pipe_timeout_set(script_err, timeout);
+ log_script_err(r, script_err);
+ }
+
+@@ -1036,7 +883,7 @@
+ * 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);
++ apr_file_pipe_timeout_set(script_err, timeout);
+ log_script_err(r, script_err);
+ }
+
+@@ -1277,7 +1124,7 @@
+ 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 */
+--- httpd-2.4.37/modules/generators/mod_cgid.c
++++ httpd-2.4.37/modules/generators/mod_cgid.c
+@@ -342,15 +342,19 @@
+ 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 +369,52 @@
+ }
+ } 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;
++
++ msg.msg_control = u.buf;
++ msg.msg_controllen = sizeof(u.buf);
++
++ if (errfd) *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;
++ }
++
++ cmsg = CMSG_FIRSTHDR(&msg);
++ if (errfd
++ && cmsg
++ && 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 +431,7 @@
+ 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 +446,39 @@
+ }
+ 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 +487,7 @@
+ }
+
+ 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 +498,7 @@
+ 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;
+ }
+@@ -479,14 +556,15 @@
+ 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,
++ 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 +585,21 @@
+ 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 +614,7 @@
+ 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 +665,34 @@
+ }
+ }
+
++/* 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)
+@@ -669,7 +766,7 @@
+ }
+
+ while (!daemon_should_exit) {
+- int errfileno = STDERR_FILENO;
++ int errfileno;
+ char *argv0 = NULL;
+ char **env = NULL;
+ const char * const *argv;
+@@ -709,7 +806,7 @@
+ 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)
+@@ -741,6 +838,16 @@
+ 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);
+
+@@ -800,7 +907,10 @@
+ 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);
+
+@@ -1099,6 +1209,33 @@
+ return ret;
+ }
+
++/* Soak up stderr from a script and redirect it to the error log.
++ * TODO: log_scripterror() and this could move to cgi_common.h. */
++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;
++ cgid_server_conf *conf = ap_get_module_config(r->server->module_config, &cgid_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, argsbuffer);
++ }
++
++ return rv;
++}
++
+ 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)
+@@ -1204,6 +1341,11 @@
+ return ret;
+ }
+
++#ifdef HAVE_CGID_FDPASSING
++/* Pull in CGI bucket implementation. */
++#include "cgi_common.h"
++#endif
++
+ static int connect_to_daemon(int *sdptr, request_rec *r,
+ cgid_server_conf *conf)
+ {
+@@ -1395,6 +1537,7 @@
+
+ static int cgid_handler(request_rec *r)
+ {
++ conn_rec *c = r->connection;
+ int retval, nph, dbpos;
+ char *argv0, *dbuf;
+ apr_bucket_brigade *bb;
+@@ -1404,10 +1547,11 @@
+ 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;
+@@ -1416,7 +1560,7 @@
+ 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) {
+@@ -1469,6 +1613,17 @@
+ }
+ */
+
++#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.
+@@ -1481,12 +1636,16 @@
+ 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");
+ }
+
++ /* 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;
+@@ -1508,12 +1667,7 @@
+ */
+
+ 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...
+@@ -1605,23 +1759,28 @@
+ */
+ shutdown(sd, 1);
+
++ 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);
++
+ /* 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 = log_script(r, conf, ret, dbuf, sbuf, bb, script_err);
+
+ /*
+ * ret could be HTTP_NOT_MODIFIED in the case that the CGI script
+@@ -1658,6 +1817,11 @@
+ /* Soak up all the script output */
+ 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);
++ }
++
+ /* This redirect needs to be a GET no matter what the original
+ * method was.
+ */
+@@ -1690,7 +1854,6 @@
+ }
+
+ if (nph) {
+- conn_rec *c = r->connection;
+ struct ap_filter_t *cur;
+
+ /* get rid of all filters up through protocol... since we
+@@ -1704,14 +1867,20 @@
+ }
+ 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);
++ 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. */
+ }
+
+@@ -1829,7 +1998,7 @@
+ 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;
+--- httpd-2.4.37/modules/generators/config5.m4
++++ httpd-2.4.37/modules/generators/config5.m4
+@@ -78,4 +78,15 @@
+
+ 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
++#include ])
++ fi
++])
++
+ APACHE_MODPATH_FINISH
+--- httpd-2.4.37/modules/generators/cgi_common.h
++++ httpd-2.4.37/modules/generators/cgi_common.h
+@@ -0,0 +1,216 @@
++/* 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"
++
++/* 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);
++
++ 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
++};
++
diff --git a/httpd-2.4.37-r1842929+.patch b/httpd-2.4.37-r1842929+.patch
deleted file mode 100644
index e841e34..0000000
--- a/httpd-2.4.37-r1842929+.patch
+++ /dev/null
@@ -1,326 +0,0 @@
-# ./pullrev.sh 1842929 1842931
-http://svn.apache.org/viewvc?view=revision&revision=1842929
-http://svn.apache.org/viewvc?view=revision&revision=1842931
-http://svn.apache.org/viewvc?view=revision&revision=1852982
-
---- httpd-2.4.38/acinclude.m4.r1842929+
-+++ httpd-2.4.38/acinclude.m4
-@@ -45,6 +45,7 @@
- APACHE_SUBST(installbuilddir)
- APACHE_SUBST(runtimedir)
- APACHE_SUBST(proxycachedir)
-+ APACHE_SUBST(statedir)
- APACHE_SUBST(other_targets)
- APACHE_SUBST(progname)
- APACHE_SUBST(prefix)
-@@ -663,6 +664,7 @@
- APACHE_SUBST_EXPANDED_ARG(runtimedir)
- APACHE_SUBST_EXPANDED_ARG(logfiledir)
- APACHE_SUBST_EXPANDED_ARG(proxycachedir)
-+ APACHE_SUBST_EXPANDED_ARG(statedir)
- ])
-
- dnl
---- httpd-2.4.38/config.layout.r1842929+
-+++ httpd-2.4.38/config.layout
-@@ -29,6 +29,7 @@
- includedir: ${prefix}/include
- localstatedir: ${prefix}
- runtimedir: ${localstatedir}/logs
-+ statedir: ${localstatedir}/state
- logfiledir: ${localstatedir}/logs
- proxycachedir: ${localstatedir}/proxy
-
-@@ -54,6 +55,7 @@
- includedir: ${prefix}/include+
- localstatedir: ${prefix}/var+
- runtimedir: ${localstatedir}/run
-+ statedir: ${localstatedir}/state
- logfiledir: ${localstatedir}/log
- proxycachedir: ${localstatedir}/proxy
-
-@@ -78,6 +80,7 @@
- includedir: /System/Library/Frameworks/Apache.framework/Versions/2.0/Headers
- localstatedir: /var
- runtimedir: ${prefix}/Logs
-+ statedir: ${prefix}/State
- logfiledir: ${prefix}/Logs
- proxycachedir: ${prefix}/ProxyCache
-
-@@ -102,6 +105,7 @@
- includedir: ${prefix}/include+
- localstatedir: /var
- runtimedir: ${localstatedir}/run
-+ statedir: ${localstatedir}/state
- logfiledir: ${localstatedir}/log+
- proxycachedir: ${runtimedir}/proxy
-
-@@ -126,6 +130,7 @@
- includedir: ${prefix}/include/apache
- localstatedir: /var
- runtimedir: ${localstatedir}/run
-+ statedir: ${localstatedir}/lib/httpd
- logfiledir: ${localstatedir}/log/httpd
- proxycachedir: ${localstatedir}/cache/httpd
-
-@@ -151,6 +156,7 @@
- includedir: ${prefix}/include/httpd
- runtimedir: /run/httpd
- logfiledir: ${localstatedir}/log/httpd
-+ statedir: ${localstatedir}/lib/httpd
- proxycachedir: ${localstatedir}/cache/httpd/proxy
-
-
-@@ -175,6 +181,7 @@
- localstatedir: /var${prefix}
- runtimedir: ${localstatedir}/run
- logfiledir: ${localstatedir}/logs
-+ statedir: ${localstatedir}/state
- proxycachedir: ${localstatedir}/proxy
-
-
-@@ -197,6 +204,7 @@
- cgidir: ${datadir}/cgi-bin
- includedir: ${prefix}/include/apache
- localstatedir: /var/lib/httpd
-+ statedir: ${localstatedir}
- runtimedir: /var/run
- logfiledir: /var/log/httpd
- proxycachedir: /var/cache/httpd
-@@ -223,6 +231,7 @@
- localstatedir: /var
- runtimedir: ${localstatedir}/run
- logfiledir: ${localstatedir}/log/httpd
-+ statedir: ${prefix}/state
- proxycachedir: ${localstatedir}/proxy
-
-
-@@ -246,6 +255,7 @@
- includedir: ${exec_prefix}/include
- localstatedir: ${prefix}
- runtimedir: /var/run
-+ statedir: ${datadir}/state
- logfiledir: ${datadir}/logs
- proxycachedir: ${datadir}/proxy
-
-@@ -271,6 +281,7 @@
- localstatedir: ${prefix}
- runtimedir: ${prefix}/logs
- logfiledir: ${prefix}/logs
-+ statedir: ${prefix}/state
- proxycachedir: ${prefix}/proxy
-
-
-@@ -315,6 +326,7 @@
- cgidir: ${prefix}/usr/lib/cgi-bin
- includedir: ${exec_prefix}/include/apache2
- localstatedir: ${prefix}/var/lock/apache2
-+ statedir: ${prefix}/var/lib/apache2
- runtimedir: ${prefix}/var/run/apache2
- logfiledir: ${prefix}/var/log/apache2
- proxycachedir: ${prefix}/var/cache/apache2/proxy
-@@ -343,6 +355,7 @@
- manualdir: ${datadir}/manual
- cgidir: ${datadir}/cgi-bin
- runtimedir: ${localstatedir}/run
-+ runtimedir: ${localstatedir}/lib/httpd
- logfiledir: ${localstatedir}/log/httpd
- proxycachedir: ${localstatedir}/cache/httpd/cache-root
-
-@@ -366,6 +379,7 @@
- manualdir: ${prefix}/manual
- includedir: ${prefix}/include
- localstatedir: /var/httpd
-+ statedir: ${localstatedir}/state
- runtimedir: ${localstatedir}/run
- logfiledir: ${localstatedir}/logs
- proxycachedir: ${localstatedir}/proxy
-@@ -391,6 +405,7 @@
- includedir: ${prefix}/include/httpd
- localstatedir: /var
- runtimedir: ${localstatedir}/run/httpd
-+ statedir: ${localstatedir}/lib/httpd
- logfiledir: ${localstatedir}/log/httpd
- proxycachedir: ${localstatedir}/cache/httpd
-
---- httpd-2.4.38/configure.in.r1842929+
-+++ httpd-2.4.38/configure.in
-@@ -41,7 +41,7 @@
- AC_PREFIX_DEFAULT(/usr/local/apache2)
-
- dnl Get the layout here, so we can pass the required variables to apr
--APR_ENABLE_LAYOUT(Apache, [errordir iconsdir htdocsdir cgidir])
-+APR_ENABLE_LAYOUT(Apache, [errordir iconsdir htdocsdir cgidir statedir])
-
- dnl reparse the configure arguments.
- APR_PARSE_ARGUMENTS
---- httpd-2.4.38/include/ap_config_layout.h.in.r1842929+
-+++ httpd-2.4.38/include/ap_config_layout.h.in
-@@ -60,5 +60,7 @@
- #define DEFAULT_REL_LOGFILEDIR "@rel_logfiledir@"
- #define DEFAULT_EXP_PROXYCACHEDIR "@exp_proxycachedir@"
- #define DEFAULT_REL_PROXYCACHEDIR "@rel_proxycachedir@"
-+#define DEFAULT_EXP_STATEDIR "@exp_statedir@"
-+#define DEFAULT_REL_STATEDIR "@rel_statedir@"
-
- #endif /* AP_CONFIG_LAYOUT_H */
---- httpd-2.4.38/include/http_config.h.r1842929+
-+++ httpd-2.4.38/include/http_config.h
-@@ -757,6 +757,14 @@
- */
- AP_DECLARE(char *) ap_runtime_dir_relative(apr_pool_t *p, const char *fname);
-
-+/**
-+ * Compute the name of a persistent state file (e.g. a database or
-+ * long-lived cache) relative to the appropriate state directory.
-+ * Absolute paths are returned as-is. The state directory is
-+ * configured via the DefaultStateDir directive or at build time.
-+ */
-+AP_DECLARE(char *) ap_state_dir_relative(apr_pool_t *p, const char *fname);
-+
- /* Finally, the hook for dynamically loading modules in... */
-
- /**
---- httpd-2.4.38/Makefile.in.r1842929+
-+++ httpd-2.4.38/Makefile.in
-@@ -213,6 +213,7 @@
- install-other:
- @test -d $(DESTDIR)$(logfiledir) || $(MKINSTALLDIRS) $(DESTDIR)$(logfiledir)
- @test -d $(DESTDIR)$(runtimedir) || $(MKINSTALLDIRS) $(DESTDIR)$(runtimedir)
-+ @test -d $(DESTDIR)$(statedir) || $(MKINSTALLDIRS) $(DESTDIR)$(statedir)
- @for ext in dll x; do \
- file=apachecore.$$ext; \
- if test -f $$file; then \
---- httpd-2.4.38/modules/dav/fs/mod_dav_fs.c.r1842929+
-+++ httpd-2.4.38/modules/dav/fs/mod_dav_fs.c
-@@ -29,6 +29,10 @@
-
- extern module AP_MODULE_DECLARE_DATA dav_fs_module;
-
-+#ifndef DEFAULT_DAV_LOCKDB
-+#define DEFAULT_DAV_LOCKDB "davlockdb"
-+#endif
-+
- const char *dav_get_lockdb_path(const request_rec *r)
- {
- dav_fs_server_conf *conf;
-@@ -39,7 +43,11 @@
-
- static void *dav_fs_create_server_config(apr_pool_t *p, server_rec *s)
- {
-- return apr_pcalloc(p, sizeof(dav_fs_server_conf));
-+ dav_fs_server_conf *conf = apr_pcalloc(p, sizeof(dav_fs_server_conf));
-+
-+ conf->lockdb_path = ap_state_dir_relative(p, DEFAULT_DAV_LOCKDB);
-+
-+ return conf;
- }
-
- static void *dav_fs_merge_server_config(apr_pool_t *p,
---- httpd-2.4.38/modules/md/mod_md_config.c.r1842929+
-+++ httpd-2.4.38/modules/md/mod_md_config.c
-@@ -54,10 +54,14 @@
-
- #define DEF_VAL (-1)
-
-+#ifndef MD_DEFAULT_BASE_DIR
-+#define MD_DEFAULT_BASE_DIR "md"
-+#endif
-+
- /* Default settings for the global conf */
- static md_mod_conf_t defmc = {
- NULL,
-- "md",
-+ NULL,
- NULL,
- NULL,
- 80,
-@@ -112,6 +116,7 @@
- memcpy(mod_md_config, &defmc, sizeof(*mod_md_config));
- mod_md_config->mds = apr_array_make(pool, 5, sizeof(const md_t *));
- mod_md_config->unused_names = apr_array_make(pool, 5, sizeof(const md_t *));
-+ mod_md_config->base_dir = ap_state_dir_relative(pool, MD_DEFAULT_BASE_DIR);
-
- apr_pool_cleanup_register(pool, NULL, cleanup_mod_config, apr_pool_cleanup_null);
- }
---- httpd-2.4.38/server/core.c.r1842929+
-+++ httpd-2.4.38/server/core.c
-@@ -129,6 +129,8 @@
- AP_DECLARE_DATA int ap_run_mode = AP_SQ_RM_UNKNOWN;
- AP_DECLARE_DATA int ap_config_generation = 0;
-
-+static const char *core_state_dir;
-+
- static void *create_core_dir_config(apr_pool_t *a, char *dir)
- {
- core_dir_config *conf;
-@@ -3104,6 +3106,24 @@
- return NULL;
- }
-
-+static const char *set_state_dir(cmd_parms *cmd, void *dummy, const char *arg)
-+{
-+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
-+
-+ if (err != NULL) {
-+ return err;
-+ }
-+
-+ if ((apr_filepath_merge((char**)&core_state_dir, NULL,
-+ ap_server_root_relative(cmd->temp_pool, arg),
-+ APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS)
-+ || !ap_is_directory(cmd->temp_pool, core_state_dir)) {
-+ return "DefaultStateDir must be a valid directory, absolute or relative to ServerRoot";
-+ }
-+
-+ return NULL;
-+}
-+
- static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg)
- {
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
-@@ -4398,6 +4418,8 @@
- "Common directory of server-related files (logs, confs, etc.)"),
- AP_INIT_TAKE1("DefaultRuntimeDir", set_runtime_dir, NULL, RSRC_CONF | EXEC_ON_READ,
- "Common directory for run-time files (shared memory, locks, etc.)"),
-+AP_INIT_TAKE1("DefaultStateDir", set_state_dir, NULL, RSRC_CONF | EXEC_ON_READ,
-+ "Common directory for persistent state (databases, long-lived caches, etc.)"),
- AP_INIT_TAKE1("ErrorLog", set_server_string_slot,
- (void *)APR_OFFSETOF(server_rec, error_fname), RSRC_CONF,
- "The filename of the error log"),
-@@ -4927,6 +4949,7 @@
- ap_regcomp_set_default_cflags(AP_REG_DOLLAR_ENDONLY);
-
- mpm_common_pre_config(pconf);
-+ core_state_dir = NULL;
-
- return OK;
- }
-@@ -5150,6 +5173,27 @@
- }
- }
-
-+AP_DECLARE(char *) ap_state_dir_relative(apr_pool_t *p, const char *file)
-+{
-+ char *newpath = NULL;
-+ apr_status_t rv;
-+ const char *state_dir;
-+
-+ state_dir = core_state_dir
-+ ? core_state_dir
-+ : ap_server_root_relative(p, DEFAULT_REL_STATEDIR);
-+
-+ rv = apr_filepath_merge(&newpath, state_dir, file, APR_FILEPATH_TRUENAME, p);
-+ if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv)
-+ || APR_STATUS_IS_ENOENT(rv)
-+ || APR_STATUS_IS_ENOTDIR(rv))) {
-+ return newpath;
-+ }
-+ else {
-+ return NULL;
-+ }
-+}
-+
- static apr_random_t *rng = NULL;
- #if APR_HAS_THREADS
- static apr_thread_mutex_t *rng_mutex = NULL;
diff --git a/httpd-2.4.37-r1861793+.patch b/httpd-2.4.37-r1861793+.patch
new file mode 100644
index 0000000..22886e2
--- /dev/null
+++ b/httpd-2.4.37-r1861793+.patch
@@ -0,0 +1,270 @@
+# ./pullrev.sh 1861793 1862611 1862612
+http://svn.apache.org/viewvc?view=revision&revision=1861793
+
+http://svn.apache.org/viewvc?view=revision&revision=1862611
+http://svn.apache.org/viewvc?view=revision&revision=1862612
+
+--- httpd-2.4.37/configure.in
++++ httpd-2.4.37/configure.in
+@@ -500,6 +500,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
++#include
++#include
++
++#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.37/support/htpasswd.c
++++ httpd-2.4.37/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 aencryption 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.37/support/passwd_common.c
++++ httpd-2.4.37/support/passwd_common.c
+@@ -185,10 +185,15 @@
+ #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.37/support/passwd_common.h
++++ httpd-2.4.37/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,
+--- httpd-2.4.37/docs/man/htpasswd.1
++++ httpd-2.4.37/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,6 +73,12 @@
+ \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
+@@ -79,11 +85,14 @@
+ \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,11 +161,14 @@
+ 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 and \fBcrypt()\fR formats are insecure by today's standards\&.
++The SHA-1 and \fBcrypt()\fR formats are insecure by today's standards\&.
+
++.PP
++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"
+
+ .PP
diff --git a/httpd-2.4.39-export.patch b/httpd-2.4.39-export.patch
new file mode 100644
index 0000000..b20a6e7
--- /dev/null
+++ b/httpd-2.4.39-export.patch
@@ -0,0 +1,57 @@
+
+Reduce size of httpd binary by telling linker to export all symbols
+from libmain.a, rather than bloating the symbol table with ap_hack_*
+to do so indirectly.
+
+Upstream: https://svn.apache.org/r1861685 (as new default-off configure option)
+
+--- httpd-2.4.39/Makefile.in.export
++++ httpd-2.4.39/Makefile.in
+@@ -4,8 +4,15 @@
+
+ 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) \
+--- httpd-2.4.39/server/main.c.export
++++ httpd-2.4.39/server/main.c
+@@ -835,17 +835,3 @@
+ 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
+--- httpd-2.4.39/server/Makefile.in.export
++++ httpd-2.4.39/server/Makefile.in
+@@ -12,7 +12,7 @@
+ 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 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/httpd-2.4.39-r1842929+.patch b/httpd-2.4.39-r1842929+.patch
new file mode 100644
index 0000000..0bf7292
--- /dev/null
+++ b/httpd-2.4.39-r1842929+.patch
@@ -0,0 +1,221 @@
+# ./pullrev.sh 1842929 1842931 1852982 1853631 1857731
+http://svn.apache.org/viewvc?view=revision&revision=1842929
+http://svn.apache.org/viewvc?view=revision&revision=1842931
+http://svn.apache.org/viewvc?view=revision&revision=1852982
+http://svn.apache.org/viewvc?view=revision&revision=1857731
+http://svn.apache.org/viewvc?view=revision&revision=1853631
+
+--- httpd-2.4.39/acinclude.m4.r1842929+
++++ httpd-2.4.39/acinclude.m4
+@@ -45,6 +45,7 @@
+ APACHE_SUBST(installbuilddir)
+ APACHE_SUBST(runtimedir)
+ APACHE_SUBST(proxycachedir)
++ APACHE_SUBST(statedir)
+ APACHE_SUBST(other_targets)
+ APACHE_SUBST(progname)
+ APACHE_SUBST(prefix)
+@@ -663,6 +664,7 @@
+ APACHE_SUBST_EXPANDED_ARG(runtimedir)
+ APACHE_SUBST_EXPANDED_ARG(logfiledir)
+ APACHE_SUBST_EXPANDED_ARG(proxycachedir)
++ APACHE_SUBST_EXPANDED_ARG(statedir)
+ ])
+
+ dnl
+--- httpd-2.4.39/configure.in.r1842929+
++++ httpd-2.4.39/configure.in
+@@ -41,7 +41,7 @@
+ AC_PREFIX_DEFAULT(/usr/local/apache2)
+
+ dnl Get the layout here, so we can pass the required variables to apr
+-APR_ENABLE_LAYOUT(Apache, [errordir iconsdir htdocsdir cgidir])
++APR_ENABLE_LAYOUT(Apache, [errordir iconsdir htdocsdir cgidir statedir])
+
+ dnl reparse the configure arguments.
+ APR_PARSE_ARGUMENTS
+--- httpd-2.4.39/include/ap_config_layout.h.in.r1842929+
++++ httpd-2.4.39/include/ap_config_layout.h.in
+@@ -60,5 +60,7 @@
+ #define DEFAULT_REL_LOGFILEDIR "@rel_logfiledir@"
+ #define DEFAULT_EXP_PROXYCACHEDIR "@exp_proxycachedir@"
+ #define DEFAULT_REL_PROXYCACHEDIR "@rel_proxycachedir@"
++#define DEFAULT_EXP_STATEDIR "@exp_statedir@"
++#define DEFAULT_REL_STATEDIR "@rel_statedir@"
+
+ #endif /* AP_CONFIG_LAYOUT_H */
+--- httpd-2.4.39/include/http_config.h.r1842929+
++++ httpd-2.4.39/include/http_config.h
+@@ -757,6 +757,14 @@
+ */
+ AP_DECLARE(char *) ap_runtime_dir_relative(apr_pool_t *p, const char *fname);
+
++/**
++ * Compute the name of a persistent state file (e.g. a database or
++ * long-lived cache) relative to the appropriate state directory.
++ * Absolute paths are returned as-is. The state directory is
++ * configured via the DefaultStateDir directive or at build time.
++ */
++AP_DECLARE(char *) ap_state_dir_relative(apr_pool_t *p, const char *fname);
++
+ /* Finally, the hook for dynamically loading modules in... */
+
+ /**
+--- httpd-2.4.39/Makefile.in.r1842929+
++++ httpd-2.4.39/Makefile.in
+@@ -213,6 +213,7 @@
+ install-other:
+ @test -d $(DESTDIR)$(logfiledir) || $(MKINSTALLDIRS) $(DESTDIR)$(logfiledir)
+ @test -d $(DESTDIR)$(runtimedir) || $(MKINSTALLDIRS) $(DESTDIR)$(runtimedir)
++ @test -d $(DESTDIR)$(statedir) || $(MKINSTALLDIRS) $(DESTDIR)$(statedir)
+ @for ext in dll x; do \
+ file=apachecore.$$ext; \
+ if test -f $$file; then \
+--- httpd-2.4.39/modules/dav/fs/mod_dav_fs.c.r1842929+
++++ httpd-2.4.39/modules/dav/fs/mod_dav_fs.c
+@@ -29,6 +29,10 @@
+
+ extern module AP_MODULE_DECLARE_DATA dav_fs_module;
+
++#ifndef DEFAULT_DAV_LOCKDB
++#define DEFAULT_DAV_LOCKDB "davlockdb"
++#endif
++
+ const char *dav_get_lockdb_path(const request_rec *r)
+ {
+ dav_fs_server_conf *conf;
+@@ -57,6 +61,24 @@
+ return newconf;
+ }
+
++static apr_status_t dav_fs_post_config(apr_pool_t *p, apr_pool_t *plog,
++ apr_pool_t *ptemp, server_rec *base_server)
++{
++ server_rec *s;
++
++ for (s = base_server; s; s = s->next) {
++ dav_fs_server_conf *conf;
++
++ conf = ap_get_module_config(s->module_config, &dav_fs_module);
++
++ if (!conf->lockdb_path) {
++ conf->lockdb_path = ap_state_dir_relative(p, DEFAULT_DAV_LOCKDB);
++ }
++ }
++
++ return OK;
++}
++
+ /*
+ * Command handler for the DAVLockDB directive, which is TAKE1
+ */
+@@ -87,6 +109,8 @@
+
+ static void register_hooks(apr_pool_t *p)
+ {
++ ap_hook_post_config(dav_fs_post_config, NULL, NULL, APR_HOOK_MIDDLE);
++
+ dav_hook_gather_propsets(dav_fs_gather_propsets, NULL, NULL,
+ APR_HOOK_MIDDLE);
+ dav_hook_find_liveprop(dav_fs_find_liveprop, NULL, NULL, APR_HOOK_MIDDLE);
+--- httpd-2.4.39/server/core.c.r1842929+
++++ httpd-2.4.39/server/core.c
+@@ -129,6 +129,8 @@
+ AP_DECLARE_DATA int ap_run_mode = AP_SQ_RM_UNKNOWN;
+ AP_DECLARE_DATA int ap_config_generation = 0;
+
++static const char *core_state_dir;
++
+ static void *create_core_dir_config(apr_pool_t *a, char *dir)
+ {
+ core_dir_config *conf;
+@@ -1409,12 +1411,15 @@
+ return res_buf;
+ }
+
+-static int reset_config_defines(void *dummy)
++/* pconf cleanup - clear global variables set from config here. */
++static apr_status_t reset_config(void *dummy)
+ {
+ ap_server_config_defines = saved_server_config_defines;
+ saved_server_config_defines = NULL;
+ server_config_defined_vars = NULL;
+- return OK;
++ core_state_dir = NULL;
++
++ return APR_SUCCESS;
+ }
+
+ /*
+@@ -3113,6 +3118,24 @@
+ return NULL;
+ }
+
++static const char *set_state_dir(cmd_parms *cmd, void *dummy, const char *arg)
++{
++ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
++
++ if (err != NULL) {
++ return err;
++ }
++
++ if ((apr_filepath_merge((char**)&core_state_dir, NULL,
++ ap_server_root_relative(cmd->temp_pool, arg),
++ APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS)
++ || !ap_is_directory(cmd->temp_pool, core_state_dir)) {
++ return "DefaultStateDir must be a valid directory, absolute or relative to ServerRoot";
++ }
++
++ return NULL;
++}
++
+ static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg)
+ {
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
+@@ -4407,6 +4430,8 @@
+ "Common directory of server-related files (logs, confs, etc.)"),
+ AP_INIT_TAKE1("DefaultRuntimeDir", set_runtime_dir, NULL, RSRC_CONF | EXEC_ON_READ,
+ "Common directory for run-time files (shared memory, locks, etc.)"),
++AP_INIT_TAKE1("DefaultStateDir", set_state_dir, NULL, RSRC_CONF | EXEC_ON_READ,
++ "Common directory for persistent state (databases, long-lived caches, etc.)"),
+ AP_INIT_TAKE1("ErrorLog", set_server_string_slot,
+ (void *)APR_OFFSETOF(server_rec, error_fname), RSRC_CONF,
+ "The filename of the error log"),
+@@ -4934,8 +4959,7 @@
+
+ if (!saved_server_config_defines)
+ init_config_defines(pconf);
+- apr_pool_cleanup_register(pconf, NULL, reset_config_defines,
+- apr_pool_cleanup_null);
++ apr_pool_cleanup_register(pconf, NULL, reset_config, apr_pool_cleanup_null);
+
+ ap_regcomp_set_default_cflags(AP_REG_DOLLAR_ENDONLY);
+
+@@ -5163,6 +5187,27 @@
+ }
+ }
+
++AP_DECLARE(char *) ap_state_dir_relative(apr_pool_t *p, const char *file)
++{
++ char *newpath = NULL;
++ apr_status_t rv;
++ const char *state_dir;
++
++ state_dir = core_state_dir
++ ? core_state_dir
++ : ap_server_root_relative(p, DEFAULT_REL_STATEDIR);
++
++ rv = apr_filepath_merge(&newpath, state_dir, file, APR_FILEPATH_TRUENAME, p);
++ if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv)
++ || APR_STATUS_IS_ENOENT(rv)
++ || APR_STATUS_IS_ENOTDIR(rv))) {
++ return newpath;
++ }
++ else {
++ return NULL;
++ }
++}
++
+ static apr_random_t *rng = NULL;
+ #if APR_HAS_THREADS
+ static apr_thread_mutex_t *rng_mutex = NULL;
diff --git a/httpd-2.4.39-r1861269.patch b/httpd-2.4.39-r1861269.patch
new file mode 100644
index 0000000..4142e3c
--- /dev/null
+++ b/httpd-2.4.39-r1861269.patch
@@ -0,0 +1,24 @@
+# ./pullrev.sh r1861269
+http://svn.apache.org/viewvc?view=revision&revision=r1861269
+
+Allows "httpd -L" etc to work before httpd-init.service has run,
+if mod_ssl is installed.
+
+--- httpd-2.4.37/modules/ssl/ssl_engine_config.c
++++ httpd-2.4.37/modules/ssl/ssl_engine_config.c
+@@ -904,8 +904,14 @@
+ static const char *ssl_cmd_check_file(cmd_parms *parms,
+ const char **file)
+ {
+- const char *filepath = ap_server_root_relative(parms->pool, *file);
++ const char *filepath;
+
++ /* If only dumping the config, don't verify the paths */
++ if (ap_state_query(AP_SQ_RUN_MODE) == AP_SQ_RM_CONFIG_DUMP) {
++ return NULL;
++ }
++
++ filepath = ap_server_root_relative(parms->pool, *file);
+ if (!filepath) {
+ return apr_pstrcat(parms->pool, parms->cmd->name,
+ ": Invalid file path ", *file, NULL);
diff --git a/httpd.spec b/httpd.spec
index ff6ec31..9eda715 100644
--- a/httpd.spec
+++ b/httpd.spec
@@ -12,8 +12,8 @@
Summary: Apache HTTP Server
Name: httpd
-Version: 2.4.39
-Release: 3%{?dist}
+Version: 2.4.41
+Release: 1%{?dist}
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source1: index.html
@@ -44,7 +44,6 @@ 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
@@ -63,8 +62,8 @@ Patch3: httpd-2.4.1-deplibs.patch
# Needed for socket activation and mod_systemd patch
Patch19: httpd-2.4.25-detect-systemd.patch
# Features/functional changes
-Patch21: httpd-2.4.37-r1842929+.patch
-Patch23: httpd-2.4.33-export.patch
+Patch21: httpd-2.4.39-r1842929+.patch
+Patch23: httpd-2.4.39-export.patch
Patch24: httpd-2.4.1-corelimit.patch
Patch25: httpd-2.4.25-selinux.patch
Patch26: httpd-2.4.4-r1337344+.patch
@@ -76,6 +75,9 @@ Patch34: httpd-2.4.17-socket-activation.patch
Patch36: httpd-2.4.38-r1830819+.patch
Patch38: httpd-2.4.34-sslciphdefault.patch
Patch39: httpd-2.4.37-sslprotdefault.patch
+Patch40: httpd-2.4.39-r1861269.patch
+Patch41: httpd-2.4.37-r1861793+.patch
+Patch42: httpd-2.4.37-r1828172+.patch
# Bug fixes
# https://bugzilla.redhat.com/show_bug.cgi?id=1397243
@@ -167,18 +169,6 @@ The mod_ssl module provides strong cryptography for the Apache Web
server via the Secure Sockets Layer (SSL) and Transport Layer
Security (TLS) protocols.
-%package -n mod_md
-Summary: Certificate provisioning using ACME for the Apache HTTP Server
-Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
-BuildRequires: jansson-devel, libcurl-devel
-
-%description -n mod_md
-This module manages common properties of domains for one or more
-virtual hosts. Specifically it can use the ACME protocol (RFC Draft)
-to automate certificate provisioning. These will be configured for
-managed domains and their virtual hosts automatically. This includes
-renewal of certificates before they expire.
-
%package -n mod_proxy_html
Summary: HTML and XML content filters for the Apache HTTP Server
Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
@@ -227,6 +217,9 @@ interface for storing and accessing per-user session data.
%patch36 -p1 -b .r1830819+
%patch38 -p1 -b .sslciphdefault
%patch39 -p1 -b .sslprotdefault
+%patch40 -p1 -b .r1861269
+%patch41 -p1 -b .r1861793+
+%patch42 -p1 -b .r1828172+
%patch58 -p1 -b .r1738878
%patch60 -p1 -b .enable-sslv3
@@ -283,7 +276,7 @@ autoheader && autoconf || exit 1
# Before configure; fix location of build dir in generated apxs
%{__perl} -pi -e "s:\@exp_installbuilddir\@:%{_libdir}/httpd/build:g" \
- support/apxs.in
+ support/apxs.in
export CFLAGS=$RPM_OPT_FLAGS
export LDFLAGS="-Wl,-z,relro,-z,now"
@@ -293,42 +286,44 @@ export LYNX_PATH=/usr/bin/links
# Build the daemon
./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} \
+ --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} \
--enable-layout=Fedora \
--with-installbuilddir=%{_libdir}/httpd/build \
--enable-mpms-shared=all \
--with-apr=%{_prefix} --with-apr-util=%{_prefix} \
- --enable-suexec --with-suexec \
+ --enable-suexec --with-suexec \
--enable-suexec-capabilities \
- --with-suexec-caller=%{suexec_caller} \
- --with-suexec-docroot=%{docroot} \
- --without-suexec-logfile \
+ --with-suexec-caller=%{suexec_caller} \
+ --with-suexec-docroot=%{docroot} \
+ --without-suexec-logfile \
--with-suexec-syslog \
- --with-suexec-bin=%{_sbindir}/suexec \
- --with-suexec-uidmin=1000 --with-suexec-gidmin=1000 \
+ --with-suexec-bin=%{_sbindir}/suexec \
+ --with-suexec-uidmin=1000 --with-suexec-gidmin=1000 \
--with-brotli \
--enable-pie \
--with-pcre \
--enable-mods-shared=all \
- --enable-ssl --with-ssl --disable-distcache \
- --enable-proxy --enable-proxy-fdpass \
+ --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-cgid-fdpassing \
--enable-authn-anon --enable-authn-alias \
--disable-imagemap --disable-file-cache \
--disable-http2 \
- $*
+ --disable-md \
+ $*
make %{?_smp_mflags}
%install
@@ -353,8 +348,7 @@ install -m 644 $RPM_SOURCE_DIR/README.confmod \
$RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/README
for f in 00-base.conf 00-mpm.conf 00-lua.conf 01-cgi.conf 00-dav.conf \
00-proxy.conf 00-ssl.conf 01-ldap.conf 00-proxyhtml.conf \
- 01-ldap.conf 00-systemd.conf 01-session.conf 00-optional.conf \
- 01-md.conf; do
+ 01-ldap.conf 00-systemd.conf 01-session.conf 00-optional.conf; do
install -m 644 -p $RPM_SOURCE_DIR/$f \
$RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/$f
done
@@ -401,19 +395,22 @@ install -m 644 -p $RPM_SOURCE_DIR/httpd.tmpfiles \
$RPM_BUILD_ROOT%{_prefix}/lib/tmpfiles.d/httpd.conf
# Other directories
-mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/dav \
- $RPM_BUILD_ROOT%{_localstatedir}/lib/httpd/state \
+mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/httpd \
$RPM_BUILD_ROOT/run/httpd/htcacheclean
# Substitute in defaults which are usually done (badly) by "make install"
sed -i \
- "s,@@ServerRoot@@/var,%{_localstatedir}/lib/dav,;
+ "/^DavLockDB/d;
s,@@ServerRoot@@/user.passwd,/etc/httpd/conf/user.passwd,;
s,@@ServerRoot@@/docs,%{docroot},;
s,@@ServerRoot@@,%{docroot},;
s,@@Port@@,80,;" \
docs/conf/extra/*.conf
+# Set correct path for httpd binary in apachectl script
+sed 's,@HTTPDBIN@,%{_sbindir}/httpd,g' $RPM_SOURCE_DIR/apachectl.sh \
+ > apachectl.sh
+
# Create cache directory
mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/cache/httpd \
$RPM_BUILD_ROOT%{_localstatedir}/cache/httpd/proxy \
@@ -473,14 +470,15 @@ ln -s ../..%{_libdir}/httpd/modules $RPM_BUILD_ROOT/etc/httpd/modules
# install http-ssl-pass-dialog
mkdir -p $RPM_BUILD_ROOT%{_libexecdir}
install -m755 $RPM_SOURCE_DIR/httpd-ssl-pass-dialog \
- $RPM_BUILD_ROOT%{_libexecdir}/httpd-ssl-pass-dialog
+ $RPM_BUILD_ROOT%{_libexecdir}/httpd-ssl-pass-dialog
# install http-ssl-gencerts
install -m755 $RPM_SOURCE_DIR/httpd-ssl-gencerts \
- $RPM_BUILD_ROOT%{_libexecdir}/httpd-ssl-gencerts
+ $RPM_BUILD_ROOT%{_libexecdir}/httpd-ssl-gencerts
# Install scripts
-install -p -m 755 $RPM_SOURCE_DIR/apachectl.sh $RPM_BUILD_ROOT%{_sbindir}/apachectl
+install -m 755 apachectl.sh $RPM_BUILD_ROOT%{_sbindir}/apachectl
+touch -r $RPM_SOURCE_DIR/apachectl.sh $RPM_BUILD_ROOT%{_sbindir}/apachectl
mkdir -p $RPM_BUILD_ROOT%{_libexecdir}/initscripts/legacy-actions/httpd
for f in graceful configtest; do
install -p -m 755 $RPM_SOURCE_DIR/action-${f}.sh \
@@ -490,7 +488,7 @@ done
# Install logrotate config
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
install -m 644 -p $RPM_SOURCE_DIR/httpd.logrotate \
- $RPM_BUILD_ROOT/etc/logrotate.d/httpd
+ $RPM_BUILD_ROOT/etc/logrotate.d/httpd
# Install man pages
install -d $RPM_BUILD_ROOT%{_mandir}/man8 $RPM_BUILD_ROOT%{_mandir}/man5
@@ -564,19 +562,36 @@ test -f /etc/sysconfig/httpd-disable-posttrans || \
/bin/systemctl try-restart --no-block httpd.service htcacheclean.service >/dev/null 2>&1 || :
%check
+make -C server exports.o
+nm --defined httpd > exports-actual.list
+set +x
+rv=0
+nm --defined-only server/exports.o | \
+ sed -n '/ap_hack_/{s/.* ap_hack_//;/^ap[ru]/d;p;}' | \
+ while read sym; do
+ if ! grep -q " "$sym\$ exports-actual.list; then
+ echo ERROR: Symbol $sym missing in httpd exports
+ rv=1
+ fi
+ done
+if [ $rv -eq 0 ]; then
+ echo PASS: Symbol export list verified.
+fi
# Check the built modules are all PIC
if readelf -d $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.so | grep TEXTREL; then
- : modules contain non-relocatable code
- exit 1
+ echo FAIL: Modules contain non-relocatable code
+ rv=1
+else
+ echo PASS: No non-relocatable code in module builds
fi
-set +x
-rv=0
# Ensure every mod_* that's built is loaded.
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.
+ echo FAIL: Module $m not configured. Disable it, or load it.
rv=1
+ else
+ echo PASS: Module $m is configured and loaded.
fi
done
# Ensure every loaded mod_* is actually built
@@ -584,8 +599,10 @@ mods=`grep -h ^LoadModule $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/*.c
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.
+ echo FAIL: Module $m is configured but not built.
rv=1
+ else
+ echo PASS: Loaded module $m is installed.
fi
done
set -x
@@ -618,7 +635,6 @@ exit $rv
%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
@@ -638,7 +654,6 @@ exit $rv
%{_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
@@ -658,7 +673,6 @@ exit $rv
%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
@@ -720,10 +734,6 @@ exit $rv
%{_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
@@ -734,6 +744,41 @@ exit $rv
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
+* Thu Aug 15 2019 Joe Orton - 2.4.41-1
+- update to 2.4.41
+
+* Thu Jul 25 2019 Fedora Release Engineering - 2.4.39-13
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Tue Jul 23 2019 Joe Orton - 2.4.39-12
+- drop /var/lib/dav directory, since mod_dav_fs uses statedir
+
+* Wed Jul 17 2019 Joe Orton - 2.4.39-11
+- mod_cgid: use fd passing to fix script stderr handling (#1591157)
+
+* Mon Jul 8 2019 Joe Orton - 2.4.39-10
+- htpasswd: add SHA-256/512 support
+- apachectl: restore -V/-v/-t support (#1727434)
+
+* Fri Jun 21 2019 Joe Orton - 2.4.39-9
+- create instance-specific StateDir in httpd@.service, instance.conf
+
+* Thu Jun 20 2019 Joe Orton - 2.4.39-8
+- remove superfluous ap_hack_ symbols from httpd binary
+- more verbose %%check section
+
+* Thu Jun 13 2019 Lubos Uhliarik - 2.4.39-7
+- remove bundled mod_md module
+
+* Thu Jun 13 2019 Joe Orton - 2.4.39-6
+- mod_ssl: fix "httpd -L" (etc) before httpd-init.service runs
+
+* Wed Jun 12 2019 Joe Orton - 2.4.39-5
+- fixes for StateDir directive (upstream r1857731, r1857731)
+
+* Thu May 02 2019 Lubos Uhliarik - 2.4.39-4
+- httpd dependency on initscripts is unspecified (#1705188)
+
* Tue Apr 9 2019 Joe Orton - 2.4.39-3
- fix statedir symlink to point to /var/lib/httpd (#1697662)
- mod_reqtimeout: fix default values regression (PR 63325)
diff --git a/httpd@.service b/httpd@.service
index c58ae88..7649dff 100644
--- a/httpd@.service
+++ b/httpd@.service
@@ -12,6 +12,8 @@ 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
+ExecStartPre=/bin/mkdir -m 700 -p /var/lib/httpd/instance-%i
+ExecStartPre=/bin/chown apache.apache /var/lib/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
diff --git a/instance.conf b/instance.conf
index f2b03f7..074fb66 100644
--- a/instance.conf
+++ b/instance.conf
@@ -1,6 +1,6 @@
#
# This is an example instance-specific configuration file. See the
-# httpd.service(8) man page for detailed information on using 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
@@ -10,7 +10,7 @@
# # systemctl start httpd@foobar.service
#
# The changes compared to the default are:
-# - DefaultRuntime and Pidfile renamed to be instance-specific
+# - DefaultRuntime, DefaultStateDir and Pidfile renamed to 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)
#
@@ -20,4 +20,5 @@
#
DefaultRuntimeDir /run/httpd/instance-${HTTPD_INSTANCE}
+DefaultStateDir /var/lib/httpd/instance-${HTTPD_INSTANCE}
PidFile /run/httpd/instance-${HTTPD_INSTANCE}.pid
diff --git a/sources b/sources
index 248974a..c6aa939 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (httpd-2.4.39.tar.bz2) = 9742202040b3dc6344b301540f54b2d3f8e36898410d24206a7f8dcecb1bea7d7230fabc7256752724558af249facf64bffe2cf678b8f7cccb64076737abfda7
+SHA512 (httpd-2.4.41.tar.bz2) = 350cc7dcd2c439e0590338fa6da3f44df44f9bb885c381e91f91b14c2f48597f6f0bbac0ea118a8a67eaa70ae7edbb769beace368643ed73f6daee44c307b335