diff options
Diffstat (limited to '')
-rw-r--r-- | modules/generators/mod_cgi.c | 63 | ||||
-rw-r--r-- | modules/generators/mod_cgid.c | 15 | ||||
-rw-r--r-- | modules/generators/mod_status.c | 48 |
3 files changed, 87 insertions, 39 deletions
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, "<dt>%d requests currently being processed, " - "%d idle workers</dt>\n", busy, ready); + ap_rprintf(r, "<dt>%d requests currently being processed, %d workers gracefully restarting, " + "%d idle workers</dt>\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("</dl>", 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<table rules=\"all\" cellpadding=\"1%\">\n" "<tr><th rowspan=\"2\">Slot</th>" @@ -573,7 +575,7 @@ static int status_handler(request_rec *r) "<th colspan=\"2\">Threads</th>" "<th colspan=\"3\">Async connections</th></tr>\n" "<tr><th>total</th><th>accepting</th>" - "<th>busy</th><th>idle</th>" + "<th>busy</th><th>graceful</th><th>idle</th>" "<th>writing</th><th>keep-alive</th><th>closing</th></tr>\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, "<tr><td>%u</td><td>%" APR_PID_T_FMT "</td>" "<td>%s%s</td>" "<td>%u</td><td>%s</td>" - "<td>%u</td><td>%u</td>" + "<td>%u</td><td>%u</td><td>%u</td>" "<td>%u</td><td>%u</td><td>%u</td>" "</tr>\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, "<tr><td>Sum</td>" "<td>%d</td><td>%d</td>" "<td>%d</td><td> </td>" - "<td>%d</td><td>%d</td>" + "<td>%d</td><td>%d</td><td>%d</td>" "<td>%d</td><td>%d</td><td>%d</td>" "</tr>\n</table>\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); } |