From 3161ed034bbea40a705303811d7213aff9be17d2 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 01:56:20 +0200 Subject: Merging upstream version 2.4.59. Signed-off-by: Daniel Baumann --- modules/generators/mod_cgi.c | 63 ++++++++++++++++++++++++++++++++++------- modules/generators/mod_cgid.c | 15 ++++++++-- modules/generators/mod_status.c | 48 +++++++++++++++---------------- 3 files changed, 87 insertions(+), 39 deletions(-) (limited to 'modules/generators') diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c index 7e4b126..1f77786 100644 --- a/modules/generators/mod_cgi.c +++ b/modules/generators/mod_cgi.c @@ -92,6 +92,10 @@ typedef struct { 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 @@ static void *merge_cgi_config(apr_pool_t *p, void *basev, void *overridesv) return overrides->logname ? overrides : base; } +static void *create_cgi_dirconf(apr_pool_t *p, char *dummy) +{ + cgi_dirconf *c = (cgi_dirconf *) apr_pcalloc(p, sizeof(cgi_dirconf)); + return c; +} + static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg) { server_rec *s = cmd->server; @@ -150,6 +160,17 @@ static const char *set_scriptlog_buffer(cmd_parms *cmd, void *dummy, return NULL; } +static const char *set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg) +{ + cgi_dirconf *dc = dummy; + + if (ap_timeout_parameter_parse(arg, &dc->timeout, "s") != APR_SUCCESS) { + return "CGIScriptTimeout has wrong format"; + } + + return NULL; +} + static const command_rec cgi_cmds[] = { AP_INIT_TAKE1("ScriptLog", set_scriptlog, NULL, RSRC_CONF, @@ -158,6 +179,9 @@ AP_INIT_TAKE1("ScriptLogLength", set_scriptlog_length, NULL, RSRC_CONF, "the maximum length (in bytes) of the script debug log"), AP_INIT_TAKE1("ScriptLogBuffer", set_scriptlog_buffer, NULL, RSRC_CONF, "the maximum size (in bytes) to record of a POST request"), +AP_INIT_TAKE1("CGIScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_CONF, + "The amount of time to wait between successful reads from " + "the CGI script, in seconds."), {NULL} }; @@ -466,23 +490,26 @@ static apr_status_t run_cgi_child(apr_file_t **script_out, apr_filepath_name_get(r->filename)); } else { + cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module); + apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout; + apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); *script_in = procnew->out; if (!*script_in) return APR_EBADF; - apr_file_pipe_timeout_set(*script_in, r->server->timeout); + apr_file_pipe_timeout_set(*script_in, timeout); if (e_info->prog_type == RUN_AS_CGI) { *script_out = procnew->in; if (!*script_out) return APR_EBADF; - apr_file_pipe_timeout_set(*script_out, r->server->timeout); + apr_file_pipe_timeout_set(*script_out, timeout); *script_err = procnew->err; if (!*script_err) return APR_EBADF; - apr_file_pipe_timeout_set(*script_err, r->server->timeout); + apr_file_pipe_timeout_set(*script_err, timeout); } } } @@ -675,11 +702,14 @@ 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_interval_time_t timeout = 0; apr_status_t rv; int gotdata = 0; + cgi_dirconf *dc = ap_get_module_config(data->r->per_dir_config, &cgi_module); - timeout = block == APR_NONBLOCK_READ ? 0 : data->r->server->timeout; + if (block != APR_NONBLOCK_READ) { + timeout = dc->timeout > 0 ? dc->timeout : data->r->server->timeout; + } do { const apr_pollfd_t *results; @@ -757,6 +787,8 @@ static int cgi_handler(request_rec *r) 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; @@ -935,9 +967,18 @@ static int cgi_handler(request_rec *r) char sbuf[MAX_STRING_LEN]; int ret; - if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, - APLOG_MODULE_INDEX))) - { + ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, + APLOG_MODULE_INDEX); + + /* xCGI has its own body framing mechanism which we don't + * match against any provided Content-Length, so let the + * core determine C-L vs T-E based on what's actually sent. + */ + if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR)) + apr_table_unset(r->headers_out, "Content-Length"); + apr_table_unset(r->headers_out, "Transfer-Encoding"); + + if (ret != OK) { ret = log_script(r, conf, ret, dbuf, sbuf, bb, script_err); /* @@ -976,7 +1017,7 @@ static int cgi_handler(request_rec *r) * 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); } @@ -1027,7 +1068,7 @@ static int cgi_handler(request_rec *r) * 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); } @@ -1268,7 +1309,7 @@ static void register_hooks(apr_pool_t *p) AP_DECLARE_MODULE(cgi) = { STANDARD20_MODULE_STUFF, - NULL, /* dir config creater */ + create_cgi_dirconf, /* dir config creater */ NULL, /* dir merger --- default is to override */ create_cgi_config, /* server config */ merge_cgi_config, /* merge server config */ diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index 2258a68..4bab59f 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -1616,9 +1616,18 @@ static int cgid_handler(request_rec *r) 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 = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, + APLOG_MODULE_INDEX); + + /* xCGI has its own body framing mechanism which we don't + * match against any provided Content-Length, so let the + * core determine C-L vs T-E based on what's actually sent. + */ + if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR)) + apr_table_unset(r->headers_out, "Content-Length"); + apr_table_unset(r->headers_out, "Transfer-Encoding"); + + if (ret != OK) { ret = log_script(r, conf, ret, dbuf, sbuf, bb, NULL); /* diff --git a/modules/generators/mod_status.c b/modules/generators/mod_status.c index 5917953..5bada07 100644 --- a/modules/generators/mod_status.c +++ b/modules/generators/mod_status.c @@ -186,7 +186,8 @@ static int status_handler(request_rec *r) apr_uint32_t up_time; ap_loadavg_t t; int j, i, res, written; - int ready; + int idle; + int graceful; int busy; unsigned long count; unsigned long lres, my_lres, conn_lres; @@ -203,6 +204,7 @@ static int status_handler(request_rec *r) char *stat_buffer; pid_t *pid_buffer, worker_pid; int *thread_idle_buffer = NULL; + int *thread_graceful_buffer = NULL; int *thread_busy_buffer = NULL; clock_t tu, ts, tcu, tcs; clock_t gu, gs, gcu, gcs; @@ -231,7 +233,8 @@ static int status_handler(request_rec *r) #endif #endif - ready = 0; + idle = 0; + graceful = 0; busy = 0; count = 0; bcount = 0; @@ -250,6 +253,7 @@ static int status_handler(request_rec *r) stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char)); if (is_async) { thread_idle_buffer = apr_palloc(r->pool, server_limit * sizeof(int)); + thread_graceful_buffer = apr_palloc(r->pool, server_limit * sizeof(int)); thread_busy_buffer = apr_palloc(r->pool, server_limit * sizeof(int)); } @@ -318,6 +322,7 @@ static int status_handler(request_rec *r) ps_record = ap_get_scoreboard_process(i); if (is_async) { thread_idle_buffer[i] = 0; + thread_graceful_buffer[i] = 0; thread_busy_buffer[i] = 0; } for (j = 0; j < thread_limit; ++j) { @@ -336,18 +341,20 @@ static int status_handler(request_rec *r) && ps_record->pid) { if (res == SERVER_READY) { if (ps_record->generation == mpm_generation) - ready++; + idle++; if (is_async) thread_idle_buffer[i]++; } else if (res != SERVER_DEAD && res != SERVER_STARTING && res != SERVER_IDLE_KILL) { - busy++; - if (is_async) { - if (res == SERVER_GRACEFUL) - thread_idle_buffer[i]++; - else + if (res == SERVER_GRACEFUL) { + graceful++; + if (is_async) + thread_graceful_buffer[i]++; + } else { + busy++; + if (is_async) thread_busy_buffer[i]++; } } @@ -548,10 +555,10 @@ static int status_handler(request_rec *r) } /* ap_extended_status */ if (!short_report) - ap_rprintf(r, "
%d requests currently being processed, " - "%d idle workers
\n", busy, ready); + ap_rprintf(r, "
%d requests currently being processed, %d workers gracefully restarting, " + "%d idle workers
\n", busy, graceful, idle); else - ap_rprintf(r, "BusyWorkers: %d\nIdleWorkers: %d\n", busy, ready); + ap_rprintf(r, "BusyWorkers: %d\nGracefulWorkers: %d\nIdleWorkers: %d\n", busy, graceful, idle); if (!short_report) ap_rputs("", r); @@ -559,11 +566,6 @@ static int status_handler(request_rec *r) if (is_async) { int write_completion = 0, lingering_close = 0, keep_alive = 0, connections = 0, stopping = 0, procs = 0; - /* - * These differ from 'busy' and 'ready' in how gracefully finishing - * threads are counted. XXX: How to make this clear in the html? - */ - int busy_workers = 0, idle_workers = 0; if (!short_report) ap_rputs("\n\n\n" "" @@ -573,7 +575,7 @@ static int status_handler(request_rec *r) "" "\n" "" - "" + "" "\n", r); for (i = 0; i < server_limit; ++i) { ps_record = ap_get_scoreboard_process(i); @@ -582,8 +584,6 @@ static int status_handler(request_rec *r) write_completion += ps_record->write_completion; keep_alive += ps_record->keep_alive; lingering_close += ps_record->lingering_close; - busy_workers += thread_busy_buffer[i]; - idle_workers += thread_idle_buffer[i]; procs++; if (ps_record->quiescing) { stopping++; @@ -599,7 +599,7 @@ static int status_handler(request_rec *r) ap_rprintf(r, "" "" "" - "" + "" "" "\n", i, ps_record->pid, @@ -607,6 +607,7 @@ static int status_handler(request_rec *r) ps_record->connections, ps_record->not_accepting ? "no" : "yes", thread_busy_buffer[i], + thread_graceful_buffer[i], thread_idle_buffer[i], ps_record->write_completion, ps_record->keep_alive, @@ -618,25 +619,22 @@ static int status_handler(request_rec *r) ap_rprintf(r, "" "" "" - "" + "" "" "\n
SlotThreadsAsync connections
totalacceptingbusyidlebusygracefulidlewritingkeep-aliveclosing
%u%" APR_PID_T_FMT "%s%s%u%s%u%u%u%u%u%u%u%u
Sum%d%d%d %d%d%d%d%d%d%d%d
\n", procs, stopping, connections, - busy_workers, idle_workers, + busy, graceful, idle, write_completion, keep_alive, lingering_close); } else { ap_rprintf(r, "Processes: %d\n" "Stopping: %d\n" - "BusyWorkers: %d\n" - "IdleWorkers: %d\n" "ConnsTotal: %d\n" "ConnsAsyncWriting: %d\n" "ConnsAsyncKeepAlive: %d\n" "ConnsAsyncClosing: %d\n", procs, stopping, - busy_workers, idle_workers, connections, write_completion, keep_alive, lingering_close); } -- cgit v1.2.3