-
Available Languages: en |
-diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c
-index bcbba42..c29ded1 100644
---- a/modules/proxy/mod_proxy_wstunnel.c
-+++ b/modules/proxy/mod_proxy_wstunnel.c
-@@ -22,6 +22,7 @@ module AP_MODULE_DECLARE_DATA proxy_wstunnel_module;
- typedef struct {
- unsigned int fallback_to_proxy_http :1,
- fallback_to_proxy_http_set :1;
-+ apr_time_t idle_timeout;
- } proxyws_dir_conf;
-
- static int can_fallback_to_proxy_http;
-@@ -152,6 +153,8 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
- conn_rec *c = r->connection;
- apr_socket_t *sock = conn->sock;
- conn_rec *backconn = conn->connection;
-+ proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
-+ &proxy_wstunnel_module);
- char *buf;
- apr_bucket_brigade *header_brigade;
- apr_bucket *e;
-@@ -229,10 +232,13 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
- c->keepalive = AP_CONN_CLOSE;
-
- do { /* Loop until done (one side closes the connection, or an error) */
-- rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled);
-+ rv = apr_pollset_poll(pollset, dconf->idle_timeout, &pollcnt, &signalled);
- if (rv != APR_SUCCESS) {
- if (APR_STATUS_IS_EINTR(rv)) {
- continue;
-+ } else if(APR_STATUS_IS_TIMEUP(rv)){
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "RH: the connection has timed out");
-+ return HTTP_REQUEST_TIME_OUT;
- }
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02444) "error apr_poll()");
- return HTTP_INTERNAL_SERVER_ERROR;
-@@ -418,11 +424,26 @@ cleanup:
- return status;
- }
-
-+static const char * proxyws_set_idle(cmd_parms *cmd, void *conf, const char *val)
-+{
-+ proxyws_dir_conf *dconf = conf;
-+ if (ap_timeout_parameter_parse(val, &(dconf->idle_timeout), "s") != APR_SUCCESS)
-+ return "ProxyWebsocketIdleTimeout timeout has wrong format";
-+
-+ if (dconf->idle_timeout < 0)
-+ return "ProxyWebsocketIdleTimeout timeout has to be a non-negative number";
-+
-+ if (!dconf->idle_timeout) dconf->idle_timeout = -1; /* loop indefinitely */
-+
-+ return NULL;
-+}
-+
- static void *create_proxyws_dir_config(apr_pool_t *p, char *dummy)
- {
- proxyws_dir_conf *new =
- (proxyws_dir_conf *) apr_pcalloc(p, sizeof(proxyws_dir_conf));
-
-+ new->idle_timeout = -1; /* no timeout */
- new->fallback_to_proxy_http = 1;
-
- return (void *) new;
-@@ -465,7 +486,8 @@ static const command_rec ws_proxy_cmds[] =
- proxyws_fallback_to_proxy_http, NULL, RSRC_CONF|ACCESS_CONF,
- "whether to let mod_proxy_http handle the upgrade and tunneling, "
- "On by default"),
--
-+ AP_INIT_TAKE1("ProxyWebsocketIdleTimeout", proxyws_set_idle, NULL, RSRC_CONF|ACCESS_CONF,
-+ "timeout for activity in either direction, unlimited by default."),
- {NULL}
- };
-
diff --git a/httpd-2.4.48-r1825120.patch b/httpd-2.4.48-r1825120.patch
deleted file mode 100644
index 4eb0a59..0000000
--- a/httpd-2.4.48-r1825120.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
-index 4e2e80d..10a2c86 100644
---- a/modules/ssl/ssl_engine_init.c
-+++ b/modules/ssl/ssl_engine_init.c
-@@ -2256,51 +2256,6 @@ int ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog,
- return OK;
- }
-
--static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a,
-- const X509_NAME * const *b)
--{
-- return(X509_NAME_cmp(*a, *b));
--}
--
--static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
-- server_rec *s, apr_pool_t *ptemp,
-- const char *file)
--{
-- int n;
-- STACK_OF(X509_NAME) *sk;
--
-- sk = (STACK_OF(X509_NAME) *)
-- SSL_load_client_CA_file(file);
--
-- if (!sk) {
-- return;
-- }
--
-- for (n = 0; n < sk_X509_NAME_num(sk); n++) {
-- X509_NAME *name = sk_X509_NAME_value(sk, n);
--
-- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02209)
-- "CA certificate: %s",
-- modssl_X509_NAME_to_string(ptemp, name, 0));
--
-- /*
-- * note that SSL_load_client_CA_file() checks for duplicates,
-- * but since we call it multiple times when reading a directory
-- * we must also check for duplicates ourselves.
-- */
--
-- if (sk_X509_NAME_find(ca_list, name) < 0) {
-- /* this will be freed when ca_list is */
-- sk_X509_NAME_push(ca_list, name);
-- }
-- else {
-- /* need to free this ourselves, else it will leak */
-- X509_NAME_free(name);
-- }
-- }
--
-- sk_X509_NAME_free(sk);
--}
-
- static apr_status_t ssl_init_ca_cert_path(server_rec *s,
- apr_pool_t *ptemp,
-@@ -2324,7 +2279,7 @@ static apr_status_t ssl_init_ca_cert_path(server_rec *s,
- }
- file = apr_pstrcat(ptemp, path, "/", direntry.name, NULL);
- if (ca_list) {
-- ssl_init_PushCAList(ca_list, s, ptemp, file);
-+ SSL_add_file_cert_subjects_to_stack(ca_list, file);
- }
- if (xi_list) {
- load_x509_info(ptemp, xi_list, file);
-@@ -2341,19 +2296,13 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
- const char *ca_file,
- const char *ca_path)
- {
-- STACK_OF(X509_NAME) *ca_list;
--
-- /*
-- * Start with a empty stack/list where new
-- * entries get added in sorted order.
-- */
-- ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp);
-+ STACK_OF(X509_NAME) *ca_list = sk_X509_NAME_new_null();;
-
- /*
- * Process CA certificate bundle file
- */
- if (ca_file) {
-- ssl_init_PushCAList(ca_list, s, ptemp, ca_file);
-+ SSL_add_file_cert_subjects_to_stack(ca_list, ca_file);
- /*
- * If ca_list is still empty after trying to load ca_file
- * then the file failed to load, and users should hear about that.
-@@ -2377,11 +2326,6 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
- return NULL;
- }
-
-- /*
-- * Cleanup
-- */
-- (void) sk_X509_NAME_set_cmp_func(ca_list, NULL);
--
- return ca_list;
- }
-
diff --git a/httpd-2.4.48-r1828172+.patch b/httpd-2.4.48-r1828172+.patch
deleted file mode 100644
index 2b99d69..0000000
--- a/httpd-2.4.48-r1828172+.patch
+++ /dev/null
@@ -1,1411 +0,0 @@
---- httpd-2.4.48/modules/generators/cgi_common.h.r1828172+
-+++ httpd-2.4.48/modules/generators/cgi_common.h
-@@ -0,0 +1,366 @@
-+/* 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 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);
-+ }
-+}
-+
-+#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. */
-+}
---- httpd-2.4.48/modules/generators/config5.m4.r1828172+
-+++ httpd-2.4.48/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.48/modules/generators/mod_cgi.c.r1828172+
-+++ httpd-2.4.48/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}
- };
-
-@@ -466,23 +490,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);
- }
- }
- }
-@@ -536,209 +563,12 @@
- 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
--};
--
-+#define WANT_CGI_BUCKET
- #endif
-
-+#include "cgi_common.h"
-+
- static int cgi_handler(request_rec *r)
- {
- int nph;
-@@ -757,6 +587,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;
-@@ -916,10 +748,7 @@
- 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 +758,7 @@
- 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);
- }
-
- /*============================================================================
-@@ -1268,7 +993,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.48/modules/generators/mod_cgid.c.r1828172+
-+++ httpd-2.4.48/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,60 @@
- }
- } 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 +439,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 +454,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 +495,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 +506,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 +564,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 +593,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 +622,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 +673,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)
-@@ -670,7 +775,7 @@
- }
-
- while (!daemon_should_exit) {
-- int errfileno = STDERR_FILENO;
-+ int errfileno;
- char *argv0 = NULL;
- char **env = NULL;
- const char * const *argv;
-@@ -710,7 +815,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)
-@@ -742,6 +847,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);
-
-@@ -801,7 +916,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);
-
-@@ -1101,6 +1219,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)
-@@ -1206,6 +1351,13 @@
- return ret;
- }
-
-+/* Pull in CGI bucket implementation. */
-+#define cgi_server_conf cgid_server_conf
-+#ifdef HAVE_CGID_FDPASSING
-+#define WANT_CGI_BUCKET
-+#endif
-+#include "cgi_common.h"
-+
- static int connect_to_daemon(int *sdptr, request_rec *r,
- cgid_server_conf *conf)
- {
-@@ -1272,23 +1424,6 @@
- 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...
-@@ -1393,6 +1528,7 @@
-
- static int cgid_handler(request_rec *r)
- {
-+ conn_rec *c = r->connection;
- int retval, nph, dbpos;
- char *argv0, *dbuf;
- apr_bucket_brigade *bb;
-@@ -1402,10 +1538,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;
-@@ -1414,7 +1551,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) {
-@@ -1467,6 +1604,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.
-@@ -1479,12 +1627,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;
-@@ -1506,12 +1658,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...
-@@ -1603,114 +1750,19 @@
- */
- 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);
- }
-
-
-@@ -1827,7 +1879,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;
diff --git a/httpd-2.4.48-r1842929+.patch b/httpd-2.4.48-r1842929+.patch
deleted file mode 100644
index f83a21d..0000000
--- a/httpd-2.4.48-r1842929+.patch
+++ /dev/null
@@ -1,229 +0,0 @@
-diff --git a/Makefile.in b/Makefile.in
-index 6747aea..40c7076 100644
---- a/Makefile.in
-+++ b/Makefile.in
-@@ -233,6 +233,7 @@ install-cgi:
- 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 \
-diff --git a/acinclude.m4 b/acinclude.m4
-index b6ef442..98f1441 100644
---- a/acinclude.m4
-+++ b/acinclude.m4
-@@ -45,6 +45,7 @@ AC_DEFUN([APACHE_GEN_CONFIG_VARS],[
- APACHE_SUBST(installbuilddir)
- APACHE_SUBST(runtimedir)
- APACHE_SUBST(proxycachedir)
-+ APACHE_SUBST(statedir)
- APACHE_SUBST(other_targets)
- APACHE_SUBST(progname)
- APACHE_SUBST(prefix)
-@@ -665,6 +666,7 @@ AC_DEFUN([APACHE_EXPORT_ARGUMENTS],[
- APACHE_SUBST_EXPANDED_ARG(runtimedir)
- APACHE_SUBST_EXPANDED_ARG(logfiledir)
- APACHE_SUBST_EXPANDED_ARG(proxycachedir)
-+ APACHE_SUBST_EXPANDED_ARG(statedir)
- ])
-
- dnl
-diff --git a/configure.in b/configure.in
-index 37346b2..f303784 100644
---- a/configure.in
-+++ b/configure.in
-@@ -41,7 +41,7 @@ dnl Something seems broken here.
- 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
-diff --git a/include/ap_config_layout.h.in b/include/ap_config_layout.h.in
-index 2b4a70c..e076f41 100644
---- a/include/ap_config_layout.h.in
-+++ b/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 */
-diff --git a/include/http_config.h b/include/http_config.h
-index 77657ae..384a90f 100644
---- a/include/http_config.h
-+++ b/include/http_config.h
-@@ -757,6 +757,14 @@ AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *fname);
- */
- 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... */
-
- /**
-diff --git a/modules/dav/fs/mod_dav_fs.c b/modules/dav/fs/mod_dav_fs.c
-index addfd7e..2389f8f 100644
---- a/modules/dav/fs/mod_dav_fs.c
-+++ b/modules/dav/fs/mod_dav_fs.c
-@@ -29,6 +29,10 @@ typedef struct {
-
- 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 @@ static void *dav_fs_merge_server_config(apr_pool_t *p,
- 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 const command_rec dav_fs_cmds[] =
-
- 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);
-diff --git a/server/core.c b/server/core.c
-index d135764..c2176b9 100644
---- a/server/core.c
-+++ b/server/core.c
-@@ -142,6 +142,8 @@ AP_DECLARE_DATA int ap_main_state = AP_SQ_MS_INITIAL_STARTUP;
- 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;
-@@ -1444,13 +1446,16 @@ AP_DECLARE(const char *) ap_resolve_env(apr_pool_t *p, const char * word)
- 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;
- ap_runtime_dir = NULL;
-- return OK;
-+ core_state_dir = NULL;
-+
-+ return APR_SUCCESS;
- }
-
- /*
-@@ -3220,6 +3225,24 @@ static const char *set_runtime_dir(cmd_parms *cmd, void *dummy, const char *arg)
- 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);
-@@ -4521,6 +4544,8 @@ AP_INIT_TAKE1("ServerRoot", set_server_root, NULL, RSRC_CONF | EXEC_ON_READ,
- "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"),
-@@ -5055,8 +5080,7 @@ static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem
-
- 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_DEFAULT);
-
-@@ -5303,6 +5327,27 @@ AP_DECLARE(int) ap_state_query(int query)
- }
- }
-
-+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.48-ssl-proxy-chains.patch b/httpd-2.4.48-ssl-proxy-chains.patch
deleted file mode 100644
index 95c31c8..0000000
--- a/httpd-2.4.48-ssl-proxy-chains.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
-index 15f68f9..e67c81d 100644
---- a/modules/ssl/ssl_engine_init.c
-+++ b/modules/ssl/ssl_engine_init.c
-@@ -1682,6 +1682,10 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
- STACK_OF(X509) *chain;
- X509_STORE_CTX *sctx;
- X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
-+ int addl_chain = 0; /* non-zero if additional chain certs were
-+ * added to store */
-+
-+ ap_assert(store != NULL); /* safe to assume always non-NULL? */
-
- #if OPENSSL_VERSION_NUMBER >= 0x1010100fL
- /* For OpenSSL >=1.1.1, turn on client cert support which is
-@@ -1707,20 +1711,28 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
- ssl_init_ca_cert_path(s, ptemp, pkp->cert_path, NULL, sk);
- }
-
-- if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
-- sk_X509_INFO_free(sk);
-- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
-- "no client certs found for SSL proxy");
-- return APR_SUCCESS;
-- }
--
- /* Check that all client certs have got certificates and private
-- * keys. */
-- for (n = 0; n < ncerts; n++) {
-+ * keys. Note the number of certs in the stack may decrease
-+ * during the loop. */
-+ for (n = 0; n < sk_X509_INFO_num(sk); n++) {
- X509_INFO *inf = sk_X509_INFO_value(sk, n);
-+ int has_privkey = inf->x_pkey && inf->x_pkey->dec_pkey;
-
-- if (!inf->x509 || !inf->x_pkey || !inf->x_pkey->dec_pkey ||
-- inf->enc_data) {
-+ /* For a lone certificate in the file, trust it as a
-+ * CA/intermediate certificate. */
-+ if (inf->x509 && !has_privkey && !inf->enc_data) {
-+ ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509,
-+ APLOGNO(10261) "Trusting non-leaf certificate");
-+ X509_STORE_add_cert(store, inf->x509); /* increments inf->x509 */
-+ /* Delete from the stack and iterate again. */
-+ X509_INFO_free(inf);
-+ sk_X509_INFO_delete(sk, n);
-+ n--;
-+ addl_chain = 1;
-+ continue;
-+ }
-+
-+ if (!has_privkey || inf->enc_data) {
- sk_X509_INFO_free(sk);
- ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252)
- "incomplete client cert configured for SSL proxy "
-@@ -1737,13 +1749,21 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
- }
- }
-
-+ if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
-+ sk_X509_INFO_free(sk);
-+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
-+ "no client certs found for SSL proxy");
-+ return APR_SUCCESS;
-+ }
-+
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02207)
- "loaded %d client certs for SSL proxy",
- ncerts);
- pkp->certs = sk;
-
--
-- if (!pkp->ca_cert_file || !store) {
-+ /* If any chain certs are configured, build the ->ca_certs chains
-+ * corresponding to the loaded keypairs. */
-+ if (!pkp->ca_cert_file && !addl_chain) {
- return APR_SUCCESS;
- }
-
diff --git a/httpd-2.4.51-r1811831.patch b/httpd-2.4.51-r1811831.patch
deleted file mode 100644
index b8d8215..0000000
--- a/httpd-2.4.51-r1811831.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-diff --git a/server/util_script.c b/server/util_script.c
-index 4121ae0..b7f8674 100644
---- a/server/util_script.c
-+++ b/server/util_script.c
-@@ -92,9 +92,21 @@ static void add_unless_null(apr_table_t *table, const char *name, const char *va
- }
- }
-
--static void env2env(apr_table_t *table, const char *name)
-+/* Sets variable @name in table @dest from r->subprocess_env if
-+ * available, else from the environment, else from @fallback if
-+ * non-NULL. */
-+static void env2env(apr_table_t *dest, request_rec *r,
-+ const char *name, const char *fallback)
- {
-- add_unless_null(table, name, getenv(name));
-+ const char *val;
-+
-+ val = apr_table_get(r->subprocess_env, name);
-+ if (!val)
-+ val = apr_pstrdup(r->pool, getenv(name));
-+ if (!val)
-+ val = apr_pstrdup(r->pool, fallback);
-+ if (val)
-+ apr_table_addn(dest, name, val);
- }
-
- AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
-@@ -211,37 +223,29 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r)
- add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
- }
-
-- env_temp = apr_table_get(r->subprocess_env, "PATH");
-- if (env_temp == NULL) {
-- env_temp = getenv("PATH");
-- }
-- if (env_temp == NULL) {
-- env_temp = DEFAULT_PATH;
-- }
-- apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_temp));
--
-+ env2env(e, r, "PATH", DEFAULT_PATH);
- #if defined(WIN32)
-- env2env(e, "SystemRoot");
-- env2env(e, "COMSPEC");
-- env2env(e, "PATHEXT");
-- env2env(e, "WINDIR");
-+ env2env(e, r, "SystemRoot", NULL);
-+ env2env(e, r, "COMSPEC", NULL);
-+ env2env(e, r, "PATHEXT", NULL);
-+ env2env(e, r, "WINDIR", NULL);
- #elif defined(OS2)
-- env2env(e, "COMSPEC");
-- env2env(e, "ETC");
-- env2env(e, "DPATH");
-- env2env(e, "PERLLIB_PREFIX");
-+ env2env(e, r, "COMSPEC", NULL);
-+ env2env(e, r, "ETC", NULL);
-+ env2env(e, r, "DPATH", NULL);
-+ env2env(e, r, "PERLLIB_PREFIX", NULL);
- #elif defined(BEOS)
-- env2env(e, "LIBRARY_PATH");
-+ env2env(e, r, "LIBRARY_PATH", NULL);
- #elif defined(DARWIN)
-- env2env(e, "DYLD_LIBRARY_PATH");
-+ env2env(e, r, "DYLD_LIBRARY_PATH", NULL);
- #elif defined(_AIX)
-- env2env(e, "LIBPATH");
-+ env2env(e, r, "LIBPATH", NULL);
- #elif defined(__HPUX__)
- /* HPUX PARISC 2.0W knows both, otherwise redundancy is harmless */
-- env2env(e, "SHLIB_PATH");
-- env2env(e, "LD_LIBRARY_PATH");
-+ env2env(e, r, "SHLIB_PATH", NULL);
-+ env2env(e, r, "LD_LIBRARY_PATH", NULL);
- #else /* Some Unix */
-- env2env(e, "LD_LIBRARY_PATH");
-+ env2env(e, r, "LD_LIBRARY_PATH", NULL);
- #endif
-
- apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
diff --git a/httpd-2.4.51-r1877397.patch b/httpd-2.4.51-r1877397.patch
deleted file mode 100644
index f629317..0000000
--- a/httpd-2.4.51-r1877397.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
-index 211ebff..c8cb1af 100644
---- a/modules/ssl/ssl_engine_init.c
-+++ b/modules/ssl/ssl_engine_init.c
-@@ -871,6 +871,13 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
- SSL_CTX_set_keylog_callback(ctx, modssl_callback_keylog);
- }
- #endif
-+
-+#ifdef SSL_OP_NO_RENEGOTIATION
-+ /* For server-side SSL_CTX, disable renegotiation by default.. */
-+ if (!mctx->pkp) {
-+ SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION);
-+ }
-+#endif
-
- return APR_SUCCESS;
- }
-@@ -892,6 +899,14 @@ static void ssl_init_ctx_session_cache(server_rec *s,
- }
- }
-
-+#ifdef SSL_OP_NO_RENEGOTIATION
-+/* OpenSSL-level renegotiation protection. */
-+#define MODSSL_BLOCKS_RENEG (0)
-+#else
-+/* mod_ssl-level renegotiation protection. */
-+#define MODSSL_BLOCKS_RENEG (1)
-+#endif
-+
- static void ssl_init_ctx_callbacks(server_rec *s,
- apr_pool_t *p,
- apr_pool_t *ptemp,
-@@ -905,7 +920,13 @@ static void ssl_init_ctx_callbacks(server_rec *s,
- SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
- #endif
-
-- SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
-+ /* The info callback is used for debug-level tracing. For OpenSSL
-+ * versions where SSL_OP_NO_RENEGOTIATION is not available, the
-+ * callback is also used to prevent use of client-initiated
-+ * renegotiation. Enable it in either case. */
-+ if (APLOGdebug(s) || MODSSL_BLOCKS_RENEG) {
-+ SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
-+ }
-
- #ifdef HAVE_TLS_ALPN
- SSL_CTX_set_alpn_select_cb(ctx, ssl_callback_alpn_select, NULL);
-diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
-index 79b9a70..3a0c22a 100644
---- a/modules/ssl/ssl_engine_io.c
-+++ b/modules/ssl/ssl_engine_io.c
-@@ -209,11 +209,13 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl)
-
- BIO_clear_retry_flags(bio);
-
-+#ifndef SSL_OP_NO_RENEGOTIATION
- /* Abort early if the client has initiated a renegotiation. */
- if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
- outctx->rc = APR_ECONNABORTED;
- return -1;
- }
-+#endif
-
- ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c,
- "bio_filter_out_write: %i bytes", inl);
-@@ -474,11 +476,13 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen)
-
- BIO_clear_retry_flags(bio);
-
-+#ifndef SSL_OP_NO_RENEGOTIATION
- /* Abort early if the client has initiated a renegotiation. */
- if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
- inctx->rc = APR_ECONNABORTED;
- return -1;
- }
-+#endif
-
- if (!inctx->bb) {
- inctx->rc = APR_EOF;
-diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
-index 591f6ae..8416864 100644
---- a/modules/ssl/ssl_engine_kernel.c
-+++ b/modules/ssl/ssl_engine_kernel.c
-@@ -992,7 +992,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo
-
- /* Toggle the renegotiation state to allow the new
- * handshake to proceed. */
-- sslconn->reneg_state = RENEG_ALLOW;
-+ modssl_set_reneg_state(sslconn, RENEG_ALLOW);
-
- SSL_renegotiate(ssl);
- SSL_do_handshake(ssl);
-@@ -1019,7 +1019,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo
- */
- SSL_peek(ssl, peekbuf, 0);
-
-- sslconn->reneg_state = RENEG_REJECT;
-+ modssl_set_reneg_state(sslconn, RENEG_REJECT);
-
- if (!SSL_is_init_finished(ssl)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02261)
-@@ -1078,7 +1078,7 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
- (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) {
- int vmode_inplace, vmode_needed;
- int change_vmode = FALSE;
-- int old_state, n, rc;
-+ int n, rc;
-
- vmode_inplace = SSL_get_verify_mode(ssl);
- vmode_needed = SSL_VERIFY_NONE;
-@@ -1180,8 +1180,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
- return HTTP_FORBIDDEN;
- }
-
-- old_state = sslconn->reneg_state;
-- sslconn->reneg_state = RENEG_ALLOW;
- modssl_set_app_data2(ssl, r);
-
- SSL_do_handshake(ssl);
-@@ -1191,7 +1189,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
- */
- SSL_peek(ssl, peekbuf, 0);
-
-- sslconn->reneg_state = old_state;
- modssl_set_app_data2(ssl, NULL);
-
- /*
-@@ -2263,8 +2260,8 @@ static void log_tracing_state(const SSL *ssl, conn_rec *c,
- /*
- * This callback function is executed while OpenSSL processes the SSL
- * handshake and does SSL record layer stuff. It's used to trap
-- * client-initiated renegotiations, and for dumping everything to the
-- * log.
-+ * client-initiated renegotiations (where SSL_OP_NO_RENEGOTIATION is
-+ * not available), and for dumping everything to the log.
- */
- void ssl_callback_Info(const SSL *ssl, int where, int rc)
- {
-@@ -2276,14 +2273,12 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
- return;
- }
-
-- /* With TLS 1.3 this callback may be called multiple times on the first
-- * negotiation, so the below logic to detect renegotiations can't work.
-- * Fortunately renegotiations are forbidden starting with TLS 1.3, and
-- * this is enforced by OpenSSL so there's nothing to be done here.
-- */
--#if SSL_HAVE_PROTOCOL_TLSV1_3
-- if (SSL_version(ssl) < TLS1_3_VERSION)
--#endif
-+#ifndef SSL_OP_NO_RENEGOTIATION
-+ /* With OpenSSL < 1.1.1 (implying TLS v1.2 or earlier), this
-+ * callback is used to block client-initiated renegotiation. With
-+ * TLSv1.3 it is unnecessary since renegotiation is forbidden at
-+ * protocol level. Otherwise (TLSv1.2 with OpenSSL >=1.1.1),
-+ * SSL_OP_NO_RENEGOTIATION is used to block renegotiation. */
- {
- SSLConnRec *sslconn;
-
-@@ -2308,6 +2303,7 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
- sslconn->reneg_state = RENEG_REJECT;
- }
- }
-+#endif
-
- s = mySrvFromConn(c);
- if (s && APLOGdebug(s)) {
-diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
-index a329d99..7666c31 100644
---- a/modules/ssl/ssl_private.h
-+++ b/modules/ssl/ssl_private.h
-@@ -512,6 +512,16 @@ typedef struct {
- apr_time_t source_mtime;
- } ssl_asn1_t;
-
-+typedef enum {
-+ RENEG_INIT = 0, /* Before initial handshake */
-+ RENEG_REJECT, /* After initial handshake; any client-initiated
-+ * renegotiation should be rejected */
-+ RENEG_ALLOW, /* A server-initiated renegotiation is taking
-+ * place (as dictated by configuration) */
-+ RENEG_ABORT /* Renegotiation initiated by client, abort the
-+ * connection */
-+} modssl_reneg_state;
-+
- /**
- * Define the mod_ssl per-module configuration structure
- * (i.e. the global configuration for each httpd process)
-@@ -543,18 +553,13 @@ typedef struct {
- NON_SSL_SET_ERROR_MSG /* Need to set the error message */
- } non_ssl_request;
-
-- /* Track the handshake/renegotiation state for the connection so
-- * that all client-initiated renegotiations can be rejected, as a
-- * partial fix for CVE-2009-3555. */
-- enum {
-- RENEG_INIT = 0, /* Before initial handshake */
-- RENEG_REJECT, /* After initial handshake; any client-initiated
-- * renegotiation should be rejected */
-- RENEG_ALLOW, /* A server-initiated renegotiation is taking
-- * place (as dictated by configuration) */
-- RENEG_ABORT /* Renegotiation initiated by client, abort the
-- * connection */
-- } reneg_state;
-+#ifndef SSL_OP_NO_RENEGOTIATION
-+ /* For OpenSSL < 1.1.1, track the handshake/renegotiation state
-+ * for the connection to block client-initiated renegotiations.
-+ * For OpenSSL >=1.1.1, the SSL_OP_NO_RENEGOTIATION flag is used in
-+ * the SSL * options state with equivalent effect. */
-+ modssl_reneg_state reneg_state;
-+#endif
-
- server_rec *server;
- SSLDirConfigRec *dc;
-@@ -1158,6 +1163,9 @@ int ssl_is_challenge(conn_rec *c, const char *servername,
- * the configured ENGINE. */
- int modssl_is_engine_id(const char *name);
-
-+/* Set the renegotation state for connection. */
-+void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state);
-+
- #endif /* SSL_PRIVATE_H */
- /** @} */
-
-diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c
-index 38079a9..dafb833 100644
---- a/modules/ssl/ssl_util_ssl.c
-+++ b/modules/ssl/ssl_util_ssl.c
-@@ -589,3 +589,19 @@ cleanup:
- }
- return rv;
- }
-+
-+void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state)
-+{
-+#ifdef SSL_OP_NO_RENEGOTIATION
-+ switch (state) {
-+ case RENEG_ALLOW:
-+ SSL_clear_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION);
-+ break;
-+ default:
-+ SSL_set_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION);
-+ break;
-+ }
-+#else
-+ sslconn->reneg_state = state;
-+#endif
-+}
diff --git a/httpd-2.4.51-r1892413+.patch b/httpd-2.4.51-r1892413+.patch
deleted file mode 100644
index 59e2319..0000000
--- a/httpd-2.4.51-r1892413+.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-# ./pullrev.sh 1892413 1895552
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1938740
-
-http://svn.apache.org/viewvc?view=revision&revision=1892413
-http://svn.apache.org/viewvc?view=revision&revision=1895552
-
-- also mod_cgi/mod_cgid log_flags fix from r1881559
-
---- httpd-2.4.51/modules/filters/mod_deflate.c.r1892413+
-+++ httpd-2.4.51/modules/filters/mod_deflate.c
-@@ -1275,44 +1275,46 @@
- if (APR_BUCKET_IS_FLUSH(bkt)) {
- apr_bucket *tmp_b;
-
-- ctx->inflate_total += ctx->stream.avail_out;
-- zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH);
-- ctx->inflate_total -= ctx->stream.avail_out;
-- if (zRC != Z_OK) {
-- inflateEnd(&ctx->stream);
-- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01391)
-- "Zlib error %d inflating data (%s)", zRC,
-- ctx->stream.msg);
-- return APR_EGENERAL;
-- }
-+ if (!ctx->done) {
-+ ctx->inflate_total += ctx->stream.avail_out;
-+ zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH);
-+ ctx->inflate_total -= ctx->stream.avail_out;
-+ if (zRC != Z_OK) {
-+ inflateEnd(&ctx->stream);
-+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01391)
-+ "Zlib error %d inflating data (%s)", zRC,
-+ ctx->stream.msg);
-+ return APR_EGENERAL;
-+ }
-
-- if (inflate_limit && ctx->inflate_total > inflate_limit) {
-- inflateEnd(&ctx->stream);
-- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647)
-- "Inflated content length of %" APR_OFF_T_FMT
-- " is larger than the configured limit"
-- " of %" APR_OFF_T_FMT,
-- ctx->inflate_total, inflate_limit);
-- return APR_ENOSPC;
-- }
-+ if (inflate_limit && ctx->inflate_total > inflate_limit) {
-+ inflateEnd(&ctx->stream);
-+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647)
-+ "Inflated content length of %" APR_OFF_T_FMT
-+ " is larger than the configured limit"
-+ " of %" APR_OFF_T_FMT,
-+ ctx->inflate_total, inflate_limit);
-+ return APR_ENOSPC;
-+ }
-
-- if (!check_ratio(r, ctx, dc)) {
-- inflateEnd(&ctx->stream);
-- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02805)
-- "Inflated content ratio is larger than the "
-- "configured limit %i by %i time(s)",
-- dc->ratio_limit, dc->ratio_burst);
-- return APR_EINVAL;
-- }
-+ if (!check_ratio(r, ctx, dc)) {
-+ inflateEnd(&ctx->stream);
-+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02805)
-+ "Inflated content ratio is larger than the "
-+ "configured limit %i by %i time(s)",
-+ dc->ratio_limit, dc->ratio_burst);
-+ return APR_EINVAL;
-+ }
-
-- len = c->bufferSize - ctx->stream.avail_out;
-- ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
-- tmp_b = apr_bucket_heap_create((char *)ctx->buffer, len,
-- NULL, f->c->bucket_alloc);
-- APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_b);
-+ len = c->bufferSize - ctx->stream.avail_out;
-+ ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
-+ tmp_b = apr_bucket_heap_create((char *)ctx->buffer, len,
-+ NULL, f->c->bucket_alloc);
-+ APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_b);
-
-- ctx->stream.next_out = ctx->buffer;
-- ctx->stream.avail_out = c->bufferSize;
-+ ctx->stream.next_out = ctx->buffer;
-+ ctx->stream.avail_out = c->bufferSize;
-+ }
-
- /* Flush everything so far in the returning brigade, but continue
- * reading should EOS/more follow (don't lose them).
---- httpd-2.4.51/modules/generators/mod_cgi.c.r1892413+
-+++ httpd-2.4.51/modules/generators/mod_cgi.c
-@@ -191,11 +191,10 @@
- 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,
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
- "%s%s: %s", logno ? logno : "", error, r->filename);
-
- /* XXX Very expensive mainline case! Open, then getfileinfo! */
---- httpd-2.4.51/modules/generators/mod_cgid.c.r1892413+
-+++ httpd-2.4.51/modules/generators/mod_cgid.c
-@@ -1190,11 +1190,10 @@
- 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,
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
- "%s: %s", error, r->filename);
-
- /* XXX Very expensive mainline case! Open, then getfileinfo! */
---- httpd-2.4.51/server/mpm_unix.c.r1892413+
-+++ httpd-2.4.51/server/mpm_unix.c
-@@ -259,10 +259,12 @@
- while (cur_extra) {
- ap_generation_t old_gen;
- extra_process_t *next = cur_extra->next;
-+ pid_t pid = cur_extra->pid;
-
-- if (reclaim_one_pid(cur_extra->pid, action_table[cur_action].action)) {
-- if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
-- mpm_callback(-1, cur_extra->pid, old_gen);
-+ if (reclaim_one_pid(pid, action_table[cur_action].action)) {
-+ if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) {
-+ /* cur_extra dangling pointer from here. */
-+ mpm_callback(-1, pid, old_gen);
- }
- else {
- AP_DEBUG_ASSERT(1 == 0);
-@@ -307,10 +309,12 @@
- while (cur_extra) {
- ap_generation_t old_gen;
- extra_process_t *next = cur_extra->next;
-+ pid_t pid = cur_extra->pid;
-
-- if (reclaim_one_pid(cur_extra->pid, DO_NOTHING)) {
-- if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
-- mpm_callback(-1, cur_extra->pid, old_gen);
-+ if (reclaim_one_pid(pid, DO_NOTHING)) {
-+ if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) {
-+ /* cur_extra dangling pointer from here. */
-+ mpm_callback(-1, pid, old_gen);
- }
- else {
- AP_DEBUG_ASSERT(1 == 0);
diff --git a/httpd-2.4.53-CVE-2022-26377.patch b/httpd-2.4.53-CVE-2022-26377.patch
deleted file mode 100644
index 0b05fec..0000000
--- a/httpd-2.4.53-CVE-2022-26377.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
-index e2992fc..46d42bc 100644
---- a/modules/proxy/mod_proxy_ajp.c
-+++ b/modules/proxy/mod_proxy_ajp.c
-@@ -246,9 +246,18 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
- /* read the first block of data */
- input_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
- tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
-- if (tenc && (ap_cstr_casecmp(tenc, "chunked") == 0)) {
-- /* The AJP protocol does not want body data yet */
-- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870) "request is chunked");
-+ if (tenc) {
-+ if (ap_cstr_casecmp(tenc, "chunked") == 0) {
-+ /* The AJP protocol does not want body data yet */
-+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870)
-+ "request is chunked");
-+ }
-+ else {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10396)
-+ "%s Transfer-Encoding is not supported",
-+ tenc);
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ }
- } else {
- /* Get client provided Content-Length header */
- content_length = get_content_length(r);
diff --git a/httpd-2.4.53-CVE-2022-28614.patch b/httpd-2.4.53-CVE-2022-28614.patch
deleted file mode 100644
index ef2b535..0000000
--- a/httpd-2.4.53-CVE-2022-28614.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 8c14927162cf3b4f810683e1c5505e9ef9e1f123 Mon Sep 17 00:00:00 2001
-From: Eric Covener
-Date: Wed, 1 Jun 2022 12:34:16 +0000
-Subject: [PATCH] Merge r1901500 from trunk:
-
-handle large writes in ap_rputs
-
-
-git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901501 13f79535-47bb-0310-9956-ffa450edef68
----
- include/http_protocol.h | 22 +++++++++++++++++++++-
- server/protocol.c | 3 +++
- 2 files changed, 24 insertions(+), 1 deletion(-)
-
-diff --git a/include/http_protocol.h b/include/http_protocol.h
-index 20bd2022266..94c481e5f43 100644
---- a/include/http_protocol.h
-+++ b/include/http_protocol.h
-@@ -475,7 +475,27 @@ AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r);
- */
- static APR_INLINE int ap_rputs(const char *str, request_rec *r)
- {
-- return ap_rwrite(str, (int)strlen(str), r);
-+ apr_size_t len;
-+
-+ len = strlen(str);
-+
-+ for (;;) {
-+ if (len <= INT_MAX) {
-+ return ap_rwrite(str, (int)len, r);
-+ }
-+ else {
-+ int rc;
-+
-+ rc = ap_rwrite(str, INT_MAX, r);
-+ if (rc < 0) {
-+ return rc;
-+ }
-+ else {
-+ str += INT_MAX;
-+ len -= INT_MAX;
-+ }
-+ }
-+ }
- }
-
- /**
-diff --git a/server/protocol.c b/server/protocol.c
-index 298f61e1fb8..7adc7f75c10 100644
---- a/server/protocol.c
-+++ b/server/protocol.c
-@@ -2128,6 +2128,9 @@ AP_DECLARE(int) ap_rputc(int c, request_rec *r)
-
- AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r)
- {
-+ if (nbyte < 0)
-+ return -1;
-+
- if (r->connection->aborted)
- return -1;
-
diff --git a/httpd-2.4.53-CVE-2022-28615.patch b/httpd-2.4.53-CVE-2022-28615.patch
deleted file mode 100644
index 75a3d0f..0000000
--- a/httpd-2.4.53-CVE-2022-28615.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-diff --git a/server/util.c b/server/util.c
-index 604be1a..6808164 100644
---- a/server/util.c
-+++ b/server/util.c
-@@ -185,7 +185,7 @@ AP_DECLARE(char *) ap_ht_time(apr_pool_t *p, apr_time_t t, const char *fmt,
- */
- AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected)
- {
-- int x, y;
-+ apr_size_t x, y;
-
- for (x = 0, y = 0; expected[y]; ++y, ++x) {
- if (expected[y] == '*') {
-@@ -209,7 +209,7 @@ AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected)
-
- AP_DECLARE(int) ap_strcasecmp_match(const char *str, const char *expected)
- {
-- int x, y;
-+ apr_size_t x, y;
-
- for (x = 0, y = 0; expected[y]; ++y, ++x) {
- if (!str[x] && expected[y] != '*')
diff --git a/httpd-2.4.53-CVE-2022-29404.patch b/httpd-2.4.53-CVE-2022-29404.patch
deleted file mode 100644
index df4f70f..0000000
--- a/httpd-2.4.53-CVE-2022-29404.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en
-index bb6b90a..d14aed4 100644
---- a/docs/manual/mod/core.html.en
-+++ b/docs/manual/mod/core.html.en
-@@ -2796,16 +2796,16 @@ subrequests
- Description: | Restricts the total size of the HTTP request body sent
- from the client |
- Syntax: | LimitRequestBody bytes |
--Default: | LimitRequestBody 0 |
-+Default: | LimitRequestBody 1073741824 |
- Context: | server config, virtual host, directory, .htaccess |
- Override: | All |
- Status: | Core |
- Module: | core |
-+Compatibility: | In Apache HTTP Server 2.4.53 and earlier, the default value
-+ was 0 (unlimited) |
-